docs(recovery): accept retained token material and audit continuity
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a13eab-1e6a-7b33-9c37-372e90ada3a2
This commit is contained in:
tegwick 2026-10-16 21:14:23 +02:00
parent 3223039446
commit 8ae5150d4d
7 changed files with 141 additions and 30 deletions

View file

@ -520,3 +520,18 @@ plaintext were cleaned; failure markers and event outbox remain empty. This
validates the actual hardened recurring-job path, beyond a direct CLI capture.
Evidence: `recurring-job-review.json`. No further validation captures are needed
before the next scheduled run absent a new failure or source change.
## Native token-material and audit acceptance — 2026-10-16
The independently retrieved identity generation passed native privacyIDEA checks
on the fixed isolated local engine: all five retained token materials were read
internally using the original enckey; unrelated-key results differed for all five.
All 279,209 stored historical signatures verified, with zero unsigned/invalid
rows. A new isolated entry verified with the preserved identity; tampering and
an unrelated public key were refused. Container/plaintext cleanup passed.
T20/T31 are done. Safe evidence and source/ciphertext/target bindings are in
`evidence/2026-10-16-identity-outage-recovery/actual-isolated-privacyidea-review.json`.
This accepts internal readback and stored-row signature continuity. Existing-token
MFA, Authelia and KeyCape authentication remain separate; event completeness is
not claimed. The published Storage Share kit remains its recorded version.

View file

@ -0,0 +1,54 @@
{
"schema": "netkingdom.isolated-privacyidea-recovery.v1",
"status": "isolated_privacyidea_checked",
"production_contacted": false,
"secret_values_exported": false,
"existing_token_mfa_proven": false,
"audit_signature_continuity_proven": true,
"container_cleanup_verified": true,
"temporary_plaintext_cleanup_verified": true,
"source_sha256": "4df7196678aac1ad594f32abf45c68dc21a9d2760d9e8a536a215a4a3c5d277f",
"target": {
"engine_id": "74f93783-6cef-43a8-a3c4-f62586cd3bc1",
"engine_name": "bnt-lap001",
"images": [
{
"reference": "docker.io/lldap/lldap@sha256:9e605a66c02514bfcffd1b67cafb1e98d50992216bb2871d7ae44622047dd09d",
"image_id": "sha256:9e605a66c02514bfcffd1b67cafb1e98d50992216bb2871d7ae44622047dd09d"
},
{
"reference": "ghcr.io/gpappsoft/privacyidea-docker@sha256:af7841adad262f129e0c1d4f553af13f21cb2f4dc713533f316cfe43ed0b4473",
"image_id": "sha256:af7841adad262f129e0c1d4f553af13f21cb2f4dc713533f316cfe43ed0b4473"
},
{
"reference": "postgres@sha256:ff23cdce56cac62ada6f66013e1a50864c0abbe79d132d40b6e05bd80f378a70",
"image_id": "sha256:ff23cdce56cac62ada6f66013e1a50864c0abbe79d132d40b6e05bd80f378a70"
}
],
"production_contacted": false,
"network_mode": "none",
"host_ports_published": false
},
"ciphertext_sha256": "7117b3fe1e4840c86b301c94c85e6b16709e5626bb0884bd0580bde630e30e30",
"manifest_file_count": 36,
"all_manifest_hashes_verified": true,
"container_isolation_verified_before_private_import": true,
"retained_tokens_total": 5,
"retained_tokens_with_native_decryption": 5,
"different_key_cannot_reproduce_material_count": 5,
"retained_token_material_decrypted_inside_process": true,
"historical_audit_rows": 279209,
"historical_signed_rows": 279209,
"historical_unsigned_rows": 0,
"historical_invalid_signatures": 0,
"historical_legacy_signatures": 0,
"all_stored_audit_rows_checked": true,
"legacy_signature_verification_enabled": false,
"event_completeness_claimed": false,
"new_audit_entry_signed_verified": true,
"tampered_entry_refused": true,
"wrong_audit_public_key_refused": true,
"only_loopback_interface_verified": true,
"external_routes_absent": true,
"finished_at": "2026-10-16T19:10:46.010387+00:00"
}

View file

@ -0,0 +1,29 @@
{
"schema": "netkingdom.actual-isolated-privacyidea-review.v1",
"status": "verified",
"accepted_at": "2026-10-16T19:10:46.010387+00:00",
"receipt": "actual-isolated-privacyidea-recovery.json",
"source_commit": "3223039446dc92c692dafb587127e93701a3c230",
"source_sha256_matches": true,
"known_recovered_ciphertext_matches": true,
"exact_local_target_matches": true,
"manifest_files_verified": 36,
"retained_token_materials_read_internally": 5,
"wrong_key_material_refusals": 5,
"historical_signatures_verified": 279209,
"historical_unsigned_or_invalid_rows": 0,
"new_signature_and_negative_checks_verified": true,
"container_and_plaintext_cleanup_verified": true,
"existing_token_mfa_proven": false,
"event_completeness_claimed": false,
"agent_received_private_credentials": false,
"accepted_tasks": [
"NK-WP-0049-T20",
"NK-WP-0049-T31"
],
"knowledge_orientation": {
"version": "0.2.6",
"digest": "8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02",
"source_status": "withheld; current repository security companion reviewed directly"
}
}

View file

@ -1,8 +1,8 @@
# Isolated identity service restore packet
NK-WP-0049-T15. Prepared 2026-10-16. **Actual LLDAP recovery accepted at
18:37 UTC. Native privacyIDEA token-material/audit stage is prepared for an
owner run; MFA, Authelia and KeyCape stages remain unexecuted.**
18:37 UTC; native privacyIDEA token-material/audit recovery accepted at
19:10 UTC. Existing-token MFA, Authelia and KeyCape remain unexecuted.**
Accountable preparer: codex. Execution/acceptance: Railiance Platform and the
LLDAP, Authelia, KeyCape and privacyIDEA service owners.
@ -143,7 +143,7 @@ current production password validity, MFA or audit continuity.
Do not silently reset credentials or re-enroll tokens to pass. Historical audit
verification failures must be reported, not hidden with replacement keys.
## Ready owner step: privacyIDEA token material and stored audit history
## Accepted privacyIDEA token-material and stored-audit stage
```bash
bash tools/bootstrap-recovery/run-isolated-privacyidea.sh \
@ -193,8 +193,12 @@ scan. Counts/signatures/keys are never replaced with a sample to claim success.
Exit0 means these bounded checks and cleanup passed. Exit2 means checks completed
but historical audit exceptions need owner disposition; T20 must stay open.
Exit1 indicates another failure. All outcomes have a safe receipt in the printed
private evidence directory. Return only that directory and the outcome. Actual
owner results are still pending; native synthetic fixtures do not close T20/T31.
private evidence directory. Return only that directory and the outcome. Actual owner recovery passed at 19:10 UTC on 2026-10-16: five retained token
materials read internally, 279,209 historical signatures verified, no unsigned or
invalid rows, new-entry verification, both negative checks and cleanup passed.
T20/T31 are done. Source/ciphertext/target bindings and the safe receipt are in
`evidence/2026-10-16-identity-outage-recovery/actual-isolated-privacyidea-review.json`.
Existing-token MFA remains T19; event completeness is not claimed.
## Unresolved inputs before execution
@ -209,6 +213,6 @@ owner results are still pending; native synthetic fixtures do not close T20/T31.
- Service-owner acceptance of network/config translations and all required
grants. New grants or production effects require their own owner decisions.
Until resolved, T15 stays in progress and T17–T20 remain waiting; T16 is done. Production
Until resolved, T15 stays in progress and T17–T19 remain waiting; T16, T20 and T31 are done. Production
cutover, full-host/OpenBao restoration and application database recovery are
separate owner procedures.

View file

@ -120,14 +120,14 @@ consumer_guidance:
or recovery
- 2026-10-14 architecture review estimates operational maturity separately; a registry
entry does not authorize execution or establish deployment.
- Actual old privacyIDEA database recovery passed; full token decryption, audit
continuity and directory/issuer authentication remain open.
- Actual privacyIDEA internal token-material readback and stored audit continuity
passed; existing-token MFA, Authelia and KeyCape authentication remain open.
- Storage Share initial destination only; no second-provider full identity copy
or autonomous bare-VM restore is established.
- Actual first full identity bundle captured, sealed and Storage Share readback
verified on2026-10-16; both scoped readers passed native identity/namespace/audience/ESO
checks. Independent human-key full archive recovery passed and daily backup/hourly
health are active. Complete service authentication/token decryption/audit continuity
health are active. Full service authentication, existing-token MFA
and an unattended full-estate rebuild remain unproven. 56 focused implementation
checks pass.
---
@ -172,12 +172,13 @@ with synthetic credentials passed, including an encrypted-bundle restore. All
five pinned service images were saved/reloaded locally. T28/T29 record that
preparation. Actual private real-backup LLDAP recovery passed on 2026-10-16;
T16 is done, with original identity rows, positive/negative native bind,
isolation and cleanup accepted. Other service/MFA/audit lanes remain open.
isolation and cleanup accepted. Authelia, KeyCape and existing-token MFA remain open.
The next prepared stage is `run-isolated-privacyidea.sh TRANSFER_RECEIPT`, with
The token-material/audit stage is `run-isolated-privacyidea.sh TRANSFER_RECEIPT`, with
only a hidden backup-key prompt. Its pinned native routines check internal
token-material readback and stored audit signatures, preserve original keys,
report history exceptions and remove the isolated database/worker/tmpfs. Native
synthetic tests cover valid, tampered and unsigned history, malformed keys and
encrypted-bundle recovery. Actual owner evidence remains T20/T31; existing-token
MFA remains T19 and is not implied by token-material decryption.
encrypted-bundle recovery. Actual owner recovery passed on 2026-10-16: five token materials read internally,
279,209 stored signatures verified, new-entry/negative checks and cleanup passed.
T20/T31 are done; existing-token MFA remains T19 and is not implied by readback.

View file

@ -29,7 +29,7 @@ grant. Actual-image synthetic tests and the real owner backup-recovery run
passed on 2026-10-16; T16 is done. See the packet and actual LLDAP receipt for
the exact target, resource limits, accepted scope and repeat-drill command.
`run-isolated-privacyidea.sh TRANSFER_RECEIPT` is the next prepared owner step.
`run-isolated-privacyidea.sh TRANSFER_RECEIPT` is the token-material/audit recovery step.
It asks only for the existing backup age key. `isolated-privacyidea.py` restores
the linked dump into a loopback-only PostgreSQL/container namespace, reads
retained token material internally, and verifies all stored audit signatures
@ -37,6 +37,9 @@ plus one new isolated entry and wrong-public-key/tampering negatives. Original
keys are preserved; audit exceptions are reported without rewriting history.
No MFA code is consumed or native MFA acceptance claimed. Exit2 requires owner
review of audit exceptions; see the packet for bounds and safe receipts.
The actual owner run passed on 2026-10-16: five retained token materials,
279,209 historical signatures, new-entry and negative checks, and cleanup.
T20/T31 are done; actual existing-token MFA remains T19.
`verify-bundle.py` validates a digest-bound age-encrypted `secrets/` tar archive
using an explicit private temporary key and registered `keys/age.pub`. It checks

View file

@ -28,8 +28,8 @@ 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.
**Current position:** 20 tasks done; 2 in progress; 1 ready to start (`todo`);
8 waiting on explicit prerequisites. These are task counts, not an effort-based
**Current position:** 22 tasks done; 2 in progress; 1 ready to start (`todo`);
6 waiting on explicit prerequisites. These are task counts, not an effort-based
completion percentage. Assignees are also written in task descriptions because
the current Forge projector does not populate the dedicated Hub assignee field. The outage-retrieval tool and restore-packet draft are now prepared;
independent outage retrieval and Storage Share publication are accepted;
@ -494,7 +494,7 @@ status: wait
priority: high
assignee: codex
depends_on: [NK-WP-0049-T15, NK-WP-0049-T16, NK-WP-0049-T31]
blocking_reason: "LLDAP recovery T16 passed; await the exact isolated privacyIDEA adapter/procedure and owner-selected retained-token/MFA inputs."
blocking_reason: "LLDAP T16, token-material T31 and audit T20 passed; await the exact isolated MFA adapter and owner-selected retained-token/factor inputs."
state_hub_task_id: "6f8af1a7-2a3f-5fa8-8202-83103ebd55b2"
```
@ -521,11 +521,10 @@ selected user's private factor input and exact isolated MFA adapter remain T19.
```task
id: NK-WP-0049-T20
status: wait
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T30]
blocking_reason: "Await the private owner run of the prepared T30 audit/token-material executor with the independent backup age key; exact local target, original-key preservation and native fixtures are prepared."
state_hub_task_id: "375fa8f9-b8a5-5048-97a7-ec141aa7c45d"
```
@ -542,14 +541,16 @@ for explicit owner disposition; do not regenerate keys to hide it. Matching RSA
pairs from T13 are a prerequisite, not audit-history verification.
2026-10-16: the bounded audit stage is prepared in T30 independently of the full
multi-service T15 packet. **Unblock:** owner runs
`bash tools/bootstrap-recovery/run-isolated-privacyidea.sh /tmp/nk49-offline-handoff-1X660a5t/transfer.json`
in a private terminal and returns the safe outcome/receipt. It requests only the
backup age key, never MFA or provider credentials. All stored historical rows
are checked; unsigned/invalid history is reported for explicit owner disposition
and never rewritten. Exit2 is a review outcome, not completion. Existing-token
MFA and event completeness are not claimed by this audit stage.
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
@ -882,11 +883,10 @@ material/audit acceptance remains T31/T20; actual MFA remains T19.
```task
id: NK-WP-0049-T31
status: wait
status: done
priority: high
assignee: codex
depends_on: [NK-WP-0049-T13, NK-WP-0049-T30]
blocking_reason: "Await the owner's private age-key run of the prepared T30 executor against the independently retrieved actual bundle; synthetic native proof is complete."
state_hub_task_id: "26383841-8076-5c53-bbd1-9db64e32544a"
```
@ -894,7 +894,12 @@ state_hub_task_id: "26383841-8076-5c53-bbd1-9db64e32544a"
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.
**Unblock:** the same private `run-isolated-privacyidea.sh` run used for T20.
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