Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 4515@bnt-lap001 Assistant-Session: 0bf96127-6e04-41be-bfda-d11717c3f354
94 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | flavor | depends_on | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| NK-WP-0049 | workplan | Remove bootstrap secret output and verify separated recovery custody | infotech | net-kingdom | finished | codex | netkingdom | 2026-10-12 | 2026-10-27 | implementation | 17d315f0-829e-57c7-85cc-3a7914152804 |
Native owner work for CUST-WP-0080 G08. This workplan remains active until the remaining caller, service-recovery and custody acceptance gates are satisfied. NK-WP-0045 covers the non-secret root-grant record. Founder-deferred exposure rotation remains in CUST-WP-0073-T05; this plan does not silently reopen it.
Replanned 2026-10-16 at the operator's request: substantial completed work is
now represented by completed tasks, and remaining work has separate deliverables,
dependencies and acceptance criteria. T01–T03 retain their historical IDs and Hub
UUIDs. Completed parts of the old T02/T03 umbrellas are extracted into T04–T14;
T02 now covers the current-caller ledger and T03 retains final owner acceptance.
These are retrospective task records of evidenced work, not additional delivery
or newly granted authority. The earlier dated narrative remains in Git at
cc2dd01; its evidence references are carried into the tasks below.
Closed 2026-10-27 (finished, builder mode): 42 tasks done; 2 cancelled (T43 phase B paused, T44 moved). All production-readiness residuals live in NK-WP-0055.
Next actions: none here; continue in NK-WP-0055.
Closure: T03 assembles owner acceptance after its named dependencies pass. Passing archive recovery does not prove existing-user authentication, retained MFA-token decryption, historical audit signatures or current caller admission. The verified backup job stays active while those separate tasks are completed.
Remove secret-bearing output and ambient root discovery
id: NK-WP-0049-T01
status: done
priority: high
assignee: codex
state_hub_task_id: "d7ca8d5f-c5ff-5cba-bd25-038cb53ffe4e"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
2026-10-12: regression reproduced emergency/reprint root export, generation prefix disclosure, permissive file modes, dry-run side effects and unattended entry. Replaced emergency export with a non-secret guide (legacy secret-input arguments refused), suppressed generation prefixes/tracing and set private permissions. Bootstrap requires the registered public recipient and an attended terminal; never generates/discovers a permanent private key. Encrypted resume requires an explicit matching temporary custody key before cluster activity. Dry-run is a non-mutating plan. The live cluster/apply path was not executed.
A fresh uniquely named encrypted ops bundle follows apply; old delivery flags
cannot skip current acknowledgment. New acknowledgment state binds its SHA256
and timestamp. Declining stops before cleanup/completion. This is an operator
statement, not an independent restore receipt. Historical fields remain unchanged.
Make/help/status/console and current credential guidance reflect that distinction.
Evidence and exact source manifest: Custodian
docs/evidence/2026-10-12-netkingdom-security/bootstrap-handoff.json.
Harden custody, SOPS and rotation source entry points
id: NK-WP-0049-T04
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T01]
state_hub_task_id: "04c4e8be-5bd8-5d5c-99b1-79d8ae758462"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-12–13. Public-recipient-only encryption, explicit temporary custody, private no-overwrite output, sanitized diagnostics, stdin-only secret transport and failed-operation cleanup replace ambient-key and output paths. SOPS read/edit/data-key rotation preserve recipient/MAC/source-version guards; component rotations preserve unrelated fields and retain recovery candidates. This records source and disposable-native proof, not live rotation or revocation.
Evidence: Custodian docs/evidence/2026-10-12-netkingdom-security/ receipts
custody-entrypoints.json, sops-make-entrypoints.json, rotation-output.json,
and admin-bootstrap.json; October13 sops-write-callers.json.
Repair component, diagnostic, LDAP and resolver callers
id: NK-WP-0049-T05
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T04]
state_hub_task_id: "e8e38f42-609e-5c07-a8e6-e73c8eb4ae95"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-13–14. Repaired KeyCape configuration and component Secret publication, original privacyIDEA key export/restore transport, scoped MFA counts, LDAP group maintenance and configuration-preserving resolver cutover. Retired unsafe personal-token mint/refresh and direct LDAP lifecycle shortcuts. Disposable native PI/LLDAP tests and source regressions passed; estate provider admission, historical credential validity and service authentication remain T21/T22.
Evidence: Custodian October13 keycape-caller-reconciliation.json,
service-secret-callers.json, privacyidea-key-custody.json,
mfa-state-diagnostic.json, realm-bootstrap-repair.json; October14
legacy-lldap-retirement.json, platform-group-boundary.json,
lldap-group-maintenance.json, resolver-cutover.json under the corresponding
docs/evidence/YYYY-MM-DD-netkingdom-security/ directories.
Inventory source callers and retire remaining unsafe delivery paths
id: NK-WP-0049-T06
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T04, NK-WP-0049-T05]
state_hub_task_id: "a5f50891-c5b2-513b-8670-e1915ee52015"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-15. Enumerated all 87 current non-test shell/Python callers in the declared bootstrap/k8s scope plus Make/console/delivery adapters. Repaired streamed encrypted bundle publication and fail-closed bootstrap/lab paths; retired unsafe delivery copiers, root prompts, registry patchers and stale rollback recipes. The attended inventory records source dispositions and their native-proof limits. T02 separately maps these to current live users/owners.
Evidence: caller inventory, attended procedures and the October15 recovery evidence directory. No live production bootstrap or lab-init acceptance is claimed.
Discover off-host coverage and recover the existing PI database
id: NK-WP-0049-T07
status: done
priority: high
assignee: codex
state_hub_task_id: "2d7302a2-319a-5633-bf58-d51ccd25ebf6"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-15–16. Bounded Storage Share/Scaleway inventories identified existing database coverage and the missing full identity bundle. The operator independently matched the backup recipient, then recovered the exact existing PI dump: correct-key decryption, wrong-key refusal, isolated native PostgreSQL restore/readback and cleanup passed (5 tokens, 2 resolvers, 2 realms).
Evidence: October15 recovery offsite-discovery-summary.json,
privacyidea-transfer-r1.json, privacyidea-database-drill-r1.json,
database-drill-review.json. This database-only proof led to T08–T14.
Implement the full identity capture and archive recovery toolchain
id: NK-WP-0049-T08
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T06, NK-WP-0049-T07]
state_hub_task_id: "317ca173-c784-5329-9810-5e3d300604b8"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16. Defined exact LLDAP/Authelia/KeyCape/privacyIDEA assets, Deployment/PVC/reference bindings, original keys and snapshot consistency limits. Implemented native SQLite/PG capture, streamed age sealing, strict data-bearing manifest checks, provider readback, independent retrieval, bounded retention, root runtime and attended archive verifier. All 56 focused checks passed, including actual synthetic encrypted/native PostgreSQL recovery.
Evidence: profile, implementation review, and the live evidence's tested ESO-default/host-binding corrections. Production archive recovery is separately evidenced in T13.
Admit and verify the two scoped backup credential deliveries
id: NK-WP-0049-T09
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T08]
state_hub_task_id: "4a47eb2a-7e42-5ae7-9df1-f5ede746eca1"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16. Platform CCR-2026-0048/0049 are verified. The operator approved folder-only provider-normalized publisher21/retention25 rights, including re-sharing, in addition to the original rollout. Coding-agent denials precede KV publication. Exact 900-second single-policy readers, wrong-SA/namespace/audience rejection, metadata/sibling/old-escrow/token-create denials, ESO equality and reader/session revocation passed. Operator passwords and age private keys are not job credentials.
Evidence: live publisher-setup-verified.json, retention-setup-verified.json,
publisher-native-delivery-verified.json, retention-native-delivery-verified.json;
approval decisions 40bfae40-6108-4e51-8613-073339f5345f and
5edd5203-fae7-461b-8775-5d22b7873971; Platform CCR files.
Apply capture isolation and install the guarded node runtime
id: NK-WP-0049-T10
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T08, NK-WP-0049-T09]
state_hub_task_id: "0519444c-d559-5455-aa27-8c5dc8b832b0"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16. Applied exact UID/resource-version/spec-guarded DNS selector exclusions, preserving ordinary service matches. Capture refuses any remaining helper allow policy. Installed immutable runtime sources bound to the actual hostname, machine identity and cluster UID. Disabled-unit replacement checked previous contents and retained rollback bytes. Health unit validation passed. Activation remained gated until T13.
Evidence: live isolation-applied.json, capture-ready-plan.json,
installed-runtime-packet-r2.json, upgrade-disabled-runtime.py. Actual complete
hardened-job execution is recorded in T14.
Connect recovery to Railiance bootstrap and reuse discovery
id: NK-WP-0049-T11
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T08]
state_hub_task_id: "d69af493-4026-56a8-a526-c267d90dce18"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16. Added the Railiance bootstrap identity-recovery
dispatcher and independent-custody → isolated verification → layer/service-owner
handoff. Updated capability.security.bootstrap-recovery, linked bootstrap
sequencing and composed reuse-surface federation. Keyword discovery for identity
backup, restore, privacyIDEA and disaster recovery was verified. The operator
actually used this handoff in T13. No unattended production importer is claimed.
Evidence: ceremony, owning capability
entry, railiance-bootstrap/docs/identity-recovery.md, bootstrap commit d1dcfde
and reuse-surface federation commit 662782e.
Create and verify the first full off-host identity bundle
id: NK-WP-0049-T12
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T09, NK-WP-0049-T10]
state_hub_task_id: "decb415a-8012-521c-9dbe-d73c6ff0bbfb"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16. Captured original service keys/current data plus the
linked native PI database dump, sealed and published a unique Storage Share
artifact, then downloaded it and verified size/digest before publishing its index.
Helper and plaintext cleanup passed. Artifact:
net-kingdom-identity-20261016T063159Z-5882771aa2ce.tar.age (109738344 bytes).
Evidence: live actual-capture.json, actual-offsite.json; ciphertext SHA256
7117b3fe1e4840c86b301c94c85e6b16709e5626bb0884bd0580bde630e30e30.
No age private key was needed by the capture job.
Independently retrieve and recover the complete actual archive
id: NK-WP-0049-T13
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T11, NK-WP-0049-T12]
state_hub_task_id: "602d4921-cfac-5e5b-9993-4fbf67195c7d"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16. Independently downloaded the exact first generation through attended Backup-account custody, rehashed it locally and revoked the session. The operator used the independently held age key through the bootstrap handoff. Correct/wrong-key cases, all 36 manifest files/hashes, original RSA pairs, SQLite integrity and isolated native PG16.14 restore/readback passed; plaintext and containers were removed. No key or restored secret values reached the agent.
Evidence: live independent-owner-transfer.json, actual-full-archive-recovery.json,
actual-full-recovery-review.json. Existing-user/MFA authentication and old audit
signatures are deliberately separate T16–T20 outcomes.
Activate and prove the complete recurring backup and retention job
id: NK-WP-0049-T14
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T10, NK-WP-0049-T13]
state_hub_task_id: "eaf0708f-b3b7-5531-8172-95edf30c3a19"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16 after T13. Both daily backup/retention and hourly health timers are enabled/active. The actual hardened systemd service passed retention before/after a second capture/upload/download (Result=success, ExecMainStatus=0). Both verified generations are retained, the independently recovered point is pinned, and nothing was deleted. Helpers/plaintext were cleaned; failure markers and reporting outbox are empty. Health check succeeded.
Evidence: live activation-result.json, activation-review.json,
recurring-job-review.json. Cadence: daily 03:45 UTC plus up to 5 minutes jitter,
hourly health, 25-hour freshness bound. Second-provider/host-loss gaps go to T24;
this completed task is not a full-estate recovery claim.
Map current callers, owners and native acceptance gaps
id: NK-WP-0049-T02
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T06]
state_hub_task_id: "479d6970-6516-50f5-9436-bb5b56d58aad"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
The source inventory and known legacy objects exist; a complete current-use ledger is not yet accepted. Next action is read-only reconciliation of the 93 entries in the latest October15 source inventory (the earlier snapshot had 87) against active Make/bootstrap/operator routes and owner evidence.
Done when: each entry is identified as current, retired or owner-deferred,
with its owner, credential route, current consumer(s), native evidence or exact
missing proof, and next responsible task. Explicitly cover the historical
sso/keycape-pi-token and mfa/privacyidea-trigger-admin objects, lab init,
factor diagnostic delivery, LDAP group/provider boundary, resolver cutover and
root-output/isolation boundaries. Secret presence is not credential validity.
Send current native checks to T21 and historical revocation/rotation decisions to
T22. Do not reopen completed source repairs without a new finding.
2026-10-23 first slice (read-only, mechanical): ledger draft. For all 93 inventory entries it records presence, sha256 drift against the October15 inventory, the last commit, and references from Make, bootstrap or console routes and from runbook/doc markdown. Candidate statuses:
- 28 have an active Make/bootstrap route.
- 26 have a documented operator route.
- 11 are retired, refusing entry points.
- 11 are unrouted diagnostics.
- 17 are unrouted and need an owner disposition: privacyIDEA bootstrap/policy helpers, four KeyCape rollout helpers and the four bootstrap-recovery tools. 5 entries have drifted since the inventory (Makefile, sops-custody-unlock, sops-private, keycape-client, identity-backup-profile). These are candidates only, not owner dispositions. Next slices: (2) fill in owner, credential route and consumers for the 17 unrouted and 5 drifted entries, plus the explicitly named historical objects; (3) add native evidence or the exact missing proof and the next task for all entries, and route checks to T21 and T22.
2026-10-23 slices 2 and 3 are complete. T02 is done. Every one of the 93
entries now records a disposition, owner, credential route, consumers, evidence
and next task: 59 current, 12 current diagnostic, 7 current
recovery/internal/repair, 11 retired, 4 owner-deferred greenfield/initial
activation (including authentication-policy-rollout.py, retained because a
recovery rebuild of the issuer needs its initial activation again), and 1 superseded once
NK-WP-0048 admits 1.3 (vergabe-client-rollout.py). The 5 drifted entries are
attributed to their reviewed commits. Historical objects: sso/keycape-pi-token
and mfa/privacyidea-trigger-admin are retired in source (no current reader),
but the objects were still present on 2026-10-15 and revocation is unproven.
They route to T22 and to NK-WP-0022's deletion approval. Lab init, factor
diagnostics, the LDAP group boundary and the resolver cutover appear as their
entry-point rows. Owner acceptance and native checks stay with T21/T22. The
four recovery tools still need a runbook home; T24 G3 covers that.
Prepare the isolated full-service restore and acceptance packet
id: NK-WP-0049-T15
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T08, NK-WP-0049-T13, NK-WP-0049-T27, NK-WP-0049-T28, NK-WP-0049-T29, NK-WP-0049-T30]
state_hub_task_id: "1d1eb903-a4b0-5bc4-a421-0b842d7f68ae"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Prepared draft scope moved to T27. See
docs/identity-service-restore-packet.md: restore order, containment, safe evidence
and per-service positive/negative checks are drafted. Read-only current runtime
image digests were observed for all four services; correspondence to the selected
archive and independent image availability are not yet proved.
Next action: admit a named disposable target/private route, verify and stage matching images independently, obtain private existing-user/MFA test inputs and review version-specific native commands with service owners. Incorporate T02's ledger before submitting current-caller acceptance.
2026-10-16 checkpoint: T28 completed the exact local image save/load/inspect and T29 prepared and natively tested the bounded LLDAP stage. Its actual owner run is T16 and can proceed independently of the remaining multi-service packet. The other service adapters, matching archive/runtime lineage and private existing-user/MFA inputs are still required; no blanket T15 completion is claimed.
Done when: service owners accept the exact targets/procedure, existing-user and MFA test identities/input custody are available without posting secrets, outbound notification/provider writes are disabled, and every required new credential or production effect has its own owner decision. The verifier deletes its plaintext; it is not a production importer. This task prepares authority and inputs for T16–T20, not an automatic production restore.
2026-10-23: the T02 ledger is incorporated into
docs/identity-service-restore-packet.md. Acceptance for current callers uses
its current rows, and the two historical Secrets are excluded from restore
scope. Still owner-held: a named disposable target and route, archive/runtime
image lineage, private existing-user/MFA inputs, and service-owner acceptance.
2026-10-27 founder decision (option A, builder mode): T15 is done. Owner acceptances: key-cape fc9f09a (docs/nk49-isolated-restore-owner-acceptance-2026-10-27.md, issuer-side restore accepted with residuals K1 browser/PKCE clients not exercised, K2 post-archive changes, K3 one-key check tied to current release, K4 receipt outside Git); railiance-platform 5658150 (RPF-WP-0064, OpenBao phase A accepted for builder mode, residuals R1–R8); founder for the NetKingdom-owned LLDAP, Authelia and privacyIDEA lanes on the T16, T17, T19 and T20 owner runs. Residuals that need a joint live run go to T44.
Prove restored LLDAP directory and existing-user authentication
id: NK-WP-0049-T16
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T29]
state_hub_task_id: "b64d4d6a-e851-58d1-9929-f03343147de0"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: NetKingdom directory/User Engine owners. Restore the captured original directory/configuration in the admitted isolated environment.
Done when: user, group and membership identities are preserved; an independently supplied existing-user credential authenticates; a wrong credential is refused; provider writes/outbound effects stay confined; cleanup is verified. Native fixtures from T05 and SQLite integrity from T13 do not satisfy this current-data acceptance. Record only safe counts, identities and outcomes.
Completed 2026-10-16 at 18:37 UTC. The operator privately supplied the independent age key and an existing backup-era account credential to the exact local executor. All 36 archive hashes and the known ciphertext/source/target bindings matched. Native existing-user LDAP bind passed; explicit invalid credentials were rejected. The original seven users, 17 groups, 13 memberships and the available attribute/schema rows were preserved across service startup, authentication and graceful shutdown. The container had only loopback/no external routes; pre-import isolation and container/tmpfs cleanup passed. No production endpoint was contacted or secret exported to the agent.
Evidence: actual-isolated-lldap-recovery.json and
actual-isolated-lldap-review.json in
docs/evidence/2026-10-16-identity-outage-recovery/. This closes the actual
LLDAP stage independently of the remaining T15 packet. It does not prove
Authelia/KeyCape authentication, retained-token MFA or audit continuity. T17,
T18 and T19 retain their remaining adapter/input prerequisites.
Prove restored Authelia storage and OIDC continuity
id: NK-WP-0049-T17
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T15, NK-WP-0049-T16, NK-WP-0049-T41]
state_hub_task_id: "b47f9975-d6d7-5bb8-93ce-886deb1dfa70"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: SSO/Authelia and directory owners. Restore the original storage, encryption/session/signing material and configuration in isolation.
Done when: native storage decryption succeeds, issuer/signing identity and client configuration are preserved, and an isolated authentication flow has positive/negative results using the restored directory. Disable outbound notifications and verify cleanup. Archive integrity/RSA parsing alone are not native Authelia acceptance.
2026-10-24 redraft, after design review with the founder. KeyCape's source
(key-cape/src/internal, config/dev-config.yaml) confirms the human-login chain:
KeyCape delegates first factor to Authelia as upstream OIDC with the keycape
client secret, Authelia binds against LLDAP, and KeyCape adds MFA through
privacyIDEA. The durable Authelia state that matters is in the Secret and config:
the OIDC issuer key, HMAC secret, keycape client verifier, storage encryption key
and LDAP bind password. The SQLite store holds little under one_factor, so
storage decryption is a cheap check here, not the main proof. T17 acceptance is:
(1) the original configuration validates with the original secrets, notifier
switched to a tmpfs file notifier; (2) the storage encryption key opens the
restored store; (3) the issuer JWKS public key equals the archived issuer key;
(4) the restored keycape client verifier accepts KeyCape's archived client
secret and refuses a wrong one, at the token endpoint, with no grant issued;
(5) first-factor login through Authelia against the restored LLDAP succeeds for
an existing user, a wrong password is refused. The full KeyCape→Authelia→LLDAP→
privacyIDEA human-login chain is not part of T17. T18's selected consumer
(SECRETS-WP-0015-T04) is a workload login and does not pass through Authelia;
a human-login consumer acceptance would need its own selection and admission.
Completed 2026-10-24 at 15:24 UTC. The founder ran run-isolated-authelia.sh
privately on the independently retrieved generation (ciphertext 7117b3fe…0e30,
all 36 manifest hashes verified). Original configuration validated and the
original storage encryption key opened the store. The issuer key served by Authelia
equals the archived key (RFC 7638 thumbprint El5Prcg0…ASm8). The archived
keycape client secret passed client authentication at the token endpoint with
no grant issued, and a wrong client secret was refused. An existing user's first
factor succeeded against the restored LLDAP and a wrong password was refused.
Only loopback existed; the notifier wrote nothing; containers and tmpfs staging
were cleaned. No production endpoint was contacted and the agent received no
secret. Evidence: actual-isolated-authelia-recovery.json and
actual-isolated-authelia-review.json in
docs/evidence/2026-10-24-nk49-t17-authelia/. This does not prove the full
KeyCape to Authelia to LLDAP login chain, privacyIDEA MFA (T19) or current
production password validity.
Prove retained privacyIDEA token decryption and existing-token MFA
id: NK-WP-0049-T19
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T15, NK-WP-0049-T16, NK-WP-0049-T31, NK-WP-0049-T42]
state_hub_task_id: "6f8af1a7-2a3f-5fa8-8202-83103ebd55b2"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: MFA/privacyIDEA and directory owners. Use the exact linked dump and original enckey from the independently recovered generation.
Done when: retained token material decrypts inside the isolated process, a selected existing token completes a native MFA check, a wrong key/code is refused, and cleanup is verified. Obtain any token/user input through attended private custody; never emit token plaintext, seeds or credentials. Native database row counts and disposable synthetic-token fixtures do not prove this outcome.
2026-10-16 refinement: native token-material readback is separately tracked in T31 using the prepared T30 executor. T19 retains actual existing-token MFA and wrong-code/wrong-key authentication refusal. Internal decryption or padding success does not authenticate a user. No MFA code is needed for T20/T31; the selected user's private factor input and exact isolated MFA adapter remain T19.
Completed 2026-10-24 at 16:48 UTC. The founder ran run-isolated-privacyidea-mfa.sh
privately on the independently retrieved generation (ciphertext 7117b3fe…0e30, all 36
manifest hashes verified). Restored LLDAP, the database and the original keys ran in one
network-free namespace; the archived LDAP resolver was repointed to the restored
directory in the disposable copy only. The named user was found through the restored
resolver and directory (hashed in the receipt) and had one usable TOTP token. Through
POST /validate/check by user and realm: a wrong encryption key was refused (privacyIDEA
error 907), a wrong code was refused, and the founder's PIN and code were accepted with
the original key and retained token material. Only loopback existed; containers and tmpfs
staging were cleaned. No production endpoint was contacted and the agent received no
secret. Evidence: actual-isolated-privacyidea-mfa-recovery.json and
actual-isolated-privacyidea-mfa-review.json in
docs/evidence/2026-10-24-nk49-t19-privacyidea-mfa/. Not proven: the KeyCape consumer
login through all four services, event handlers or policies that call outside the
namespace, other users' tokens, and current production token validity. An earlier
serial-based attempt stopped at ResolverError and claimed no proof; see T42.
Prove historical and new privacyIDEA audit-signature continuity
id: NK-WP-0049-T20
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T30]
state_hub_task_id: "375fa8f9-b8a5-5048-97a7-ec141aa7c45d"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: MFA/privacyIDEA audit owner. Use the original recovered audit pair and linked database in the admitted isolated target.
Done when: existing pre-backup audit signatures are verified natively, a new isolated audit entry is signed and verified with the preserved identity, a wrong key fails, and cleanup is recorded. Report any historical verification failure for explicit owner disposition; do not regenerate keys to hide it. Matching RSA pairs from T13 are a prerequisite, not audit-history verification.
Completed 2026-10-16 at 19:10 UTC using the actual independently retrieved
bundle and original audit identity on the fixed isolated local engine. All
279,209 stored rows were signed and verified; zero unsigned, invalid or legacy
signatures. A new isolated entry verified, and tampering/unrelated-public-key
checks were refused. Container/plaintext cleanup passed. Receipt and reviewed
source/ciphertext/target bindings: actual-isolated-privacyidea-recovery.json
and actual-isolated-privacyidea-review.json in
docs/evidence/2026-10-16-identity-outage-recovery/.
Stored-row continuity is accepted; event completeness and existing-token MFA
are separate and are not claimed.
Prove restored KeyCape issuer, policy and consumer continuity
id: NK-WP-0049-T18
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T15, NK-WP-0049-T16, NK-WP-0049-T19, NK-WP-0049-T32, NK-WP-0049-T33, NK-WP-0049-T40]
state_hub_task_id: "141dd773-c1fa-56c1-a852-bbe2372e5125"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: KeyCape and the selected current consumer owners. Restore the original signing/configuration, registry, authentication policies and receipts.
Done when: issuer/JWKS signing identity, registry/client configuration and policy/receipt continuity are preserved; selected current consumers pass native positive/negative authentication using the restored dependencies; and isolation and cleanup hold. Confirm the actual dependency graph in T15. Do not route a production consumer to the isolated issuer or mint new client grants implicitly.
2026-10-23 evening, attended by the founder (ceremony steps 3 to 5, inside the T40 window):
step 3 production reissue through railiance-cluster 88b360b (isolated namespace tls-attempt-kc,
own Issuer; live sso/kc-tls resourceVersion 66444692 and fingerprint D5:DB:2B:55… unchanged; cleanup done),
chain 0dd5d582…5add to ISRG Root X1 22b557a2…43d1, key/cert public keys equal. Step 4: fresh
independent Storage Share retrieval of ciphertext 7117b3fe…0e30, then the six-argument launcher with
launcher admission a57c4c64…a6ba (R1 template completed; isolated-keycape.py pin = reviewed T38
86f37add…): OK: isolated KeyCape native checks and cleanup passed. The first launcher run was refused
pre-key because two inputs were mode 0444; fixed to 0400 without changing bytes. Step 5: independent verifier
from a clean export of a20dcfe, --not-after 2026-10-24T05:00:00+00:00: verified, no findings.
Receipt 16d72f7c…1651 reports original JWKS signing key, original config/registry/policy receipts, native
service registration, denied scopes and wrong-secret refusal, original HTTPS issuer/trust, plaintext/container
cleanup, production_contacted: false. Evidence: docs/evidence/2026-10-23-nk49-t18-keycape-attempt/verifier-output.json.
The receipt itself is not in Git: the local and Forgejo secret scanners flag its public source-file digests
(generic-api-key, file names containing "keycape"), and the founder chose not to re-encode or exempt it. The exact
original is retained outside Git on the founder workstation (mode 0400), bound by sha256 16d72f7c…1651 in the
verifier output. This deviates from the ceremony step 5 retention path by founder decision 2026-10-23.
2026-10-24: the OpenBao dependency for this consumer is recovered at configuration level. railiance-platform
RPF-WP-0064-T07 restored the original OpenBao from the 2026-10-14 off-host snapshot into a networkless target,
founder attended (attempt -03, adapter 7084b57), verified independently (receipt sha256:4e048dee…579d,
outside Git): original cluster id, the secrets-engine-openbao JWT role, its policy and KV metadata all match
source. T18 consumer acceptance still needs the live login run: RPF-WP-0064 phase B (internal network joining
the isolated NK49 KeyCape and restored OpenBao) plus the SECRETS-WP-0015-T04 consumer run, each separately
founder-admitted. MFA remains T19.
Still open for T18: selected current consumer acceptance against restored dependencies (the receipt claims
no consumer continuity), and owner acceptance; MFA stays T19.
2026-10-27 founder decision (option A, builder mode): T18 is done with a named residual. Accepted on the verified issuer-side receipt 16d72f7c…1651, key-cape owner acceptance fc9f09a, the restored OpenBao configuration (receipt 4e048dee…579d) and the 2026-10-10 live consumer proof of the same registration. CA-bundle check 2026-10-27 (claude-code, local, --network none): the pinned OpenBao image quay.io/openbao/openbao@sha256:436eaf97…c115 bundle /etc/ssl/certs/ca-certificates.crt (145 certs, sha256 61efbd6d…d1d9) contains ISRG Root X1 (DER sha256 96bcec06…08c6, not after 2035-06-04); its PEM sha256 is 22b557a2…43d1, exactly the anchor recorded for the T18 KeyCape chain. With no CA fields in the keycape-services source config, restored OpenBao would trust the KeyCape /jwks chain; the restored config's CA-field absence remains inferred (railiance-platform R1). Residual, carried to T44: restored KeyCape and restored OpenBao have not been exercised together by a real consumer login, and browser/PKCE clients were not exercised. This is not production consumer validity.
Verify current caller and provider admission at their actual boundaries
id: NK-WP-0049-T21
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T02]
state_hub_task_id: "77aa42be-7a39-5d93-8042-03d78b4094b4"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: each current caller's service/provider and credential owner. Use T02's ledger to select the exact current procedures and required owner lanes.
Done when: each current caller has scoped delivery and native positive/negative acceptance or an explicit accepted retirement/disposition. Include dedicated factor-diagnostic admission (do not borrow KeyCape's reader), deployed reserved LDAP group denial, resolver/cutover input provenance and functional proof, and bootstrap/root-output/isolation callers. Fixtures, an existing tty and historical bootstrap receipts are not current authority. Propose exact write/cutover actions before execution; record deferred actions separately rather than faking a pass.
2026-10-27: builder-mode disposition draft prepared for founder acceptance: T21 caller dispositions. It accepts the T02 ledger rows by category, points follow-up rows to their existing workplans, and assigns the reserved-LDAP-group denial and resolver re-proof to T44. Factor-diagnostic row corrected the same day: source shows the diagnostic takes only an owner-admitted private token and never KeyCape's reader; a founder-run admin scan shows only sso/keycape mounts keycape-factor-read; no admitted diagnostic lane exists, so that row is a deferral, not a T44 item. T21 stays waiting until the founder accepts.
2026-10-27: founder accepted the T21 caller dispositions for the builder-mode estate. T21 is done. Reserved-LDAP-group denial and resolver re-proof move to T44; the attended factor diagnostic stays deferred until an owner-admitted credential lane exists; follow-up rows remain in NK-WP-0042, NK-WP-0048, NK-WP-0051 and T24.
Resolve historical credential and configuration-preserving rotation dispositions
id: NK-WP-0049-T22
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T02, NK-WP-0049-T21]
state_hub_task_id: "3ea6bf00-a87f-58ea-bdce-328c13a03a55"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: Platform/custody and affected consumer owners. Review historical personal-admin/trigger credential copies and unsafe predecessor paths against known current consumers and rollback custody.
Done when: every affected credential has an owner-accepted disposition:
verified revocation/replacement, continued bounded use with acceptance, or an
explicit linked deferral. Signing/client-secret changes require preservation and
native multi-consumer proof if actually approved. CUST-WP-0073-T05's founder
rotation deferral and decision 1591daa1-6e85-4dfd-aadd-5a9fe1ef47fa remain in force;
record their exact applicability rather than automatically rotating or treating
source retirement as provider revocation.
2026-10-27, founder-run with the attended admin kubeconfig (route kubernetes-railiance01-admin), builder mode: T22 is done.
Both historical objects named by T02 still existed (sso/keycape-pi-token, Opaque, 1 key, 216d; mfa/privacyidea-trigger-admin,
Opaque, 2 keys, 216d). A read-only scan of all Deployments, StatefulSets, DaemonSets, CronJobs, Jobs and Pods found no reference to
either name. The founder deleted both; follow-up get returned NotFound for each. Neither is in the identity backup secret_refs.
This is NK-WP-0022's explicit deletion approval for these two objects. Disposition: Kubernetes copies deleted and verified absent;
revocation of the underlying privacyIDEA credentials is not claimed and stays under the founder's rotation deferral
CUST-WP-0073-T05 / decision 1591daa1-6e85-4dfd-aadd-5a9fe1ef47fa. No other historical credential copy is open in the T02 ledger.
Provide retrieval that works when OpenBao and SSO are unavailable
id: NK-WP-0049-T23
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T25]
state_hub_task_id: "1ec537ee-dfee-5576-be36-a81bdba417d1"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Completed 2026-10-16 at 18:02 UTC. The operator used independently held Backup account access in the private prompt. The actual protected 109,738,344-byte ciphertext was downloaded with unchanged ETag/size/SHA256, with no OpenBao/SSO contact or provider writes by the retrieval path. The human-held age key matched the registered recipient; wrong-key refusal, all 36 manifest hashes, SQLite integrity, original key pairs and native isolated PostgreSQL 16.14 restore passed. The database retained five token, two resolver and two realm rows. Disposable container and temporary plaintext cleanup passed. The agent received no secret.
Evidence: actual-offline-transfer.json, actual-offline-recovery.json and
actual-offline-review.json under
docs/evidence/2026-10-16-identity-outage-recovery/. The review rechecked the
local ciphertext digest and verifier source. This proves the independent path
without requiring a deliberate production outage. Service authentication,
retained-token decryption and historical audit verification remain T16–T20.
T26 separately records accepted guide publication.
Record owner disposition for second-provider and external monitoring gaps
id: NK-WP-0049-T24
status: done
priority: medium
assignee: codex
decision_id: "e4c288d9-0b8a-4261-a8bf-0d2a15688615"
depends_on: [NK-WP-0049-T14]
state_hub_task_id: "474f5a78-a643-59c6-bcf9-fc4a908dfcb0"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Next action: record the current single-provider and host-local-health limits, then obtain explicit owner scope decisions for a second encrypted provider copy, external host-loss/freshness detection and recurring recovery-drill cadence.
Done when: each gap has either an accepted bounded residual risk or a linked live intake/workplan with owner and trigger. Existing daily RPO/25-hour health settings remain the approved baseline. Scaleway full-identity publication and an external watchdog are not implemented; do not add their grants/jobs implicitly. This task triages the new insights instead of silently expanding NK49's required implementation to an entire disaster-recovery programme.
2026-10-23: current limits recorded. Gate routed as decision e4c288d9.
- G1, single provider. The full identity bundle has one encrypted off-host copy (Storage Share). Scaleway holds database dumps only.
- G2, host-local health. The hourly health check and the 25-hour freshness bound run on railiance01 itself. If that host is lost, nothing reports staleness.
- G3, no recurring drill. The PI database, LLDAP and archive recoveries were each run once.
Recommendation: accept G1 as a bounded residual risk until 2027-01-31. Open owner intakes for G2 (off-host watchdog) and G3 (a quarterly isolated restore that reuses the T16/T31 tooling). Once the founder answers, record each accepted risk or link each intake, then close this task. No grant, job or watchdog is added here.
2026-10-23: done. The founder resolved decision e4c288d9 with the recommended
split:
- G1: accepted as a bounded residual risk until 2027-01-31. The review is NK-WP-0053-T03.
- G2: linked to the outside-node watchdog that
RAPP-TELEMETRY-WP-0001-T04already owes. rapp-telemetry has been asked to cover identity-backup freshness (the 25-hour bound). - G3: new intake NK-WP-0053 (a quarterly isolated identity restore drill, registered with disaster-control).
Deliver and verify the offline retrieval adapter and recovery tools kit
id: NK-WP-0049-T25
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13]
state_hub_task_id: "1c5ea7a1-edf7-5072-b36b-8be7f827957a"
Accountable worker: codex.
Completed 2026-10-16. retrieve-identity-offline.py uses privately entered
independent Backup-account access or an exact read-capable identity-folder share.
It performs only fixed-provider HEAD/GET, binds the reviewed generation by strong
ETag/length/SHA256, refuses redirects/proxies/unreviewed scope and removes failed
downloads. No OpenBao/SSO, age key or standing agent credential is required.
recovery-kit.py builds a reproducible allowlisted ZIP containing the tools,
public profile, known-good ciphertext receipt and recovery guides, with file
checksums. Its publication path creates only three versioned guide/ZIP/checksum
objects and verifies readback without overwriting existing conflicting objects.
run-offline-recovery.sh provides the owner's two-hidden-prompt handoff.
Evidence: tests/test_identity_offline_recovery.py and the bounded test/build
receipt in docs/evidence/2026-10-16-identity-outage-recovery/. The focused run
passed 65 tests including real disposable age/PostgreSQL fixtures. ZIP-contained
entry points import without sibling repositories. This is source/fixture proof,
not actual independent-provider retrieval (T23) or publication (T26).
2026-10-16 correction: the first owner handoff stopped before its credential
prompt because Python text r+ requires a seekable stream. Reproduced against a
real controlling PTY; replaced both prompts with the shared hidden-input helper,
refusing redirected input and echo fallback. Added real-terminal and both-CLI
regressions plus closed stage/HTTP-code diagnostics (no raw responses). The
focused rerun passed 36 tests. Evidence: terminal-prompt-fix.json in the outage
evidence directory. This source correction does not complete T23/T26.
Publish and verify the disaster recovery guide on Storage Share
id: NK-WP-0049-T26
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T25, NK-WP-0049-T27]
state_hub_task_id: "94d054fe-e5d8-5ddf-8e48-80714123d184"
Accountable worker: codex; operator holds provider access privately.
Requested by the operator on 2026-10-16; decision
fc3ef8db-0a33-41d5-a0ba-d13169c5f884 records the bounded scope. Guide source:
docs/disaster-recovery-storage-share.md. Document scope, independently held
provider/key requirements, exact known-good fallback, copy/download verification,
archive-check commands, service restore order, recurring schedule and remaining
coverage limits. Include the offline tools so failed Forgejo does not prevent
access to the recovery scripts; retain an independent copy and trusted digest.
Completed 2026-10-16 at 18:01 UTC through the private independent-provider owner handoff. All three objects were conditionally created and read back with matching strong ETag, length and content; the recorded digests match a fresh reproducible local build. No existing object or provider permission was changed. The failed first attempt and terminal correction remain documented in T25.
Published location: Storage Share account Backup,
railiance-backups/net-kingdom-identity/:
net-kingdom-recovery-57d1940947aa25ff-START-HERE.mdnet-kingdom-recovery-57d1940947aa25ff.zipnet-kingdom-recovery-57d1940947aa25ff.zip.sha256
Trusted ZIP SHA256:
57d1940947aa25ff83d0f25ddf30090eb40595cccaab64225de882a2fd59ea2f.
Evidence: actual-offline-publication.json and actual-offline-review.json in
docs/evidence/2026-10-16-identity-outage-recovery/. The published guide is the
exact pre-drill revision; this acceptance record records the later successful
drill without implying an unperformed republication. Keep an independent copy
and trusted digest outside the failed service/provider dependency.
Draft the isolated service restore packet and observe candidate images
id: NK-WP-0049-T27
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T08, NK-WP-0049-T13]
state_hub_task_id: "e273e803-bee7-5d90-bc51-ecc08c0c8eff"
Accountable worker: codex.
Completed 2026-10-16. Draft in docs/identity-service-restore-packet.md names the
known recovered input, restore order, original key/data ownership, default-deny
containment, blocked production/provider/notification effects, cleanup and five
native acceptance lanes with positive/negative checks. Read-only metadata from
the pinned primary cluster resolved all four current service image digests,
including the separately observed privacyIDEA main container and LLDAP's mutable
source tag. Evidence: docs/evidence/2026-10-16-identity-outage-recovery/image-observation.json.
This task extracts completed preparation from T15. Named target admission, archive/runtime image-lineage matching and independent image availability, private existing-user/MFA inputs and owner-reviewed native commands remain T15; no service restore, production change or owner acceptance is claimed.
Stage and verify the five exact service images for local offline recovery
id: NK-WP-0049-T28
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T27]
state_hub_task_id: "4829b091-76d2-5b10-bdfc-032800190c0a"
Accountable worker: codex.
Completed 2026-10-16. All five pinned references (PostgreSQL, LLDAP, Authelia,
KeyCape, privacyIDEA) were inspected on the fixed local Linux Docker engine
bnt-lap001, ID 74f93783-6cef-43a8-a3c4-f62586cd3bc1. Missing LLDAP and
privacyIDEA images were pulled only by their observed immutable digests. Saved a
private 347,521,536-byte image archive, loaded it and re-inspected every exact
reference. Evidence and archive SHA256/location:
docs/evidence/2026-10-16-identity-outage-recovery/offline-service-images.json.
The local drill no longer requires the production registry. This is not off-host image escrow or proof of historical mutable-tag/backup lineage; those limits remain in T15. No service custody or age key was supplied to image caching.
Prepare and verify the bounded native LLDAP recovery executor
id: NK-WP-0049-T29
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T27, NK-WP-0049-T28]
state_hub_task_id: "2f8c73b0-1cdd-5b22-99b6-017ccde4454b"
Accountable worker: codex; operator retains actual private recovery inputs.
Completed 2026-10-16. isolated-lldap.py and run-isolated-lldap.sh provide the
exact owner-run stage in docs/identity-service-restore-packet.md: fixed local
engine/images, no remote Docker endpoint, original key/seed/JWT/directory data,
Linux-tmpfs decryption, memory/stdin-only private inputs, network-none/read-only
containers, isolation inspection before import, actual existing-user bind,
explicit invalid-credential denial, stable directory rows and cleanup checks.
Missing original server keys are refused; reset/replacement/notification paths
are disabled. No live Kubernetes/OpenBao/SSO path or provider grant is used.
Evidence: tests/test_isolated_lldap_recovery.py exercises the actual pinned
image, disposable retained-account directory and a full synthetic encrypted
bundle through the same native executor. The private real-bundle run and its
acceptance remain T16; fixture success is not actual user/MFA/audit recovery.
See isolated-lldap-preparation.json in the October16 outage evidence directory
for exact test/source/target provenance and limitations.
Prepare the bounded native privacyIDEA token-material and audit executor
id: NK-WP-0049-T30
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T28]
state_hub_task_id: "6e4a43db-9be2-5662-bdbf-1595fce03052"
Accountable worker: codex; operator retains private recovery inputs.
Completed 2026-10-16. isolated-privacyidea.py and its owner launcher use the
fixed local Docker target and exact cached PostgreSQL/privacyIDEA3.12.2 images.
The linked dump, original enckey/audit pair and required secret fields are
restored only into a loopback-only, nonroot, read-only, capability-free,
no-host-mount/port, tmpfs-backed environment with inspected pre-import isolation.
Decrypted host staging is tmpfs; normal cleanup removes all private data and
owned containers, with a bounded holding lifetime if the parent is interrupted.
The native provider decrypts token-key material internally, checks every stored audit row, adds one isolated signed entry and checks wrong-public-key/tampering negatives. Original policy for legacy signature verification is retained only from literal archived configuration; archived Python is never executed. Invalid or unsigned history remains reported, not repaired or sampled away. Native material readback is not existing-token MFA or proof of event completeness.
Evidence: tests/test_isolated_privacyidea_recovery.py and
isolated-privacyidea-preparation.json in the October16 outage evidence folder.
Synthetic pinned-image tests exercise valid/tampered/unsigned history, malformed
keys, encrypted archive to native restore, isolation and cleanup. Real original
material/audit acceptance remains T31/T20; actual MFA remains T19.
Verify retained privacyIDEA token material inside the isolated provider
id: NK-WP-0049-T31
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T30]
state_hub_task_id: "26383841-8076-5c53-bbd1-9db64e32544a"
Accountable worker: codex; operator supplies only the independently held age key in the hidden helper. This task extracts actual material-readback scope from T19, preserving T19's existing-token MFA acceptance gate and historical identity.
Completed 2026-10-16 at 19:10 UTC in the same actual run as T20. All five
retained token materials were decrypted internally with the original enckey;
an unrelated key could not reproduce any of the five. All 36 manifest hashes,
exact executor/ciphertext/target bindings, isolation and cleanup passed. Safe
receipts are the actual-isolated-privacyidea-{recovery,review}.json files
referenced under T20. No retained-factor authentication is claimed.
Done when: exact ciphertext/source/target/manifest bindings pass; the native
provider reads every nonempty encrypted token-key field using the original
enckey without exporting material; an unrelated key cannot reproduce that
material; aggregate counts and container/plaintext cleanup are recorded.
Only bounded internal readback is accepted here. Padding/readback success does not prove the recovered secret authenticates a retained factor; actual positive MFA and wrong-key/wrong-code authentication refusal remain T19. No token seed, plaintext, serial or user record belongs in the receipt, Git, State Hub or chat.
Deliver isolated KeyCape restore source and synthetic lifecycle proof
id: NK-WP-0049-T32
status: done
priority: high
assignee: codex
state_hub_task_id: "cd78dbb7-a8f2-5754-8788-6eb1b7d97741"
Completed 2026-10-16. This extracts bounded source/fixture delivery from T18; T18 retains actual original archive, issuer and selected consumer acceptance. The adapter reuses the existing transfer/archive/custody contracts, binds the fixed local daemon and cached images, restores private state only to temporary memory, verifies original issuer/TLS/signing/configuration/policy bytes and runs the original native service-client checker with wrong-secret/excess-scope denial. Durable pre-import obligations and exact parent pidfd/session quiescence precede loss/deadline cleanup. Daemon response uncertainty remains uncertainty after resource absence; it never authorizes recovery success or replay.
Frozen R6 fixes a demonstrated image-declared anonymous-volume incompatibility using bounded helper-only tmpfs, preserving anonymous disk-volume refusal. Safe phase markers carry no private diagnostics. Independently passed 72 focused checks, then actual pinned-image synthetic positive, hard-parent-loss, deadline and nonzero-after-accept cases. Independent fixed-daemon inventories and host mount-namespace checks prove all exact resources and plaintext absent. Reaper outcomes are retained; initial sandbox receipt lookup failure is preserved and superseded by device-bound host verification. R1–R5 failures remain retained.
Evidence: Custodian docs/changes/netkingdom-target-2026-10-16/ identity-restore-adapter-next/revisions/r6/, actual-fixture-r6-all.json and coordinator-r6-all-review.json. Exact source/dependency hashes and candidate manifest bind the proof. This uses generated test keys only; it proves neither actual owner-held recovery, human MFA, downstream reconnect nor native authority.
Publication preparation R7 preserves every R6 recovery adapter byte and digest. The normal scanner flagged eight public source-file SHA-256 values in the R6 manifest. Explicit sha256-qualified checksums resolve those false positives; the fixture reader strictly validates their type/shape before checking the same bytes. R7 passes 73 focused checks including malformed/untyped digest refusal. The frozen R6 actual four-case proof remains the runtime evidence; no repeated native outcome is claimed for publication encoding. Original scanner refusal is retained, and scanner policy/exemptions are unchanged.
Prepare the exact owner-held KeyCape recovery attempt
id: NK-WP-0049-T33
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T32, NK-WP-0049-T34, NK-WP-0049-T35, NK-WP-0049-T36, NK-WP-0049-T39]
state_hub_task_id: "56c8d469-7a10-5d50-a30e-95cbf3cd4756"
Accountable worker: NetKingdom codex with KeyCape and selected consumer owners. This umbrella retains final attempt readiness. Completed custody/preflight source preparation is extracted into T34; T35 resolves original TLS/trust recovery and T36 prepares the selected original registration and private admission. This split records distinct outcomes without counting source preparation as recovery.
After those deliverables, assemble the exact existing six-argument attended command and admission digest, bind the integrated source/dependency revision and fixed local target, and record execution deadline, safe receipt location, abort, rollback and independent receipt verification through the existing owner process. Keep private manifest derivation inside custody and original TLS/client/key inputs in the owner's own terminal; the current null fields must refuse execution. Existing session authorization is retained within scope; this record does not supply missing owner assent or approve any actual recovery attempt.
Done when: reviewed executable command and complete metadata-only/private admission packet are ready for the existing attended custody path; prerequisites and independent receipt verification are explicit. T18 still owns actual execution, original consumer continuity and acceptance. T19 retains retained-factor MFA. This task neither authorizes a production consumer redirect nor creates a new client grant.
2026-10-23: packet completed in source. docs/bootstrap-recovery-ceremony.md
step 3 now carries the decided ACME reissue disposition, with abort conditions
and the required Let's Encrypt staging rehearsal. A new step 5 fixes the
deadline (the founder-signed admission window, at most 24 h), the retained
receipt location, and an independent verifier,
tools/bootstrap-recovery/verify-keycape-attempt-receipt.py, with 10 synthetic
tests. The verifier imports no session code. It recomputes source hashes from a
clean checkout, binds the ciphertext to the transfer receipt, and requires every
native check, cleanup obligation and absence of uncertainty. It refuses
consumer/MFA over-claims and secret-shaped content. Two external prerequisites
remain: the anchor install (SECRETS-WP-0015-T04) and the staging rehearsal
(railiance-cluster).
2026-10-23: the Let's Encrypt staging rehearsal was run attended by the founder and
was green. The Certificate was Ready on the first order. The issuer was (STAGING) Ersatz Emmer YR2, the SAN was exactly kc.coulomb.social, and the chain verified OK. The live
fingerprint D5:DB:2B:55… and the sso/kc-tls resourceVersion 66444692 were unchanged,
and cleanup was done. The receipt is in railiance-cluster aad0e70. Only the anchor install
(SECRETS-WP-0015-T04) remains before the attended attempt.
2026-10-23: the attempt-host anchor was installed by the founder on the workstation, which is the attempt host.
/etc/secrets-engine/admission/allowed_signers is root:root 0644 under a root:root 0755
directory. It holds one entry: principal bernd, namespaces=secrets-engine-recovery-attempt,
ED25519 SHA256:NekDABfw8K8IBYznjREg7jPpcK/BzCgO1pH1ebT/FXM (approver key), file sha256
1964e942…c489. A throwaway self-test signature in that namespace resolved to bernd
and verified Good, and was then deleted. A placeholder line left at 07:12 was replaced. Packet
prerequisites are complete, so T33 is done. Next: the founder signs the attempt admission (T40).
Deliver attended custody, metadata preflight and private manifest preparation source
id: NK-WP-0049-T34
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T32]
state_hub_task_id: "821b3a56-6f36-5812-abc9-5a00e37cb2e7"
Accountable worker: NetKingdom codex; independent Custodian source review. Completed 2026-10-17 as source preparation. Existing attended custody entry points now have a reviewed candidate sealed anonymous descriptor mode: hidden prompt, actual public-recipient verification, strict owned/private/full-seal descriptor admission, non-inheritable returned duplicate and explicit descriptor passing. The existing file mode stays compatible, with its original hard-loss limitation; no improved file-mode cleanup is claimed. Exact parent-loss tests prove descriptor lifetime without signalling inherited user shell groups. An admitted child retains its descriptor until it exits; parent loss is not child revocation.
The candidate checks bounded, duplicate-free public JSON, exact admission digest, transfer/archive and selected service bindings, typed hashes for all 17 invoked local source/config dependencies and required Python imports before requesting a key. TLS and ciphertext preparation uses file metadata only. Legacy explicit manifest digests remain supported; versioned ciphertext-derived binding computes the canonical digest privately only after exact reviewed ciphertext, authenticated age decryption and full existing archive validation. The derived private digest never enters safe receipts/checkpoints and grants no new consumer authority.
The coordinator independently passed 111 focused checks. The existing custody regression suite passed 94 checks; 61 real-SOPS tests skipped because that trusted runtime is unavailable, so that compatibility coverage remains unverified. Tests use generated keys/archive material only, including actual age cryptography, synthetic hidden-prompt and exact parent-loss processes. Manifest-builder tests mock Docker/issuer behavior and confer no new native proof. Frozen R6/R7 proof, intermediate test failures and scanner history remain retained.
Bounded public image readback separately establishes the cached original image's
13670142-byte /keycape executable as
sha256:cd89121393e1465aa76009763602a5b8c75f9dddb5679aea6242623f135b51b4.
This is executable identity metadata, not recovery or custody acceptance.
Evidence: Custodian docs/changes/netkingdom-target-2026-10-16/recovery-attempt-r1/
(candidate.patch, review.json, source closure, attempt/admission metadata and
public-verifier-image-readback.json). Canonical integration/publication and
projection receipts must be recorded separately when performed; this completed
source-preparation record does not invent them. T33 remains open for complete
attempt readiness; actual recovery/consumer acceptance remains T18 and MFA T19.
Establish original KeyCape TLS and trust recovery ownership for outage use
id: NK-WP-0049-T35
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T34]
state_hub_task_id: "1bfd1703-589f-5511-bad5-812d860e4a71"
Accountable worker: NetKingdom codex, coordinating with the source owner of Ingress/cert-manager/Traefik and the original TLS custody/provider boundary. Next action: identify and record that actual owner's existing recovery path, then obtain its metadata/disposition through the ordinary owner process. A missing exact credential-routing catalog match is not evidence that no owner exists.
Current source declares kc.coulomb.social, sso/kc-tls, cert-manager
ClusterIssuer/letsencrypt-prod and Traefik TLS termination before KeyCape 8080.
The identity backup profile excludes kc-tls; the verified archive therefore
establishes no independent recovery of that TLS identity/trust. Determine whether
the exact original certificate/key/trust is independently recoverable during an
issuer/cluster outage, or whether a documented reissue path is acceptable for the
selected continuity claim. Do not read or place the TLS key in work records, use
a fresh self-signed trust substitute, mutate production or claim owner assent.
Done when: named owner/provider, independent outage prerequisites, original public identity/certificate/trust hashes or accepted reissue disposition, private custody entry point and verification/abort limits are explicit and reviewed. Record any unavailable recovery capability as a live owner work record and bind its dependency/unblock condition; a prose-only gap or untested archive is not completion. This delivers preparation/disposition, not actual TLS recovery.
2026-10-17 owner handoff progress: the four reviewed Railiance Cluster source
additions are present, including RCLUSTER-WP-0018 and public-only TLS metadata
preparation. They are not published. The normal publication path stopped at the
existing historical identifier guard (ensure_missing_work_record_identifiers,
execute=False): 15 bare task-label findings and five collisions. A separately
retained read-only allocator preview records those findings; the original failed
publication stderr was not retained and is not reconstructed. No Cluster Hub
workplan/task existence or projection, actual certificate/key custody, reissue
assent or native TLS acceptance is claimed. The source record and next owner
publication action remain live; do not bypass the historical identity guard.
Evidence: Custodian October17 cluster-integration.json, coordinator-checkpoint.json
and October16 cluster-historical-publication-r1/actual-source-allocator-preview.json.
2026-10-21: the publication blocker above is superseded. RCLUSTER-WP-0018 is
published (c562d71) and active. The owner is railiance-cluster (cert-manager,
Traefik, backup posture). Its live owner work records are T02 (custody metadata,
todo), T03/T04 (extraction or reissue, owner-attended verify, wait) and T05
(future archive coverage, todo). warden route find has no TLS lane. Source:
letsencrypt-prod with ACME HTTP-01 via Traefik, auto-renewing. Served public
chain today: leaf valid 2026-09-25..12-24, cert sha256 f14c928a...d15a, SPKI
sha256:236fa4dc...6b6d, ISRG Root X1 trust 22b557a2...43d1. That is current, not
proven original. The only owner-path disposition today is reissue. Original-key
recovery is an unavailable capability, owned under RCLUSTER-WP-0018-T02, and
unblocks when the owner records independent custody of the kc-tls key.
Owner message dae2e1bb requests T02 metadata. Founder disposition gate is T39.
T35 stays progress.
2026-10-23: done. The founder resolved decision 9f9d0d88 on 2026-10-21 with option A (relayed by secrets-engine, message daa264e9). During recovery, kc.coulomb.social's TLS identity is the hostname chained to ISRG Root X1, reissued through letsencrypt-prod ACME HTTP-01. No self-signed substitute is allowed. Owner: railiance-cluster. Verify: the reissued leaf has SAN kc.coulomb.social and chains to ISRG Root X1 (trust sha256 22b557a2...43d1). The original key is not required. Abort if HTTP-01 cannot complete or the chain does not match. Rehearse against LE staging first to protect the 5/week duplicate limit; T33 carries that rehearsal as a prerequisite. RCLUSTER-WP-0018-T05 stays open for future archive coverage. This approves no production mutation and no recovery attempt.
Prepare selected original service registration and private admission bindings
id: NK-WP-0049-T36
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T34]
state_hub_task_id: "8b72334b-fc27-5707-a189-bad345eaf3bc"
Accountable worker: NetKingdom codex with KeyCape and the selected existing service consumer's owner. Next action: identify that owner and the exact original registration's non-secret selector metadata using existing source/owner evidence; preserve independent private custody and never retrieve a client secret.
Bind reviewed ciphertext 7117b3fe1e4840c86b301c94c85e6b16709e5626bb0884bd0580bde630e30e30,
its independently verified transfer, source/image/executable closure and an
explicit versioned manifest-binding mode. For the original service registration,
record client identifier, secret environment name, audience, granted scope,
subject, tenant, required roles and denied scope without values or new grants.
Describe the native service-client dependency graph and distinguish unexercised
LLDAP/Authelia/privacyIDEA/downstream flows. Keep private manifest material inside
the existing custody process, never in Git, safe receipts, State Hub or chat.
Done when: the selected existing service owner and exact non-secret registration bindings are independently established, the private admission builder validates positive/negative source/archive/selector cases, and its metadata is ready to combine with T35's original TLS/trust disposition under T33. This task may prepare registration metadata while T35 proceeds independently; it does not finalize the whole admission, perform actual recovery, redirect a consumer or confer assent.
2026-10-17 owner handoff progress: Secrets Engine source workplan
SECRETS-WP-0015 and bounded public selector/preflight source were published as
c59bbf568c0be8a72ac593508f48c9b1f61ec4c1; the central primary/railiance01
reconciliation receipt reports the same expected/derived commit, four owner task
bindings and two T04 dependency edges, with no unresolved edges. T01/T02 source
preparation is done, T03 exact outage-compatible consumer proof/custody planning
is todo, and T04 actual admitted consumer result waits on T03 and NK-WP-0049-T33.
This publishes an owner handoff, not exact archived registration validation,
current native assent, an OpenBao read, a new grant or consumer continuity.
T36 therefore remains progress; T18/T19 and final native gates remain open.
Evidence: Custodian October17 secrets-engine-projection.json and October16
recovery-owner-handoffs-r1 source review; independent ID/UUID/status/remote
readback is recorded separately when performed.
2026-10-17 source checkpoint refinement: the completed exact-one original selector guard and its bounded refusal/unique-selector proof are extracted into T38. T36 retains exact archive-to-selector binding, current actual service-owner recovery assent and outage-compatible private admission/consumer preparation. The current eight-field source-selector correspondence is evidenced separately; it does not complete those remaining obligations or any T18/T19 native gate. T33 continues to require the complete reviewed TLS/custody/admission packet. This extraction records one source outcome rather than counting it again as original registration validation or consumer continuity.
2026-10-21: selector bound to secrets-engine 0f44fbe. Selector
sha256:02077af3...7012, service_auth.py sha256:c0ade429...86c0. Offline preflight
passes. A wrong source hash and an unsigned admission each refuse with rc=1. The
builder suite passes 27 (synthetic positive and negative
source/archive/selector cases). The founder-signed attempt admission (decision
d1ab097d, SECRETS-WP-0015-T04) is the surviving offline authorization, and T33
now requires --admission to pass. Owner message 0fec1113 asks secrets-engine to
confirm the pins, attempt-host anchor coverage (absent on the workstation) and
T04 consumption. Exact archive-to-selector equality is only checkable inside
custody, at attempt time. Evidence:
docs/evidence/2026-10-21-nk49-t33-readiness/readiness-observation.json.
T36 stays progress until the owner confirms.
2026-10-23: done. secrets-engine confirmed on 2026-10-21 (message 8d1ab5b7)
that the pins match HEAD 0f44fbe with no relevant drift. Installing the
attempt-host anchor is now owned work under SECRETS-WP-0015-T04 (founder- and
root-owned). SECRETS-WP-0015-T04 consumes the T33 packet unchanged. With the
registration bindings, the 27 builder cases and T35's disposition in place, the
metadata is ready for T33. No value, grant or attempt is implied.
Founder disposition of original KeyCape TLS recovery
id: NK-WP-0049-T39
status: done
priority: high
assignee: founder
decision_id: "9f9d0d88-837a-433c-8a11-d30b633b0073"
depends_on: [NK-WP-0049-T35]
state_hub_task_id: "90f473db-bda6-5fe2-a2e1-7ddfaca815b7"
Founder gate for T35. Approves no mutation and no attempt.
2026-10-23: resolved 2026-10-21 = A (ACME letsencrypt-prod reissue, LE staging rehearsal first). Recorded under T35.
Founder signs the exact KeyCape attempt admission
id: NK-WP-0049-T40
status: done
priority: high
assignee: founder
needs_human: true
decision_id: "d1ab097d-cc79-4612-9c17-bb9b364081ac"
depends_on: [NK-WP-0049-T33]
state_hub_task_id: "90865f76-0573-5840-b1b5-937f0820ea82"
The signed document is T33's required --admission input and T18's surviving
offline authorization. The signature does not run the attempt.
2026-10-23 handoff: the session is scheduled for 19:00 Berlin (17:00Z) today. The unsigned admission is prepared
at ~/nk49-attempt-20261023/attempt.json (outside Git, dir 0700, file 0444, sha256
f8297954…c157). It binds case secrets15-nk49-readiness, issuer https://kc.coulomb.social,
selector sha256:02077af3…7012, service_auth sha256:c0ade429…86c0, and window
2026-10-23T17:00:00Z to 2026-10-24T05:00:00Z (12 h, ending 07:00 Berlin). Pins were rechecked against secrets-engine
HEAD a14fbc0, with no change to the selector, service_auth.py, the checker or founder_admission.py
since 0f44fbe. A dry check passed every field and window rule, and refused only the missing signature.
Evening order:
(1) confirm that sha256 is unchanged;
(2) founder signs: ssh-keygen -Y sign -f ~/.ssh/gexec_approver_ed25519 -n secrets-engine-recovery-attempt ~/nk49-attempt-20261023/attempt.json;
(3) ceremony step 2, selector preflight with --admission, must report founder_admitted_attempt_not_native_acceptance;
(4) ceremony steps 3 to 5 (production ACME reissue under RCLUSTER-WP-0018-T04, launcher, independent receipt verifier with --not-after 2026-10-24T05:00:00+00:00) under T18.
If the window lapses, write a new file and sign again. Never edit the signed bytes.
2026-10-23 19:04 Berlin: signed by the founder. attempt.json is unchanged (sha256 f8297954…c157);
attempt.json.sig lies beside it, outside Git. Selector preflight from secrets-engine a14fbc0 with
--admission exited 0: founder_admitted_attempt_not_native_acceptance, principal bernd, key
SHA256:NekDABfw8K8IBYznjREg7jPpcK/BzCgO1pH1ebT/FXM, namespace secrets-engine-recovery-attempt, the
eight consumer fields equal to the selector, credential_source_exercised: false, network_contacted: false.
This is founder authority for this one attempt, not native acceptance. T18 continues with ceremony steps 3 to 5
before 2026-10-24T05:00Z. Launcher private-admission note: the R1 template pin for
tools/bootstrap-recovery/isolated-keycape.py is superseded by the reviewed T38 publication
sha256:86f37add…b718; the other 16 pins match HEAD.
Verify actual SOPS compatibility and sealed-descriptor read/write custody
id: NK-WP-0049-T37
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T34]
state_hub_task_id: "3403e266-d63b-5ce1-b891-3bfeac93d28c"
Accountable worker: NetKingdom codex; independent Custodian fixture review. Completed 2026-10-17 as generated-fixture compatibility proof. The coordinator ran the actual reviewed SOPS 3.13.3 binary in a network/host-custody-isolated namespace: all 65 tests passed in 14.85 seconds, including the 61 real-SOPS cases previously skipped in T34 and four new actual sealed-FD cases. The latter cover correct-key descriptor-only decryption, wrong-recipient refusal and descriptor-only edit/rotation through the real Make entry points. Generated custody key files were removed before these FD-only invocations; explicit descriptor passing, private output modes, declared encryption-policy preservation, suppressed synthetic plaintext and operation cleanup were checked.
This is a dated successor to T34's historical 94-pass/61-skip record, which stays
unchanged. The prior skip is not rewritten as an earlier pass. Binary digest
sha256:e5bec3346a873ae91d871550f3e698c1aad962aff462a080e40f25fde17fef6b
matched the official release asset/checksum; Sigstore signature verification was
not performed. SOPS was not installed systemwide or admitted for production
runtime. Host custody was not mounted, network routes were absent, diagnostics
were suppressed and namespace teardown completed. All material was generated;
no original owner key/archive, private manifest, production credential, native
service continuity or owner assent was exercised.
Evidence: Custodian
docs/changes/netkingdom-target-2026-10-17/sops-real-regressions.json,
sops-source-tool.json and sops-fd-r2/ (exact test patch/manifest). The focused
custody/source checks and frozen R6/R7 native fixture evidence remain separate.
T33 attempt readiness, T18 actual recovery/consumer acceptance, T19 retained MFA,
T35 TLS/trust disposition and T36 original registration/private admission remain
open under their existing owner boundaries.
Deliver exact-one original selector guard and bounded source refusal proof
id: NK-WP-0049-T38
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T34]
state_hub_task_id: "76dde6b9-5ee8-50d3-bf15-461d6d5f29b8"
Completed 2026-10-17 as source preparation, independently reviewed by the coordinating Custodian agent. The adapter now requires exactly one selected registration in the already-restored archive configuration before further runtime environment reads, signer-key parsing or native checker invocation. Absent, empty, identical-duplicate and conflicting-duplicate selectors refuse before those later inputs; the existing unique-selector mocked native path still passes. Current KeyCape Go configuration also rejects duplicate IDs; this makes the adapter's own boundary explicit and establishes no native duplicate exploit. The guard cannot run before archive decryption or the original key prompt.
The 39 adapter checks passed, including four added early-refusal regressions. Running those four cases against the retained original adapter failed the new refusal contract as expected. The broader 77-check source run retained 76 passes and one stale fixture-proposal source-hash refusal. Only the two affected hashes and scope of that unexecuted/unapproved successor proposal were then refreshed; all four affected fixture-plan checks passed. The original manifest preimage and failure receipt remain retained, and frozen actual R6 runtime receipts were not changed or claimed as proof of this successor. No broader native rerun occurred.
Evidence: Custodian
docs/changes/netkingdom-target-2026-10-17/native-identity-r1/:
owner-source.patch, verification.json, manifest.json, retained preimages,
original-behavior-regression.txt and focused-regressions.stderr.txt.
The later task extraction and exact workplan successor bytes are in
refinement-r2/; the original source-proof packet remains immutable.
Canonical owner publication, allocator-assigned Hub UUID and projection must be
recorded separately through the normal owner process; none is claimed here.
This completes only the source guard/refusal deliverable extracted from T36. T35 original TLS public provenance/private custody or accepted reissue, T36 exact archive binding/current owner assent/consumer custody preparation, T33 complete attempt readiness, T18 actual recovery/consumer acceptance and T19 retained-factor MFA remain open. No actual archive, private key, Secret object, token exchange, OpenBao login, rotation, production action or owner assent was exercised.
Prepare and fixture-test the isolated Authelia restore stage
id: NK-WP-0049-T41
status: done
priority: high
assignee: claude-code
depends_on: [NK-WP-0049-T16, NK-WP-0049-T29]
state_hub_task_id: "12b634c4-a21c-5503-a361-debe07f1db1d"
Accountable worker: claude-code; the founder retains the actual private recovery inputs and runs the T17 stage.
Add isolated-authelia.py and run-isolated-authelia.sh to
tools/bootstrap-recovery/, the Authelia counterpart of T29. Design, from the
2026-10-24 review:
- Topology: the anchor-namespace pattern already used by the KeyCape session.
Restored LLDAP is the
--network noneanchor; Authelia and the probe client joincontainer:<anchor>and talk over loopback only. No new network. - Reuse without edits: import helpers from
isolated-lldap.pyand the other existing modules. Do not modifyisolated-lldap.pyor the KeyCape files; they are in the pinned source-hash list of the T38/T40 attempt. - Inputs: the verified transfer receipt, the age key via
sops-custody-unlock.sh, an existing-user password by private prompt. Original Authelia secrets and thekeycapeclient secret come from the archive, never from argv, environment listings or files outside tmpfs. - Confinement: LDAP URL rewritten to loopback, SMTP notifier replaced by a
tmpfs file notifier,
authelia-smtpnot imported. Containment inspection before private import; container and tmpfs cleanup verified on every exit. - Checks: the five T17 acceptance items. Receipt records booleans, counts, the issuer key thumbprint and image IDs only.
Done when: unit tests cover config assembly (original secrets kept, notifier
and LDAP rewritten, path escape refused, missing secret refused), and an opt-in
synthetic-fixture test (NK49_RUN_ISOLATED_AUTHELIA_TEST=1) passes on the pinned
local images with disposable credentials only. The packet in
docs/identity-service-restore-packet.md names the stage and its exact command.
This prepares T17; it is not T17 acceptance and touches no production service.
Completed 2026-10-24. isolated-authelia.py, run-isolated-authelia.sh and
tests/test_isolated_authelia_recovery.py are in place. Unit tests and the
opt-in native fixture tests pass on the pinned local images (9 passed): positive
path, wrong password at existing_user_first_factor, wrong storage key at
storage_decryption, and an encrypted-bundle run through main(). Native runs
surfaced two confinement rewrites beyond the planned ones: the NTP startup
check (outbound UDP) and the container healthcheck file (Authelia writes
/app/.healthcheck.env before provider checks, which a read-only root refuses).
Both are recorded in the packet. isolated-lldap.py and the KeyCape attempt
sources are unedited; isolated-keycape.py still hashes to the T38 pin
86f37add. The packet section "Prepared owner step: isolated Authelia
recovery (T17)" gives the exact command.
Prepare and fixture-test the isolated existing-token MFA stage
id: NK-WP-0049-T42
status: done
priority: high
assignee: claude-code
depends_on: [NK-WP-0049-T31, NK-WP-0049-T41]
state_hub_task_id: "2fa3bd7c-12a9-546a-8098-a1999346da8a"
Accountable worker: claude-code; the founder holds the token, its PIN and the age key, and runs the T19 stage.
Completed 2026-10-24, then redesigned the same day after the founder's first real run.
isolated-privacyidea-mfa.py, run-isolated-privacyidea-mfa.sh and
tests/test_isolated_privacyidea_mfa.py add the T19 stage. Restored LLDAP, the
database and a privacyIDEA worker share one network-free namespace; the archived LDAP
resolver address is repointed to the restored directory in the disposable copy only;
and three native POST /validate/check calls by user and realm run in separate
processes (wrong key, wrong code, the owner's code), the call KeyCape makes. Reuses
isolated-privacyidea.py and isolated-lldap.py unedited. Fifteen opt-in native fixture
tests pass on the pinned images: HOTP and TOTP-with-PIN tokens owned by an LDAP user,
a wrong code alone, an unknown user, a malformed original key, the rewrite refusing an
unknown resolver address, and an encrypted-bundle run through main().
Two defects were found and fixed, both before any acceptance claim. (1) A first fixture
run was vacuous: privacyIDEA applies PRIVACYIDEA_CONFIGFILE after the config_file
argument, so the wrong-key run used the original key, accepted the code and spent the
HOTP counter. The probe now sets the variable and asserts the intended PI_ENCFILE.
(2) The launcher called m.preflight() on a module that did not define it, and its
catch-all printed the generic preflight message; tests now run the launcher's own
snippet. Then the founder's first real run (receipt retained in /tmp, not in Git)
stopped at acceptance with ResolverError on all three checks: the first design checked
by token serial, but real tokens belong to an LDAP user whose resolver points at the
in-cluster lldap.sso.svc.cluster.local, absent in isolation. The stage was rebuilt
around the directory and a by-user check; the gate had correctly refused to claim proof.
No key, PIN or code was recorded, and nothing was consumed.
This prepares T19 and also covers the user-to-token resolver, its encrypted bind
password and the LLDAP user lookup (receipt field user_to_token_resolver_proven). It
is not T19 acceptance and touches no production service. Event handlers or policies that
call outside the namespace are not exercised.
Prepare the phase B plan: isolated KeyCape and restored OpenBao on one internal network
id: NK-WP-0049-T43
status: cancel
priority: high
assignee: claude-code
needs_human: true
decision_id: "e4db6c9f-d464-4185-b5a1-ea71e21d1b42"
depends_on: [NK-WP-0049-T18]
state_hub_task_id: "485468fd-d56e-54d1-9bc7-97220c0c4a38"
Accountable worker: claude-code. Every signature, window and secret input stays with the founder and the named owners.
Delivered 2026-10-24: docs/nk49-phase-b-plan.md (topology, ownership, the changes the
pinned T18 machinery forces, ordering, claims and open decisions) and
docs/nk49-phase-b-admission.example.json (unsigned template). Verified from source:
the worker is launched --network none with a loopback --add-host; inspect_session
refuses any other network mode; the loopback-only probes would fail by design on an
internal network; the T38/T40 source closure is hash-pinned, so phase B is a new reviewed
module and must not edit those files; the T40 admission window ended 2026-10-24T05:00Z, so
a new founder signature is required. The consumer's client secret is part of the backup's
KeyCape secrets, so its custody into the consumer runner is an open owner design.
2026-10-27 owner replies (State Hub, from the owners' own workplans; none authorizes any run):
railiance-cluster (8fad4ef, reply 65ab47ff): one proven production issuance on 2026-10-23T16:23:09Z, estimate 1 of 5 used; unproven because cert-manager objects are unreadable to the agent and crt.sh is stale; safe date 2026-10-30T16:23Z; admin-side check suggested.
railiance-platform (2bbf1ff, task RPF-WP-0064-T09): can own the single --internal network and keep restored OpenBao up as bao-restored; needs a new adapter pin, internal listener without generate-root, network check, receipt schema and verifier; objects to longer unsealed exposure than 45 minutes unless the founder accepts it in the window.
secrets-engine (65a3dbe, reply 5aeaadc9): new reviewed runner taking the client secret from an inherited pipe fd, founder-piped from the backup; NetKingdom must name the field and decrypt command; /jwks trust of the ISRG chain by restored OpenBao is unproven.
2026-10-27 founder decision: accept the secrets-engine inherited-pipe custody design (65a3dbe) with optimizations 1, 3, 4 and 5: the wrong-secret negative test uses a generated random token, so only the one real secret passes the founder terminal; the decrypt step runs through a fixed non-echoing, unlogged wrapper that refuses to run under script or tmux logging; railiance-platform runs a value-free OpenBao-side /jwks trust probe on the phase B network before the ceremony; and the full path is rehearsed with a synthetic client on a throwaway network. Not adopted now: namespace/ptrace hardening (2) and an agent-free source (7). This accepts a design only and authorizes no run.
2026-10-27: the founder tried the admin-side cert check as ops-mason-builder; cluster-wide and sso listing of certificates, certificaterequests and orders are Forbidden. The reissue therefore waits for 2026-10-30T16:23Z, the guaranteed-safe date from railiance-cluster; no count is required then.
Done when: the decision is answered, the owners confirm their steps in their own workplans, and the NK49 phase B module, verifier and tests are reviewed to T38 depth. This task does not run phase B and does not replace T18's live consumer login or owner acceptance.
2026-10-27 founder decision (option A): phase B is paused, not built. The accepted design is retained for T44: secrets-engine inherited-pipe runner (65a3dbe) with optimizations 1, 3, 4 and 5; railiance-platform network names (5658150: rpf64-nk49-pb, 10.249.64.0/28, rehearsal -rh-); client secret keycape-secrets-engine-openbao-client key client-secret in archive member resources/sso/secret/keycape-secrets-engine-openbao-client.json; cert reissue not before 2026-10-30T16:23Z. No module, window or signature was produced.
Pre-production joint restore drill with a live consumer login
id: NK-WP-0049-T44
status: cancel
priority: medium
assignee: claude-code
depends_on: [NK-WP-0049-T18, NK-WP-0049-T21]
state_hub_task_id: "0cde15c4-9918-574f-b522-34e620168bc9"
Accountable worker: claude-code. Signatures, windows and secret inputs stay with the founder and owners.
Done when: restored KeyCape and restored OpenBao are joined on the isolated phase B network and a real consumer (secrets-engine-openbao) passes native positive/negative login, plus one browser/PKCE client; this closes key-cape K1 and railiance-platform R1/R2. Start from the T43 design notes; do not edit the pinned T38/T40 sources. Also re-prove reserved-LDAP-group denial and the resolver cutover functionally (from T21).
2026-10-27: moved, not dropped. The founder closed NK-WP-0049 in builder mode, and this drill now lives in NK-WP-0055: T02 (build and rehearse), T03 (live consumer and PKCE login) and T04 (reserved-group denial and resolver re-proof).
Accept remaining recovery and caller evidence and close the G08 handoff
id: NK-WP-0049-T03
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T02, NK-WP-0049-T16, NK-WP-0049-T17, NK-WP-0049-T18, NK-WP-0049-T19, NK-WP-0049-T20, NK-WP-0049-T21, NK-WP-0049-T22, NK-WP-0049-T23, NK-WP-0049-T24, NK-WP-0049-T26]
state_hub_task_id: "d68cd4d3-1ba3-530e-88f9-26ebb8dd6eac"
Accountable worker: codex. Service/credential-owner acceptance remains with the named owner boundary.
Owner boundary: NetKingdom, Platform and affected service owners, with Custodian G08 receiving the final evidence. The completed archive/job milestones remain accepted independently of this final gate.
Done when: T02 and T15–T38 have their stated completed or explicitly accepted handoff outcomes; service authentication/token/audit proof and current/legacy caller dispositions are accepted; the source workplan and projected tasks agree; and G08 has an exact evidence/handoff record. Record actionable residuals as live work records before workplan closure. Preserve historical IDs and receipts; do not call a deferred rotation or an untested full-estate restore complete.
2026-10-27 closure (founder-accepted, builder mode): T03 is done. Dependencies T02 and T15–T38 are done except T43 (cancelled: phase B paused, design retained in T44).
G08 handoff evidence: archive recovery and backup activation (T04–T14, T23–T26); isolated owner recoveries of LLDAP (T16), Authelia (T17), existing-token MFA (T19), privacyIDEA audit continuity (T20), KeyCape issuer side (T18, receipt 16d72f7c…1651, key-cape acceptance fc9f09a) and OpenBao (RPF-WP-0064, receipt 4e048dee…579d, railiance-platform acceptance 5658150); caller ledger (T02) and accepted dispositions (T21); historical objects deleted and verified absent (T22).
Live residuals (not claimed complete): T44 pre-production joint drill (restored KeyCape plus OpenBao live consumer login, browser/PKCE client, reserved-group denial, resolver re-proof); attended factor-diagnostic credential lane (owner-deferred); privacyIDEA credential revocation and exposure rotation under CUST-WP-0073-T05 / decision 1591daa1. NK-WP-0049 closed 2026-10-27; residuals moved to NK-WP-0055.
Evidence locations and refinement history
“Live” above means docs/evidence/2026-10-16-identity-backup-live/ in NetKingdom.
Implementation preparation is in the October16 implementation directory; earlier
backup discovery/database recovery is in docs/evidence/2026-10-15-bootstrap-recovery/.
The source-repair receipts explicitly labelled Custodian belong to that owning
repository. Use the recovery ceremony
for exact procedure and approval history. No secret values belong in task evidence.
Refinement rule: substantial work and newly understood remaining scope must be visible in task blocks at a checkpoint, not only in progress prose. This replan preserves T01–T03 identity and original evidence while making the completed milestones and each remaining acceptance gate separately manageable.
Managed identifier assignment also consumed a preexisting staged generated brief; the follow-up commit restores its prior published baseline while preserving the operator's working brief and original staged version. This is a projection-tool side effect, not new recovery evidence.
R7 source publication and task bindings verified:
5fcd5952add1c0167116094298a1d5feaa60cf30 is the observed published source.
All eight canonical additions match the reviewed bytes; all 33 task statuses
match the actual hub projection, including T32 done and T33 todo. Original
staged/working brief content is preserved. Normal synchronization has zero
failures/automation errors; existing warnings and scanner false-positive history
remain retained. Custodian identity-restore-adapter-next/canonical-r7-integration.json
binds source/projection/native-fixture evidence separately. T18 remains waiting
for the actual owner-held attempt and selected consumer acceptance.
2026-10-17 source/attempt refinement: T34 records completed attended custody, preflight/private-manifest source preparation and its bounded tests; T35 and T36 make original TLS recovery ownership and selected original admission metadata live work. T33 retains final attempt readiness and its original Hub UUID. This adds no actual recovery, MFA, native authority or owner assent. Source task counts above refer to this file; projection has not been claimed for this proposed refinement.
2026-10-17 verified source follow-through: source commit 4f65e41 passed normal
local scanning and 111 canonical focused checks. The initial T34 source-only
preparation now has an exact integrated source revision; existing real-SOPS
compatibility remains partly skipped and actual owner-held execution remains T18.
T35/T36 source preparation is underway, with 17 pinned public-source references. railiance-cluster owns the ingress/cert-manager/cluster-backup substrate; the inspected same-host encrypted backup source establishes no independent original kc-tls/trust recovery or accepted reissue. Draft owner questions remain unsent; no private TLS input was requested. The historically deployed secrets-engine-openbao registration is a defensible proposed consumer: its 7 October issuer and 10 October consumer proofs predate the reviewed archive. The exact selector proposal is retained without current assent or private archive validation. No token exchange, OpenBao login, client secret retrieval, new grant or production redirect occurred. Keep incomplete admission refused before custody. Custodian evidence: recovery-attempt-r1/t35-t36-source-next; final source/projection review: resume-integration-r1/publication-verification.json.