feat(admission): founder-signed trust and recovery-attempt admission (WP14 T02, WP15 T05)
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s

Reuse the gated-executor approval pattern: ssh-keygen -Y signatures over exact
bytes, verified against a runtime-unwritable allowed_signers anchor with a fixed
namespace per purpose. load_trust now refuses responder trust without a founder
admission; the KeyCape selector preflight gains --admission for one exact,
bounded recovery attempt. WP14 re-pointed to CUST-WP-0082-T06 and split founder
key admission into human-gated T04; WP15 T04 now requires the signed admission.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 809600@bnt-lap001
Assistant-Session: 40ba228f-c8a0-4ec9-bb29-3129951afdc4
This commit is contained in:
tegwick 2026-10-21 00:30:59 +02:00
parent 497040c58c
commit ebd8e49aff
15 changed files with 469 additions and 29 deletions

View file

@ -8,18 +8,29 @@ status: active
owner: codex
topic_slug: secrets-engine
created: "2026-10-12"
updated: "2026-10-16"
updated: "2026-10-21"
flavor: implementation
depends_on: []
related: [CUST-WP-0082, FLEX-WP-0024, GEXEC-WP-0001, SECRETS-WP-0013]
state_hub_workstream_id: "7252469d-d7a5-5c18-8911-b511b8c6a736"
---
Native owner work for CUST-WP-0080 G13. Reuses the accepted Check contract and
Native owner work for G13, now tracked as CUST-WP-0082-T06. CUST-WP-0080 finished
on 2026-10-19 and transferred its T21 native acceptance obligation to WP-82 without
implementing it. Reuses the accepted Check contract and
FLEX-WP-0024 producer signature surface; does not create another PDP or grant
any catalog-lane execution authority. SECRETS-WP-0013 still owns task-scoped
protected execution. Transport review is complete; key admission and native
rollout remain separate gates below.
2026-10-21 review against gated-executor (GEXEC-WP-0001, accepted on railiance01
2026-10-20): the estate now has a working, founder-held exact-byte approval
mechanism (`ssh-keygen -Y`, runtime-unwritable `allowed_signers`, per-purpose
namespace). T02's open "independent admission" gap had no concrete anchor before
this; it now reuses that pattern. T02 closes at source scope. The founder's actual
signature over the real producer trust file is split out as human-gated T04, and
T03's native rollout depends on it.
## Prevent the Check credential from leaving the admitted local transport
```task
@ -44,7 +55,7 @@ This closes the source transport defects only; T02/T03 remain mandatory.
```task
id: SECRETS-WP-0014-T02
status: progress
status: done
priority: high
state_hub_task_id: "877782e5-045b-5186-8b95-82e25db21a5a"
```
@ -86,21 +97,52 @@ artifacts, signed HTTP consumption and missing/tampered artifact refusal; they d
not admit packages, keys or a production prefix. T02 remains progress and T03
wait; no native installation, trust change or protected entitlement is claimed.
2026-10-21 founder admission anchor (closes T02 source scope): `load_trust` now
refuses any trust file without a sibling `<trust>.sig`. The signature must be made
with `ssh-keygen -Y sign -n secrets-engine-pdp-trust` by exactly one principal in
`/etc/secrets-engine/admission/allowed_signers`, and is verified over the exact
bytes that are parsed. That anchor and directory must not be writable by, or owned
by, the running UID (gated-executor rule), which closes the same-UID trust
self-admission path recorded above. `src/secrets_engine/founder_admission.py`;
operator procedure `docs/founder-admission.md`. Tests cover unsigned, edited after
signing, wrong namespace (including `gexec-approval`), unknown signer key,
runtime-owned or group-writable anchor and missing anchor, plus re-signed
rotation overlap/removal in the existing signature and installed-bundle tests.
No production key, anchor installation or trust admission occurred. That work is T04.
## Admit the real producer verification key by founder signature
```task
id: SECRETS-WP-0014-T04
status: wait
priority: high
needs_human: true
depends_on: [SECRETS-WP-0014-T02]
blocking_reason: "Needs Access's real producer kid/public key/custody receipt (FLEX-WP-0024) and the founder's signature over the exact trust file; the anchor install under /etc needs root."
```
Install `/etc/secrets-engine/admission/allowed_signers` (root-owned) with the
founder's approver public key, the same key that signs gexec approvals. Write
the exact `pdp-trust.json` for the real producer kid/key and pin. The founder
signs it in namespace `secrets-engine-pdp-trust`. Record only the principal, key
fingerprint and trust-file hash. This is founder action, not worker
work. A local signature test is not admission.
## Verify the admitted native consumer and rotation path
```task
id: SECRETS-WP-0014-T03
status: wait
priority: high
depends_on: [SECRETS-WP-0014-T02]
blocking_reason: "Requires reviewed verification-key admission, source enforcement and exact native rollout receipt; no production trust change is proposed yet."
depends_on: [SECRETS-WP-0014-T02, SECRETS-WP-0014-T04]
blocking_reason: "Requires the founder-signed key admission (T04) and an exact native rollout receipt; source enforcement is done (T02)."
state_hub_task_id: "85aa4c78-b66d-5201-8e31-0ed50e7eaeec"
```
Under an exact reviewed rollout, prove the real pin and consumer accept the
admitted signer, reject forgery/downgrade, rotate without accepting removed keys,
and preserve request/approval binding, lifetime and single-use consumption.
Retain rollback and failure evidence. Update CUST-WP-0080 G13 only with these
Retain rollback and failure evidence. Update CUST-WP-0082-T06 (G13) only with these
native receipts; do not equate passing transport tests with closure.

View file

@ -8,10 +8,10 @@ status: active
owner: codex
topic_slug: custodian
created: "2026-10-17"
updated: "2026-10-17"
updated: "2026-10-21"
flavor: implementation
depends_on: []
related: [CUST-WP-0080, NK-WP-0049, SECRETS-WP-0012, SECRETS-WP-0008, SECRETS-WP-0013]
related: [CUST-WP-0082, NK-WP-0049, SECRETS-WP-0012, SECRETS-WP-0008, SECRETS-WP-0013, SECRETS-WP-0014, GEXEC-WP-0001]
state_hub_workstream_id: "68a0642e-4908-5260-89c9-3adce60e6a4d"
---
@ -22,6 +22,14 @@ it is not native assent. Finished0012 remains finished; functional adoption/back
entitlement stay0008T06/0013. No new grant,
secret fetch, provider login, production redirect or external message occurred.
2026-10-21 review against gated-executor (GEXEC-WP-0001, accepted on railiance01
2026-10-20): the T03 plan requires "surviving offline founder authorization" bound
to the exact source/issuer/case/deadline, with "no new auth or approval service".
The gexec approval pattern (founder `ssh-keygen -Y` signature, runtime-unwritable
`allowed_signers`) is that existing mechanism, and it verifies offline during an
outage. T05 makes it a checkable precondition of the selector preflight, and T04
now requires it. CUST-WP-0080 finished; its remaining native gates live in CUST-WP-0082.
## Establish exact current intended source selector
```task
@ -94,6 +102,29 @@ original OpenBao and its custody/OIDC/MFA graph for full consumer continuity;
exact native action approval and resource-server negative/revocation receipts.
Protected backend operation entitlement stays in existing0008T06/0013.
## Require founder-signed exact attempt admission
```task
id: SECRETS-WP-0015-T05
status: done
priority: high
assignee: claude
depends_on: [SECRETS-WP-0015-T03]
```
Completed 2026-10-21 as source. `tools/check-keycape-recovery-selector.py --admission`
verifies a `secrets-engine.recovery-attempt-admission.v1` document. It binds the
exact selector-file SHA-256, the consumer source hash, the issuer, the case id and
a window of at most 24 hours. The founder signs it in namespace
`secrets-engine-recovery-attempt` against the shared runtime-unwritable anchor
(`src/secrets_engine/founder_admission.py`, `docs/founder-admission.md`; same
anchor as SECRETS-WP-0014). A pass reports
`founder_admitted_attempt_not_native_acceptance`. Synthetic tests cover every
binding mismatch, the expired/early/overlong window, edits after signing, the
trust/gexec namespaces, an empty signature, a changed selector and suppressed CLI
diagnostics. No private archive, token, endpoint or real founder signature was
touched. Single-use consumption and cleanup remain in the bounded NK49 execution.
## Verify the separately admitted actual isolated consumer result
```task
@ -102,11 +133,13 @@ status: wait
priority: high
assignee: codex
needs_human: true
depends_on: [SECRETS-WP-0015-T03, NK-WP-0049-T33]
blocking_reason: "Source plan delivered in T03. Await NK-WP-0049-T33 original TLS/archive/private admission, exact native owner authority, and original OpenBao/custody recovery for actual consumer continuity."
depends_on: [SECRETS-WP-0015-T03, SECRETS-WP-0015-T05, NK-WP-0049-T33]
blocking_reason: "Source plan (T03) and signed-admission check (T05) delivered. Await NK-WP-0049-T33 original TLS/archive/private admission, the founder's signed attempt admission for the exact case, and original OpenBao/custody recovery for actual consumer continuity."
state_hub_task_id: "aeec6eb0-39e2-5f7c-8f5d-778133edfc73"
```
Before any key prompt, the selector preflight must pass with `--admission` on the
founder-signed attempt document for this exact case (T05).
Only a separately admitted owner action can establish actual archived registration,
issuer trust, native negative checks and consumer continuity. Source selector and
historical provider proof do not fill this gate. No production consumer redirect,