docs: bring SCOPE.md back in line with what the engine actually does
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

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 <noreply@anthropic.com>
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
This commit is contained in:
tegwick 2026-09-07 13:46:31 +02:00
parent 7eeb1c7265
commit 3a19069b4b

View file

@ -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 |