From 3a19069b4b56049a9c92c2662479099827b17c36 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 7 Sep 2026 13:46:31 +0200 Subject: [PATCH] docs: bring SCOPE.md back in line with what the engine actually does MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SCOPE.md is the capability boundary other agents read, and three of its claims had gone stale — one of them describing checks that were deliberately removed months of decisions ago. - It said the engine "builds and validates the flex-auth ActionAuthorization profile", including State Hub authority and an independently required distinct-approver threshold. All three are wrong: ActionAuthorization is deferred and never ratified (FLEX-DEC-2026-006) and nothing validates it, the State Hub authority constant was removed because State Hub is a read model with no runtime approval authority, and the approver threshold is folded into valid_now by the issuer rather than re-checked here. Replaced with the actual two-artifact split from GH-DEC-2026-005, including the reduction in what this engine verifies alone, stated rather than buried. - It said the access-engine serving endpoint does not exist. It does, and step 2 is proven against it. Step 1 is the unserved half. - The layer-model table row repeated the ActionAuthorization framing. Also records the structured-correspondence rule and the tenant requirement in the capability list, and adds responder authentication to Not Implemented — it is a real gap in what this engine can promise, not merely flex-auth's open work. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01E4tNMAYcSQmZWUE4wqP4ij Assistant: claude-code Assistant-Model: opus Assistant-Process: 715726@bnt-lap001 Assistant-Session: 80a42b32-cba6-4b23-8be0-68819b1a6092 --- SCOPE.md | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/SCOPE.md b/SCOPE.md index 91b057f..102211c 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -40,17 +40,35 @@ point, not an identity provider, and not a general secrets API. - Resolves legacy lane decisions from State Hub by id, with tracked local YAML mirrors retained only for non-production and explicit throwaway demos. This is not an access-engine decision record. -- Fails every production live command closed while there is no durable - access-engine / ActionAuthorization record. That fail-closed row is the - published unreachable-engine stance for `prod` in `pep-stance.yaml`. A local +- Fails every production live command closed while the two-artifact chain + cannot be completed — today because approval-engine does not serve the + approval-claim endpoint. That fail-closed row is the published + unreachable-engine stance for `prod` in `pep-stance.yaml`. A local mirror can unlock a prod-labeled lane only when an explicit unsafe-demo switch, disabled Hub URL, and loopback OpenBao target are all present. Plans and `apply --dry-run` remain usable. -- Builds and validates the flex-auth `ActionAuthorization` profile, including - exact lane/stage/action/target/actor/purpose matching, bounded validity, - State Hub authority, request digest and decision binding, accepted policy - package/version, and an independently required distinct-approver threshold. - Validation is consume-only; this process does not evaluate policy. +- Validates the two-artifact authorization chain, split by owning layer per + `GH-DEC-2026-005`. The approval-engine **approval-claim** supplies the approval + fact: issuer, `valid_now`, consumption state, freshness, `reason_code`, a + required `binding.pdp_path` declaration, and the `pdp_digest` tie to this exact + action. The flex-auth **DecisionEnvelope** supplies the decision: effect, + structured binding correspondence to the proposed action, canonical request + digest, lifetime, and the accepted policy package/version pin. Neither layer + republishes the other's data, and validation is consume-only; this process does + not evaluate policy. +- Compares the decision binding by structured correspondence rather than + byte-equality, per flex-auth's published normalization rule: everything the + engine proposed must survive unchanged, registry enrichment may add only + `type`/`tenant`/`attributes`, and an enriched tenant must be the request + tenant. The request digest is verified against the tuple the binding carries. + The CheckRequest carries the package's `known_tenant`; an absent tenant is a + `wrong_tenant` denial, not an ignored field. +- The `ActionAuthorization` object is **deferred and never ratified** + (`FLEX-DEC-2026-006`); nothing validates it. There is no State Hub authority + constant — State Hub is a read model and holds no runtime approval authority. + The distinct-approver threshold is folded into `valid_now` by the issuer and is + no longer an independent consumer-side check, which is correct on layering and + a real reduction in what this engine verifies alone. - Renders guarded OpenBao plans for exact consumer ACL policies and AppRoles. - Applies policy and AppRole metadata idempotently. Existing mounts render a non-mutating check and are never created by apply. @@ -227,10 +245,18 @@ metadata. `secrets-engine wrap` implements response-wrapped operator handoff. service-auth / `service-jwt` provider. - Provider-side / workload consumer rotation. Overlay lane state is local and non-secret only; it is not an OpenBao-side state machine. -- Resolution of a durable access-engine decision record / State Hub - ActionAuthorization and wiring its validated approval threshold to each - production handler. The consumer validator exists; the serving endpoint does - not, so live production remains fail-closed. +- Protocol step 1 in production: approval-engine does not yet serve the + approval-claim endpoint (`APPROVAL-WP-0002-T03`), so `resolve_consume_binding` + returns no binding and live production remains fail-closed. Step 2 is served + and proven — a real CheckRequest against the deployed `flex-auth-secrets-engine` + pin returns a validated v2 decision over the owner-documented access path + (`docs/pdp-access-path.md`). +- Responder authentication for the decision channel. `flex-auth.decision-record.v1` + carries no signature and pins serve plain HTTP, so a responder knowing the + published package and version could return a well-formed allow. Fail-closed + protects against a PDP that is absent, not one that lies (`FLEX-DEC-2026-010`). + The enforced loopback address shape stands in for this until `FLEX-WP-0024` + ships detached signatures. - Direct access-engine evaluation, JWT signature verification, or identity authentication. KeyCape claims receive only a consumer preflight; OpenBao is responsible for cryptographic JWT validation. @@ -306,7 +332,7 @@ Working companion: `net-kingdom/SECURITY-COMPANION.md`. | Obligation | Current | Intended | | --- | --- | --- | | Layer declaration | `INTENT.md` frontmatter + `layer.yaml` | Keep in this repository's own voice | -| One decision point | Consumer validator for ActionAuthorization; production live fail-closed from `pep-stance.yaml` | Consume an access-engine decision record before every protected side effect | +| One decision point | Two-artifact consumer validation (approval-claim + DecisionEnvelope); step 2 proven against the deployed pin, step 1 unserved so production live stays fail-closed from `pep-stance.yaml` | Consume an access-engine decision record before every protected side effect | | PEP stance | Runtime loads `pep-stance.yaml`; named stance fields on privileged evidence | Unchanged map; T02 replaces fail-open residue with a decision record | | Evidence bound | `evidence-classification.yaml`; load-bearing local outbox; heartbeat command | Drain to `audit-core` once that sender is admitted | | SSH-CA surface | Contract at `docs/ssh-ca-signing-contract.md`; not shipped | Engine API after ops-warden assent |