NK-WP-0049: T33 attempt assembly requires secrets-engine selector --admission; T35/T36 owner prep
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Bind secrets-engine selector/source pins and founder-signed attempt admission
(d1ab097d) as T33's required pre-key step; record kc-tls owner (RCLUSTER-WP-0018)
and public served-chain metadata; add founder gates T39 (TLS disposition,
decision 9f9d0d88) and T40 (attempt signature). Preparation only.

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 01:04:19 +02:00
parent d2d1dbcd36
commit f890760176
4 changed files with 175 additions and 3 deletions

View file

@ -535,3 +535,52 @@ T20/T31 are done. Safe evidence and source/ciphertext/target bindings are in
This accepts internal readback and stored-row signature continuity. Existing-token
MFA, Authelia and KeyCape authentication remain separate; event completeness is
not claimed. The published Storage Share kit remains its recorded version.
## KeyCape original attempt assembly (NK-WP-0049-T33) — 2026-10-21
This is the attended order for the original KeyCape attempt. It is preparation and
authorizes nothing. T18 owns the actual run. Abort at any non-zero step, before the
hidden key prompt.
1. **Founder attempt admission (surviving offline authorization).** The founder
signs a `secrets-engine.recovery-attempt-admission.v1` document with namespace
`secrets-engine-recovery-attempt`, case `secrets15-nk49-readiness`, a window of
at most 24 h, issuer `https://kc.coulomb.social`, and the exact hashes below
(secrets-engine `docs/founder-admission.md`; approved in principle by hub decision
`d1ab097d-cc79-4612-9c17-bb9b364081ac`, not yet signed). The verifier anchor
`/etc/secrets-engine/admission/allowed_signers` (root-owned, runtime-unwritable)
must exist on the attempt host. It is absent on the workstation today.
2. **Selector preflight with admission. This step is required.** From a secrets-engine checkout at
`0f44fbeea18147e65f379632621f2f29ded5f310` (or a replacement the owner names):
```sh
python3 -I tools/check-keycape-recovery-selector.py \
--selector docs/keycape-recovery-selector.json \
--source-sha256 sha256:c0ade429edf452ad17f05d690b7ebef091db7f1a42b5ac350f1e40955c8586c0 \
--admission <attempt.json>
```
Proceed only with exit 0 and status `founder_admitted_attempt_not_native_acceptance`.
The selector bytes must hash to
`sha256:02077af3c18b24f5e4a85992a3d4d0df51a8e458de1e48b48f7eb5f482257012`. The
NK49 admission's consumer block must equal the selector's eight fields
(`secrets-engine-openbao`, `KEYCAPE_SECRETS_ENGINE_OPENBAO_CLIENT_SECRET`,
audience `secrets-engine-openbao`, scope `openbao:login`, subject
`service:secrets-engine`, tenant `tenant:platform`, roles `secrets-engine`,
deny `openbao:admin`). A pass shows founder authority for this one attempt. It
is not native acceptance and not single use. The NK49 execution keeps single-use
consumption and cleanup.
3. **TLS/trust input per T35 disposition** (founder decision
`9f9d0d88-837a-433c-8a11-d30b633b0073`). Under reissue, record the public chain
with railiance-cluster `tools/public-tls-metadata.py` at attempt time and compare
it to the admission. Under original recovery, use only the custody path that
RCLUSTER-WP-0018-T03/T04 delivers. No self-signed substitute is allowed. The TLS
key stays in the owner's own terminal.
4. **Existing six-argument launcher** `tools/bootstrap-recovery/run-isolated-keycape.sh`
with the reviewed admission digest. Its T34 source closure and abort/cleanup
behaviour are unchanged. The private manifest is derived and the archive
registration is compared to the selector inside custody only.
Still open before T33 can close: T35 owner metadata (RCLUSTER-WP-0018-T02) and
the founder disposition; the execution deadline, safe receipt location and
independent receipt verifier fixed in the packet; the anchor installed on the
attempt host. Public observations are in
`docs/evidence/2026-10-21-nk49-t33-readiness/readiness-observation.json`.

View file

@ -0,0 +1,63 @@
{
"schema": "nk49.t35-t36-readiness-observation.v1",
"observed_at": "2026-10-21",
"status": "preparation_only_not_recovery_or_owner_assent",
"t35_public_tls": {
"source": "currently served chain at kc.coulomb.social:443 (public), projected by railiance-cluster tools/public-tls-metadata.py @ a594840; trust file = Mozilla ISRG Root X1",
"originality_proven": false,
"schema": "nk49.public-tls-metadata.v1",
"status": "public_metadata_only_not_originality_or_owner_assent",
"tls_cert_sha256": "f14c928a51b3cf98b0c0964b9bf9a33f4b37e9f30b5c3e949f819fe120ebd15a",
"trust_sha256": "22b557a27055b33606b6559f37703928d3e4ad79f110b407d04986e1843543d1",
"leaf_public_spki_sha256": "sha256:236fa4dcf1ce1d58be398dd01ab067157281e54356a550be35a157527b464b6d",
"leaf_dns_sans": [
"kc.coulomb.social"
],
"leaf_not_before": "2026-09-25T17:57:22+00:00",
"leaf_not_after": "2026-12-24T17:57:21+00:00",
"server_chain_certificates": 3,
"trust_certificates": 1,
"network_contacted": false,
"private_key_argument_supported": false,
"issuer_source": "net-kingdom sso-mfa/k8s/cert-manager/issuers.yaml: ClusterIssuer letsencrypt-prod, ACME HTTP-01, ingressClassName traefik, account key secret letsencrypt-prod-account-key",
"credential_routing": "warden route find returned only SSH-certificate lanes; no TLS lane. Not evidence of absence of an owner.",
"owner": "railiance-cluster (cert-manager, Traefik, cluster backup posture); live work RCLUSTER-WP-0018 T02 todo, T03/T04 wait, T05 todo"
},
"t36_selector": {
"owner_repo": "secrets-engine",
"commit": "0f44fbeea18147e65f379632621f2f29ded5f310",
"selector_path": "docs/keycape-recovery-selector.json",
"selector_sha256": "sha256:02077af3c18b24f5e4a85992a3d4d0df51a8e458de1e48b48f7eb5f482257012",
"source_path": "src/secrets_engine/service_auth.py",
"source_sha256": "sha256:c0ade429edf452ad17f05d690b7ebef091db7f1a42b5ac350f1e40955c8586c0",
"consumer": {
"client_id": "secrets-engine-openbao",
"secret_env": "KEYCAPE_SECRETS_ENGINE_OPENBAO_CLIENT_SECRET",
"audience": "secrets-engine-openbao",
"scope": "openbao:login",
"subject": "service:secrets-engine",
"tenant": "tenant:platform",
"roles": "secrets-engine",
"deny_scope": "openbao:admin"
},
"preflight_cases": [
{
"case": "exact selector + source hash, no admission",
"rc": 0,
"status": "source_selector_matches_not_native_assent"
},
{
"case": "wrong source hash",
"rc": 1,
"status": "source_selector_refused"
},
{
"case": "unsigned admission document",
"rc": 1,
"status": "source_selector_refused"
}
],
"admission_anchor_on_workstation": "absent (/etc/secrets-engine/admission)",
"builder_tests": "net-kingdom tests/test_private_manifest_binding.py + tests/test_prepare_isolated_keycape.py: 27 passed (synthetic inputs; positive bindings, archive/size/transfer/source/issuer/consumer-overlap/symlink/mode/digest negatives)"
}
}