FLEX-WP-0040-T07: compact-sitting v14 admits present-existing requester
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:
parent
18db517e00
commit
2de0f862f9
10 changed files with 1414 additions and 2 deletions
98
docs/compact-sitting-v14-present-existing.md
Normal file
98
docs/compact-sitting-v14-present-existing.md
Normal 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…`).
|
||||
Loading…
Add table
Add a link
Reference in a new issue