FLEX-WP-0035 T01-T03: application access readback pin
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 58s

Contract accepted by user-engine; FLEX-DEC-2026-019 accepted.
- serve-readback: dedicated pin, no enforcement routes, own caller binding
- CheckRequest.purpose hashed into every digest when set; /v1/check refuses it
- POST /v1/readback/application_access and GET /v1/readback/systems
- optional client_binding on protected systems; readback schemas
- schemaguard implements maxItems
- T05 added: informed-decision needs an application.access rule over
  realm-level claims (its lifecycle rules read authentication_audience)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 609675@bnt-lap001
Assistant-Session: 4987a36e-eb38-4b10-803c-15a29cd78212
This commit is contained in:
tegwick 2026-10-09 20:02:31 +02:00
parent b6d6bff85e
commit 8f2ba75e4a
23 changed files with 1314 additions and 44 deletions

View file

@ -39,7 +39,7 @@ record.
```task
id: FLEX-WP-0035-T01
status: progress
status: done
priority: high
state_hub_task_id: "0585a684-d462-5caa-937f-b1730efddbd8"
```
@ -56,6 +56,11 @@ a PEP decision by another system.
Gate: written contract in `docs/` plus an ADR or decision record; reviewed with
user-engine before code.
2026-10-09: user-engine accepted the contract (message `f54df082`) with three
amendments, now folded in: the `/v1/check` subject shape with `tenant`, the
rendering table, and a separate `USER_ENGINE_READBACK_TOKEN_FILE`. Also added: a
realm-level-claims-only rule. `FLEX-DEC-2026-019` is accepted.
2026-10-09: activated by the founder. Draft contract
`docs/application-access-readback.md` and `FLEX-DEC-2026-019` (proposed). Key
finding: each pin loads one consumer's package, so no existing pin can answer
@ -68,7 +73,7 @@ user-engine with four review questions. The gate closes on their reply.
```task
id: FLEX-WP-0035-T02
status: todo
status: done
priority: high
depends_on: [FLEX-WP-0035-T01]
state_hub_task_id: "eb0b6a91-7750-553b-b87f-c4262eb9df07"
@ -82,11 +87,22 @@ accept, and its decisions must say so in the binding.
Gate: tests prove a readback-scoped token gets 403 on `/v1/check` for a foreign
system and is admitted only on the readback route.
2026-10-09 done. `flex-auth serve-readback` is a separate subcommand that mounts
no `/v1/check` or `/v1/batch_check` (404 there). `--readback-caller` is bound
under the non-system key `application-readback`. `CheckRequest.purpose` is
hashed into `request_digest`, `submitted_request_digest` and
`approval_binding_digest`, but only when set, so enforcement digests are
unchanged. `/v1/check` refuses a request that carries it. Tests:
`cmd/flex-auth/readback_test.go`
(`TestReadbackPrincipalCannotCheckOnEnforcementPin`,
`TestReadbackHTTPCallerAndRequestShape`, `TestReadbackWithholdsUncommittedAllow`)
and `pkg/api/purpose_test.go`.
## Readable protected-system registry
```task
id: FLEX-WP-0035-T03
status: todo
status: done
priority: medium
depends_on: [FLEX-WP-0035-T01]
state_hub_task_id: "5dbb3280-8490-58a5-a0bb-f3883e568f58"
@ -99,17 +115,44 @@ inside access-engine; user-domain admins get no grant surface from this work.
Gate: endpoint plus schema, admitted only for the readback caller, tests.
## Deploy to the user-engine pin
2026-10-09 done. `GET /v1/readback/systems`; optional `client_binding` on
`protected_system_manifest`. Schemas `readback_request`, `readback_response`
and `readback_systems` are checked against live service output
(`TestReadbackShapesMatchSchemas`). schemaguard gained `maxItems` for this.
## informed-decision declares `application.access`
```task
id: FLEX-WP-0035-T05
status: todo
priority: high
```
informed-decision is the first participant. Its `informed-decision.lifecycle`
package reads `authentication_audience`, which the readback must not use
(contract §3). Add an `application.access` rule over realm-level claims only,
as a new package version with fixtures. Coordinate the version bump with
informed-decision, because its own pin must run the same digest. Add
`client_binding` to its registry entry.
Gate: package valid with allow/deny fixtures, informed-decision agrees, and
the rule reads no audience, authorized-party or client-scoped claim.
## Deploy the readback pin
```task
id: FLEX-WP-0035-T04
status: wait
needs_human: true
depends_on: [FLEX-WP-0035-T02, FLEX-WP-0035-T03]
depends_on: [FLEX-WP-0035-T05]
blocking_reason: "Live pin change on railiance01 needs founder go."
priority: medium
state_hub_task_id: "82a8a7e6-54e9-5262-a271-24ce2f161362"
```
Roll the readback route and its caller binding onto `flex-auth-user-engine`,
then hand user-engine the evidence that unblocks `USER-WP-0026-T03`.
Add `values/flex-auth-application-readback.yaml` (or a deploy manifest) for a
dedicated `flex-auth-application-readback` pin, plus a test asserting that its
package paths match each participant's own pin values (digest-equality, §4).
Add the user-engine ingress rule, then get the founder's go for the rollout.
The pin ships with the image that contains `serve-readback`. Hand user-engine
the evidence that unblocks `USER-WP-0026-T03`.