net-kingdom/docs/railiance01-coulombcore-cutover-inventory-2026-07-28.md
tegwick a58df4c3e6
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Advance pre-cutover identity conformance
2026-07-28 16:48:47 +02:00

11 KiB

Railiance01 / CoulombCore cutover inventory

Captured read-only on 2026-07-28. This inventory intentionally contains no Secret values, private keys, password hashes, tokens, or database contents.

Public routing

Name Current target Cutover owner/state
kc.coulomb.social railiance01 (92.205.62.239) KeyCape active
auth.coulomb.social railiance01 (92.205.62.239) Authelia active
login.coulomb.social railiance01 (92.205.62.239) Authelia alias active
lldap.coulomb.social CoulombCore (92.205.130.254) identity cutover pending
pink.coulomb.social CoulombCore (92.205.130.254) identity cutover pending
pink-account.coulomb.social CoulombCore (92.205.130.254) identity cutover pending
bao.coulomb.social CoulombCore (92.205.130.254) OpenBao-owned cutover
gitea.coulomb.social CoulombCore (92.205.130.254) Forgejo/Gitea-owned cutover
hub.coulomb.social CoulombCore (92.205.130.254) State Hub-owned cutover

Public recursive resolvers return railiance01 for both Authelia names. The certificate at railiance01 is trusted and covers both names. The portal → KeyCape → Authelia redirect chain terminates on railiance01.

During cutover, cert-manager's HTTP-01 self-check inherited stale node DNS. The live controller now uses 1.1.1.1:53,8.8.8.8:53 for ACME self-checks and the expanded certificate was renewed through cmctl. The cluster add-on configuration must codify that resolver flag so a future Helm reconciliation does not remove it.

Identity workload comparison

Component CoulombCore railiance01 Finding
KeyCape main-nonce-0601 key-cape:909bb32 New runtime is ahead; both healthy
Authelia authelia:4.38 authelia:4.38 Same declared image
LLDAP lldap/lldap:stable lldap/lldap:stable Independent PVCs; content differs
privacyIDEA 3.12.2 3.12.2 Independent data/log PVCs
NetKingdom PostgreSQL 10 Gi PVC 10 Gi PVC Independent clusters require semantic comparison
Identity provisioner absent identity-provisioner:dbf7cfd railiance01-only lifecycle adapter
User engine absent user-engine:portal-e23674d railiance01-only control surface

Both KeyCape endpoints serve the same public JWKS fingerprint: 8e3237da6030c6af91c5005d0112a149204bc549f67d2234939c5581fdb95a32. This proves current public signing-key continuity, not full configuration equivalence.

Persistent state and backup observations

  • Both LLDAP databases are 139264 bytes, but their SHA-256 fingerprints differ: CoulombCore b3be5eed...b91278; railiance01 fc538cc8...03dab. Equal size is not equivalence. Railiance01 also has newer writes from the provisioning conformance path.
  • railiance01 runs daily LLDAP, Authelia, and privacyIDEA backup CronJobs and exposes an LLDAP backup directory on its PVC.
  • The queried CoulombCore workload inventory exposed daily logical PostgreSQL backup CronJobs, but no matching LLDAP, Authelia, or privacyIDEA backup CronJobs. A fresh source-side protected backup is therefore a hard gate.
  • Both servers retain independent LLDAP, Authelia, privacyIDEA, and NetKingdom PostgreSQL PVCs. No DNS move for LLDAP/privacyIDEA is evidence of data migration.
  • CoulombCore still runs KeyCape and Authelia ingress even though their public 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.

Persistent-state reconciliation

T03 used a bounded write freeze covering KeyCape, LLDAP, privacyIDEA, and user-engine where present. Fresh encrypted frozen snapshots were created at:

  • CoulombCore: ~/identity-cutover-backups/2026-07-28T0925Z-pre-migration-source;
  • railiance01: ~/identity-cutover-backups/2026-07-28T0925Z-pre-migration-destination.

Both sets contain LLDAP, privacyIDEA database and custody, and interhub rollback artifacts with passing relative-path checksum manifests.

LLDAP was reconciled as a selective union. The CoulombCore platform-root row, attributes, and memberships are authoritative. railiance01's bootstrap admin, destination test user, and Binky tenant groups remain authoritative. Shared groups were mapped by normalized group name, and the source-only whynot-design and activity-core-operators groups were added with collision-free destination IDs. The known --cleanup-only and t06-final-* lifecycle-test identities were deliberately excluded.

Post-restart LLDAP evidence is:

  • SQLite integrity: ok;
  • users/groups/memberships: 3/9/6;
  • platform-root memberships: 4;
  • destination test user preserved: 1;
  • excluded source test artifacts present: 0.

The complete CoulombCore privacyIDEA database and its matching encryption key, audit signing keypair, and instance UUID were applied as one unit. All four custody fingerprints match the source. Source and destination now both report one token, one token owner, two realms, two resolvers, and two policies. privacyIDEA returned HTTP 200 after restart.

CoulombCore interhub data was loaded into railiance01's newer schema rather than replacing that schema. A legacy hubs.hub_family column was intentionally discarded after the first data-only restore rejected the mismatch and the encrypted destination snapshot was restored. All twelve nonempty source-table row counts and stable row digests match, including a common-column digest for hubs. railiance01's 16-row migration ledger and one destination-only user were preserved.

Temporary helper pods, shared-memory databases, dumps, archives, and restore logs were removed. CoulombCore identity writers remain scaled to zero to prevent divergence while the railiance01 direct-resolution conformance gates run; no PVC, Secret, database, or workload declaration was deleted.

Runtime dependency reconciliation

sso-mfa/k8s/verify-identity-cutover-dependencies.sh now provides the repeatable T04 negative search. It decodes Kubernetes Secret values only in process memory and reports resource/key locators rather than values.

The live railiance01 run passed all gates:

  • no Secret, ConfigMap, Deployment, or StatefulSet in sso, mfa, user-engine, or databases references CoulombCore, its IP, or the public LLDAP/privacyIDEA endpoints;
  • KeyCape resolves LLDAP, Authelia, and privacyIDEA through cluster-local service names and retains both user-engine and rapp-qonto client declarations;
  • privacyIDEA's migrated LLDAP resolver is cluster-local;
  • the KeyCape signing-key fingerprint matches CoulombCore;
  • LLDAP, Authelia, KeyCape, privacyIDEA, and user-engine deployments are Ready.

TLS-preserving direct resolution to 92.205.62.239 returned HTTP 200 with successful certificate verification for auth, login, lldap, pink, and pink-account under coulomb.social.

Pre-cutover conformance progress

KeyCape's canonical issuer is https://kc.coulomb.social; auth.coulomb.social and login.coulomb.social belong to Authelia. The user-engine portal currently returns a 303 to KeyCape with an exact callback and S256 PKCE challenge.

The rapp-qonto-client service flow passes against KeyCape: qonto:read returns a token, a deliberately wrong secret returns 401 without a token, and the excessive qonto:write scope returns 400 without a token.

The deployed user-engine API created the Binky tenant-admin lifecycle record, membership, LLDAP subject, and identity link. The provider reports password_setup_required. This flow found a newline-bearing runtime Secret that could not legally be sent as an HTTP header; user-engine commit 0ef2ae5 normalizes transport whitespace, passes 105 tests with three integration skips, and is deployed as user-engine:portal-0ef2ae5.

The human conformance gate is not yet complete. LLDAP's native self-service password reset requires configured SMTP, but this deployment has no SMTP settings. The existing Binky mailbox route authorizes read-only IMAP and explicitly does not authorize SMTP. No operator-set initial password was used as a shortcut. A reusable NetKingdom password-setup or transactional-mail handoff must precede Binky MFA enrollment and final claim/denial evidence.

Required next evidence

  1. Exercise platform-root and Binky login/MFA using TLS-preserving direct resolution to railiance01.
  2. Verify KeyCape service-client flows and negative authorization probes.
  3. Move LLDAP and privacyIDEA DNS only after those gates pass.