219 lines
11 KiB
Markdown
219 lines
11 KiB
Markdown
# 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.
|