FLEX-WP-0040-T07: compact-sitting v14 admits present-existing requester
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 1m15s

v14 (proposed, sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde)
keeps every v13 decision and admits approval requester service:nk-bind-executor
only from submitter nk-bind-executor, memo class and approval action
bounded-execution, an aal2 human reviewer, and never the approval actor
itself (GH-DEC-2026-026 class C2). v13 stays unchanged as rollback reference.
The admission generator skips present_existing registry rows.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5502@bnt-lap001
Assistant-Session: 68b3b02f-5d0f-4e71-8421-796f62e50196
This commit is contained in:
tegwick 2026-11-01 00:40:35 +01:00
parent 18db517e00
commit 2de0f862f9
10 changed files with 1414 additions and 2 deletions

View file

@ -0,0 +1,98 @@
# Owner note: compact-sitting v14, present-existing requester
**Date:** 2026-11-01
**Owner:** access-engine (flex-auth PDP)
**Workplan:** `workplans/FLEX-WP-0040-bounded-execution-pdp-gate.md`, task FLEX-WP-0040-T07
**Answers:** informed-decision `docs/decision-services-alignment-answer.md` (commit `0e66a33`,
INFD-WP-0010), blocker 1 and open question 3. Doctrine: gate-house GH-DEC-2026-026
(an approval something executes against is class C2: human approver at aal2, and
the actor that files the approval may never approve it).
## Package
| Field | Value |
| --- | --- |
| package | `informed-decision.compact-sitting` |
| version | `v14` (status `proposed`) |
| package_digest | `sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde` |
| source | `examples/informed-decision-present-existing-review/policy.md` |
| pin | `examples/informed-decision-present-existing-review/pin.json` |
| rollback | v13 `sha256:31be5985…3711873`, unchanged in `examples/informed-decision-lifecycle-review/` |
v14 lives in a new directory so the deployed v13 package, its pin and the release
values stay byte-identical as the rollback reference.
## Behaviour
Unchanged from v13: every exact-record and list-only decision; the attribute branch
for requester `informed-decision` (same generated submitter/class sets, same reasons);
any other requester is still `requester_mismatch` (or an earlier class/submitter refusal).
Added: an owner-authored `present_existing_profiles` table with one entry:
| approval_requester | intake_submitter | memo_class | approval_action |
| --- | --- | --- | --- |
| `service:nk-bind-executor` | `nk-bind-executor` | `bounded-execution` | `bounded-execution` |
When `context.approval_requester` names this profile, the request is allowed
(`present_existing_eligible`) only if, in addition to every v13 attribute guard
(authenticated human, tenant, review group in the subject's groups, recipient for
`list`, resource shape, `approval_human_control == true`, UUID approval id, digest
shape, memo version >= 1):
- `intake_submitter` and `memo_class` equal the profile (otherwise `unknown_submitter` /
`unknown_class`); the generated sets are not widened, so the executor cannot use the
create path and this requester cannot borrow state-hub's class;
- `context.approval_action == "bounded-execution"` (otherwise, or when absent,
`approval_action_not_admitted`);
- the reviewing human holds KeyCape AAL2 with MFA `pwd`+`otp`, 900 s fresh for read and
acts, 12 h for list (otherwise `identity_refused` / `stale_mfa`);
- the reviewing human's `subject.id` is neither `service:nk-bind-executor` nor
`nk-bind-executor` (`self_approval_refused`).
The PDP still proves no pin. The consumer re-reads the approval and compares actor,
human-control flag and binding digest before asking, as today.
## Consumer change required (informed-decision)
v14 needs one new context key, `approval_action`, on present-existing requests only.
Today `policy.build_request` accepts exactly five intake keys and `store._intake_context`
does not carry the action, so a v14-pinned consumer would be refused with
`approval_action_not_admitted` until both are changed. Suggested shape: record the
approval's `binding.action` in the ledger metadata at intake (already verified there),
emit it as `approval_action` for present-existing memos, and in `review._authorize`
also compare the live `binding.action` to it. Requests for requester `informed-decision`
may omit the key; v14 ignores it there.
`tools/gen_informed_decision_admission.py` now accepts a registry row with a
`present_existing` profile and skips it, so adding the nk-bind-executor row to
informed-decision `deploy/intake-submitters.json` does not change the generated sets
or break `--check`.
## Tests
- 46 embedded Rego tests (32 from v13 unchanged, 14 for v14: positive read/acts/list,
self-approval for acts and list, aal1/no-MFA/password-only, stale MFA, service subject,
wrong or missing action, wrong submitter/class, other service requester, executor on
the create path, and v13 requester unaffected by the new key or subject).
- `internal/policy/informed_decision_present_existing_test.go`: v14 package valid, pin
matches the computed digest, 12 engine evaluation cases, and the generator skips
present-existing rows.
- `go test ./internal/policy/` passes; generator `--check` in sync.
## Live steps (founder; none performed by this owner)
1. informed-decision lands the `approval_action` context change above.
2. Build the access-engine image from the commit carrying v14 (owner CI), scan it.
3. Update the review release values (`values/informed-decision-sitting.yaml` and the
`access-engine` twin) to the new image digest and
`--policy /opt/flex-auth/examples/informed-decision-present-existing-review/policy.md`
(registry path may stay on the lifecycle-review directory or the identical copy);
dry-run, diff, then upgrade the Helm release with `--atomic`.
4. Pin informed-decision to `informed-decision.compact-sitting` / `v14` /
`sha256:8911458f36f1a60598aa19592a2d752a74dffe2617fd86238407ac87bc300fde` in the same
release window: the `policy` object of its review runtime (`deploy/lifecycle/service.candidate.json`
`runtime.json`, and `deploy/lifecycle/admission.candidate.json`). A version or digest
mismatch fails closed.
5. Rollback: restore the release values in force before step 3 (v13 policy path and the
image then deployed) and the consumer's v13 pin (`sha256:31be5985…`).