diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index b787e0d..506af82 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -42,7 +42,7 @@ | task | NK-WP-0021-T04 | done | — | workplans/NK-WP-0021-activity-core-ops-sso-operators.md | | task | NK-WP-0021-T05 | done | — | workplans/NK-WP-0021-activity-core-ops-sso-operators.md | | task | NK-WP-0022-T01 | progress | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | -| task | NK-WP-0022-T02 | wait | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | +| task | NK-WP-0022-T02 | done | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T03 | wait | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T04 | wait | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | | task | NK-WP-0022-T05 | wait | — | workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md | diff --git a/docs/railiance01-coulombcore-cutover-inventory-2026-07-28.md b/docs/railiance01-coulombcore-cutover-inventory-2026-07-28.md index 7e1282e..b1b8f50 100644 --- a/docs/railiance01-coulombcore-cutover-inventory-2026-07-28.md +++ b/docs/railiance01-coulombcore-cutover-inventory-2026-07-28.md @@ -62,14 +62,69 @@ equivalence. DNS moved. Keep these intact only for the bounded rollback window; prevent new authoritative writes once state migration begins. +## Encrypted source backup + +A fresh source backup set was created on CoulombCore at +`~/identity-cutover-backups/2026-07-28T0100Z`, encrypted directly to the +existing SOPS/age custody recipient. The directory is mode `0700`; encrypted +artifacts and `SHA256SUMS` are mode `0600`. + +The set contains: + +- hot SQLite backups for LLDAP and Authelia; +- a complete `pg_dumpall` stream for `net-kingdom-pg`; +- privacyIDEA encryption/signing custody files; +- encrypted Kubernetes identity Secrets and ConfigMaps; +- encrypted workload/recovery manifests. + +All encrypted checksums pass. Every artifact decrypts with the custody key; +both restored SQLite databases return `pragma integrity_check = ok`. Plaintext +verification used `/dev/shm` or streams and was removed, and the temporary +export pod was deleted. + +The encrypted set was copied to independent custody on railiance01 at +`~/identity-cutover-backups/coulombcore/2026-07-28T0100Z`. The destination +directory is mode `0700`, every file is mode `0600`, and all source hashes +match. The original checksum manifest contains absolute CoulombCore paths, so +the independent-copy check preserved the manifest and resolved each entry by +basename. + +An isolated restore drill started a temporary PostgreSQL 16 pod with no +service, ingress, or persistent volume. The decrypted dump recreated +`interhub` and `privacyidea_db`; the restored privacyIDEA database contained +the expected one token, one token owner, two realms, two resolvers, and two +policies. The pod and transient restore log were deleted automatically. + +## Semantic comparison + +| State | CoulombCore | railiance01 | Result | +| --- | ---: | ---: | --- | +| LLDAP users | 4 | 3 | divergent | +| LLDAP groups | 7 | 7 | stable-identifier digest divergent | +| LLDAP memberships | 7 | 3 | divergent | +| privacyIDEA tokens | 1 | 0 | critical migration required | +| privacyIDEA token owners | 1 | 0 | critical migration required | +| privacyIDEA realms | 2 | 0 | configuration migration required | +| privacyIDEA resolvers | 2 | 0 | configuration migration required | +| privacyIDEA policies | 2 | 0 | configuration migration required | + +Authelia schemas match. Session, consent, access-token, authorization-code, +and audit counts differ because both instances have been independently active; +those ephemeral sessions should not be merged as authoritative identity data. + +Every compared privacyIDEA custody fingerprint (`enckey`, signing keypair, and +instance UUID) differs. Migrating only database rows would make the enrolled +token unusable. The CoulombCore privacyIDEA database plus its encryption and +signing custody must move as one rollback-tested unit. + ## Required next evidence -1. Create and verify fresh encrypted CoulombCore identity backups. -2. Compare semantic user/group counts and stable identifiers without exporting - credential material into logs. -3. Compare privacyIDEA realms, resolver mappings, token counts, and encryption - custody using redacted/count-only probes. -4. Compare NetKingdom PostgreSQL schemas and row counts. -5. Freeze writes, merge the authoritative source into railiance01, rerun the - comparisons, and then exercise platform-root and Binky login/MFA. +1. Copy the encrypted backup set to independent custody and perform an + isolated PostgreSQL/privacyIDEA restore drill. +2. Decide the LLDAP merge rule for the one source-only user and four + source-only memberships while preserving railiance01-only lifecycle groups. +3. Freeze writes, migrate privacyIDEA database and custody as one unit, and + migrate/merge authoritative LLDAP state. +4. Rerun semantic counts/digests and restart recovery probes. +5. Exercise platform-root and Binky login/MFA. 6. Move LLDAP and privacyIDEA DNS only after those gates pass. diff --git a/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md b/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md index 46a3c12..99c7153 100644 --- a/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md +++ b/workplans/NK-WP-0022-railiance01-identity-cutover-and-coulombcore-retirement.md @@ -75,7 +75,7 @@ source backups remain a hard gate. ```task id: NK-WP-0022-T02 -status: wait +status: done priority: high state_hub_task_id: "fdc7b492-855f-471e-a7df-ee67a291d7a1" ``` @@ -90,6 +90,16 @@ logs, or chat. Done when restore evidence proves the migration can be reversed from independent custody. +2026-07-28: created the age-encrypted source set documented in +`docs/railiance01-coulombcore-cutover-inventory-2026-07-28.md`. Checksums, +age decryption, both SQLite integrity checks, PostgreSQL dump readability, +privacyIDEA archive readability, permissions, and plaintext cleanup passed. +The encrypted set was then copied to mode-`0700` independent custody on +railiance01 with mode-`0600` files and matching source hashes. A temporary, +non-networked PostgreSQL 16 pod restored the full dump and reproduced the +expected `interhub`, `privacyidea_db`, token, owner, realm, resolver, and policy +counts. The pod and transient restore log were removed automatically. + ## T03 - Reconcile persistent identity state onto railiance01 ```task @@ -109,6 +119,12 @@ Do not blindly overwrite newer railiance01-only configuration such as the Done when source/destination counts and semantic probes agree and restart tests pass on railiance01. +Pre-migration comparison proves this task is required: LLDAP is 4/7/7 +users/groups/memberships on CoulombCore versus 3/7/3 on railiance01. +CoulombCore privacyIDEA has one enrolled token, two realms, two resolvers, and +two policies; railiance01 is empty. All privacyIDEA custody fingerprints +differ, so its database and encryption/signing material must migrate together. + ## T04 - Align configuration, secrets, and internal dependencies ```task