185 lines
7.9 KiB
YAML
185 lines
7.9 KiB
YAML
|
|
# informed-decision — NetKingdom security layer declaration
|
||
|
|
#
|
||
|
|
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
||
|
|
# Companion: net-kingdom/SECURITY-COMPANION.md v0.2
|
||
|
|
# Voice: INTENT.md (this repository's own, per §11 "who must declare")
|
||
|
|
# Ruling: GH-DEC-2026-012 (gate-house@0a1d1d9) answered INFD-IN-0001
|
||
|
|
#
|
||
|
|
# Reference form: ops-warden's, adopted by audit-core and kings-guard, with
|
||
|
|
# kings-guard's adaptation for a repository with no Tooling contacts.
|
||
|
|
#
|
||
|
|
# GH-DEC-2026-012 R1 confirmed the SHAPE. The layer is declared here, in this
|
||
|
|
# repository's own voice, because a layer someone else states about you is not
|
||
|
|
# a declaration.
|
||
|
|
|
||
|
|
schema_version: "0.1"
|
||
|
|
framework: netkingdom-security-layer-model
|
||
|
|
standard_version: "0.7"
|
||
|
|
companion_version: "0.2"
|
||
|
|
repository: informed-decision
|
||
|
|
layer: surface
|
||
|
|
role: pep-shaped
|
||
|
|
declared_by: INTENT.md
|
||
|
|
declared_at: "2026-09-09"
|
||
|
|
ruling: GH-DEC-2026-012
|
||
|
|
|
||
|
|
# §6.4 — informed-decision is PEP-shaped: it causes a protected side effect on
|
||
|
|
# the far side of a decision (recording an approver entry against an approval
|
||
|
|
# object). Companion §5 is owed and §6.4 applies in full.
|
||
|
|
#
|
||
|
|
# Built to v0.8 obligation 3, not v0.7, per GH-DEC-2026-011 — see pep-stance.yaml.
|
||
|
|
pep_stance: pep-stance.yaml
|
||
|
|
|
||
|
|
protected_action: "Approver entry recorded against an approval object (POST /v1/approvals/{id}/entries)"
|
||
|
|
decision_engine: access-engine
|
||
|
|
|
||
|
|
# §6 — no repository other than access-engine exposes an authorization decision.
|
||
|
|
# This surface renders a question and records a human's answer. A disposition is
|
||
|
|
# evidence of an act, never a verdict.
|
||
|
|
decision_surfaces_exposed: none
|
||
|
|
|
||
|
|
# §3.3 / GH-DEC-2026-012 R2 — YES to a presentation claim, and NO second catalog
|
||
|
|
# row: PEP and PIP are shapes a repository has; §4 records the layers it
|
||
|
|
# occupies. The permission carries three limits, and they are the substance of
|
||
|
|
# it rather than caveats on it.
|
||
|
|
presentation_claim:
|
||
|
|
emitted: true
|
||
|
|
carries: presentation-only
|
||
|
|
limits:
|
||
|
|
- id: L1-presentation-only
|
||
|
|
rule: >-
|
||
|
|
The claim carries presentation and nothing else. It MUST NOT carry,
|
||
|
|
restate, summarise or imply the decision, the verdict, or whether the
|
||
|
|
act was permitted. A consumer learns from it only what was SHOWN, never
|
||
|
|
what was DECIDED.
|
||
|
|
- id: L2-not-an-input
|
||
|
|
rule: >-
|
||
|
|
The claim MUST NOT be an input to the decision it presents for. A policy
|
||
|
|
reading view_hash to decide whether an act is permitted would let the
|
||
|
|
presenting surface contribute to its own authorization.
|
||
|
|
note: >-
|
||
|
|
Load-bearing, not a formality. GH-DEC-2026-012 accepted this
|
||
|
|
repository's argument that a renderer attesting its own rendering is not
|
||
|
|
the self-dealing that kept the approval object out of access-engine —
|
||
|
|
but only because this limit holds. Without it the two collapse into the
|
||
|
|
same failure.
|
||
|
|
- id: L3-independent-evidence-path
|
||
|
|
rule: >-
|
||
|
|
The evidence copy reaches audit-core INDEPENDENTLY of this repository.
|
||
|
|
The claim endpoint and the evidence path are different things and
|
||
|
|
neither substitutes for the other. The copy that is evidence MUST NOT be
|
||
|
|
reachable only through the party it is evidence about.
|
||
|
|
note: >-
|
||
|
|
The limit that matters most here: audit evidence is protected from the
|
||
|
|
actor being audited, and in this component the actor and the source are
|
||
|
|
the same. Architecture consequence, tracked in
|
||
|
|
docs/specs/ArchitectureBlueprint.md.
|
||
|
|
|
||
|
|
# §17 — the shared request-claim schema is still unowned. This repository
|
||
|
|
# publishes at its own boundary and yields to that schema when it exists.
|
||
|
|
# Position accepted by GH-DEC-2026-012 and matching approval-engine's in
|
||
|
|
# APPROVAL-IN-0001.
|
||
|
|
request_claim_schema:
|
||
|
|
status: unowned-upstream
|
||
|
|
local_shape: published-at-own-boundary
|
||
|
|
yields_to: taxonomy-request-claim-schema
|
||
|
|
|
||
|
|
# GH-DEC-2026-012 R3 — (b), with the authority rule written down.
|
||
|
|
binding_digest_relationship:
|
||
|
|
ruling: GH-DEC-2026-012
|
||
|
|
view_hash_authoritative_for: what-was-shown
|
||
|
|
binding_digest_authoritative_for: what-the-request-is
|
||
|
|
binding_digest_owner: approval-engine
|
||
|
|
substitutable: false
|
||
|
|
disagreement_is: >-
|
||
|
|
A finding against the presenting surface, never a fact about the request.
|
||
|
|
linkage: co-reference
|
||
|
|
linkage_rule: >-
|
||
|
|
The presentation record carries the approval or binding identifier
|
||
|
|
explicitly, and both attestations are read against that one reference. This
|
||
|
|
repository MUST NOT recompute or restate approval-engine's binding digest
|
||
|
|
from its own vocabulary — it references the digest that layer computed and
|
||
|
|
recorded.
|
||
|
|
nesting_forbidden: >-
|
||
|
|
view_hash MUST NOT contain the binding digest, and MUST NOT travel inside
|
||
|
|
hashed request material while containing it. Option (c) was refused because
|
||
|
|
nesting reproduces the hash cycle that made GH-DEC-2026-008 unimplementable:
|
||
|
|
a claim required to name the digest of a request that would come to contain
|
||
|
|
it, where a fail-closed consumer denies permanently.
|
||
|
|
|
||
|
|
# §5 applies to Staff. This is a browser-facing surface with no Tooling contact.
|
||
|
|
tooling_contacts: []
|
||
|
|
|
||
|
|
# §11 — record non-Tooling clients so the check is total.
|
||
|
|
non_tooling_clients: []
|
||
|
|
|
||
|
|
intended_non_tooling_clients:
|
||
|
|
- target: approval-engine
|
||
|
|
layer: engine
|
||
|
|
rationale: >-
|
||
|
|
GET /v1/approvals/{id} and /claim (approval:read) to render; POST
|
||
|
|
/v1/approvals/{id}/entries (approval:approve) to record a binding. Never
|
||
|
|
/consume. Requirements: approval-engine/docs/approver-surface-requirements.md.
|
||
|
|
- target: access-engine
|
||
|
|
layer: engine
|
||
|
|
rationale: >-
|
||
|
|
Decision consumed before rendering an approval to a person. A 200 from
|
||
|
|
approval-engine is not entitlement. This surface consumes a decision and
|
||
|
|
never renders one.
|
||
|
|
- target: key-cape
|
||
|
|
layer: engine
|
||
|
|
rationale: >-
|
||
|
|
Identity. Authorization-code + PKCE browser client. Identity is imported,
|
||
|
|
never invented here.
|
||
|
|
- target: audit-core
|
||
|
|
layer: engine
|
||
|
|
rationale: >-
|
||
|
|
Evidence destination for presentation records and dispositions. Must be an
|
||
|
|
independent path per limit L3-independent-evidence-path.
|
||
|
|
- target: state-hub
|
||
|
|
layer: not-catalogued
|
||
|
|
rationale: >-
|
||
|
|
Progress events. Outside §5 by the v0.5 scope rule. Recorded, not policed.
|
||
|
|
|
||
|
|
# §9.6 — presentation evidence is load-bearing: it is the only record of what a
|
||
|
|
# human was shown before binding. Atomicity and attestation cover accident and
|
||
|
|
# later tampering, never a compromised source.
|
||
|
|
evidence:
|
||
|
|
kind: load-bearing
|
||
|
|
residual: compromised-surface-presents-x-attests-y
|
||
|
|
residual_closed: false
|
||
|
|
custody: same-bound-as-every-other-source # §16 decided: no stronger archive
|
||
|
|
note: >-
|
||
|
|
GH-DEC-2026-012 states the residual is not closed in those words, and this
|
||
|
|
repository is not credited with closing it. Same disposition as
|
||
|
|
approval-engine's equivalent residual for adversarial omission at a
|
||
|
|
compromised source.
|
||
|
|
|
||
|
|
# INHERITED DECLARED GAP — GH-DEC-2026-010.
|
||
|
|
#
|
||
|
|
# Obligation 1 now requires a decision be ATTRIBUTABLE to access-engine. No
|
||
|
|
# consumer can satisfy that today: flex-auth's decision envelope is unsigned.
|
||
|
|
# This is a declared §13 gap tracked as FLEX-WP-0024, not a clean path this
|
||
|
|
# repository can walk.
|
||
|
|
#
|
||
|
|
# Stated here, and in SCOPE.md and ArchitectureBlueprint.md, because
|
||
|
|
# GH-DEC-2026-012 requires it be said in this repository's own documents rather
|
||
|
|
# than describing validation as complete.
|
||
|
|
inherited_gaps:
|
||
|
|
- id: GH-DEC-2026-010-attributability
|
||
|
|
obligation: 1
|
||
|
|
gap: >-
|
||
|
|
A decision consumed from access-engine cannot today be proven to have come
|
||
|
|
from access-engine — the envelope is unsigned.
|
||
|
|
tracked_by: FLEX-WP-0024
|
||
|
|
consequence_here: >-
|
||
|
|
This surface's record can show that a decision was obtained and what it
|
||
|
|
said. It cannot yet show it was access-engine that said it. Validation of
|
||
|
|
the decision path MUST NOT be described as complete while this is open.
|
||
|
|
status: open
|
||
|
|
|
||
|
|
declared_shapes:
|
||
|
|
"5.1": []
|
||
|
|
"5.2": []
|
||
|
|
"5.3": []
|