diff --git a/creds-manifests/vm-secret-locations b/creds-manifests/vm-secret-locations index 16cb6e1..e1c864f 100644 --- a/creds-manifests/vm-secret-locations +++ b/creds-manifests/vm-secret-locations @@ -124,3 +124,5 @@ rack vr1-dc0 ssh vr1-dc0-rack:~/.local/share/juju/* rack vr1-dc1 ssh vr1-dc1-rack:~/vr1-dc1-creds/* rack vr1-dc1 ssh vr1-dc1-rack:~/.local/share/juju/* +rack vr1-dc0 ssh vr1-dc0-rack:~/repo-stage/overlays/vr1-dc0-octavia-pki.yaml +rack vr1-dc1 ssh vr1-dc1-rack:~/repo-stage/overlays/vr1-dc1-octavia-pki.yaml diff --git a/creds-matrix-notes.md b/creds-matrix-notes.md index 0804489..c454006 100644 --- a/creds-matrix-notes.md +++ b/creds-matrix-notes.md @@ -447,3 +447,17 @@ dc1's four rows are the FORWARD REGISTER and are EXPECTED to fail S2 until dc1's region is built and its own user minted. That failure is the register working as designed (D-137); do NOT delete the rows to make the checker green. + +## n-overlay-on-rack +The Octavia PKI overlay carries the controller CERT and its PRIVATE KEY, and `juju deploy` +consumes it at deploy time. D-138 moved the cloud-facing juju client INTO the DC, and the +deploy cannot run from `voffice1` at all -- there is no L3 path from the headend to the +controller API on the provider plane. So the overlay must be resident on the DC's own rack. + +Copied 2026-07-30 for dc0, operator-ruled, `0600`, sha256 compared end to end. Per-DC +isolation is preserved BY CONSTRUCTION: each rack receives ONLY its own DC's overlay, never +the pair -- a cross-DC copy would destroy the independence `octavia-pki.sh verify`'s A11 +assertion exists to prove. + +dc1's row is the FORWARD REGISTER and is EXPECTED to fail until dc1 deploys. Do NOT delete +it to go green. diff --git a/creds-matrix.tsv b/creds-matrix.tsv index bb5d9d2..4de7b5f 100644 --- a/creds-matrix.tsv +++ b/creds-matrix.tsv @@ -154,6 +154,7 @@ octavia-pki-backup per-DC vr1-dc0 jumphost octavia-pki-vr1-dc0.tar.gz none service consolidated stage5 runbook:runbooks/phase-01-bundle-deploy.md:694 SEC-023 n-pki-backup octavia-reissue-backup per-DC vr1-dc0 jumphost vr1-dc0-octavia-pki-.tar.gz none service consolidated stage5 runbook:runbooks/phase-01-bundle-deploy.md:853 SEC-023 n-reissue-backup octavia-pki-overlay per-DC vr1-dc0 headend vr1-dc0-octavia-pki.yaml none service off-manifest-known stage5 runbook:runbooks/phase-01-bundle-deploy.md:645 SEC-004 n-overlay-in-clone +octavia-pki-overlay per-DC vr1-dc0 rack vr1-dc0-octavia-pki.yaml none service off-manifest-known stage5 runbook:runbooks/dc-dc-phase4-juju-bundle-per-dc.md:376 SEC-029 n-overlay-on-rack octavia-issuing-ca-passphrase per-DC vr1-dc1 headend passphrase.txt none service off-manifest-known stage5 runbook:runbooks/phase-01-bundle-deploy.md:391 SEC-023 n-outside-convention octavia-issuing-ca-key per-DC vr1-dc1 headend issuing-ca.key.enc none service off-manifest-known stage5 runbook:runbooks/phase-01-bundle-deploy.md:395 SEC-023 n-outside-convention octavia-issuing-ca-cert per-DC vr1-dc1 headend issuing-ca.cert.pem none service off-manifest-known stage5 runbook:runbooks/phase-01-bundle-deploy.md:398 SEC-023 n-outside-convention @@ -168,6 +169,7 @@ octavia-pki-backup per-DC vr1-dc1 jumphost octavia-pki-vr1-dc1.tar.gz none service consolidated stage5 runbook:runbooks/phase-01-bundle-deploy.md:694 SEC-023 n-pki-backup octavia-reissue-backup per-DC vr1-dc1 jumphost vr1-dc1-octavia-pki-.tar.gz none service consolidated stage5 runbook:runbooks/phase-01-bundle-deploy.md:853 SEC-023 n-reissue-backup octavia-pki-overlay per-DC vr1-dc1 headend vr1-dc1-octavia-pki.yaml none service off-manifest-known stage5 runbook:runbooks/phase-01-bundle-deploy.md:645 SEC-004 n-overlay-in-clone +octavia-pki-overlay per-DC vr1-dc1 rack vr1-dc1-octavia-pki.yaml none service off-manifest-known stage5 runbook:runbooks/dc-dc-phase4-juju-bundle-per-dc.md:376 SEC-029 n-overlay-on-rack tenant-domain-admin per-tenant - jumphost -domain-admin-cred.txt gui human off-manifest-known tenant-onboard script:scripts/tenant-onboard.sh:64 SEC-023 n-tenant-dir tenant-cluster-user per-tenant - jumphost -cluster-cred.txt api human off-manifest-known tenant-onboard script:scripts/tenant-onboard.sh:90 SEC-023 n-tenant-dir tenant-svc-user per-tenant - jumphost -svc-cred.txt api service off-manifest-known tenant-onboard script:scripts/tenant-onboard.sh:90 SEC-023 n-tenant-dir diff --git a/docs/security-ledger.md b/docs/security-ledger.md index a02b009..8ec59a7 100644 --- a/docs/security-ledger.md +++ b/docs/security-ledger.md @@ -79,3 +79,4 @@ | SEC-026 | 2026-07-30 | **A MAAS admin-scoped API key becomes RESIDENT on a DC-local host, by D-138.** D-138 (RULED 2026-07-30) moves the cloud-facing client -- the Juju client, and `phase-03`..`phase-06`'s `openstack` CLI work -- INTO each DC, because `voffice1` has no L3 path to any DC node plane and SEC-010/D-052/D-125 deliberately forbid creating one. The client needs its DC's MAAS credential where it runs, so `juju-vr1-dc0`'s key (SEC-018) now lives on the dc0 client host, and `juju-vr1-dc1`'s (SEC-019) will on dc1's. **The exposure is wider than the DC it sits in: the key is MAAS ADMIN-scoped (full machine/power/deploy) and the MAAS region is SHARED by BOTH DCs**, so a host inside dc0 holding it has region-wide MAAS admin, including over dc1's hardware. This is a NEW residency, not a new key -- SEC-018/-019 already carry the keys' own rotation obligations. | 2026-07-30 Stage-5 bootstrap failure + D-138 ruling; capture `docs/audit/stage5-bootstrap-reachability-20260730.txt` | operator | **OPEN.** (1) **ISOLATION IS THE LOAD-BEARING CONTROL:** each DC's client host receives ONLY THAT DC's credential. Never copy the whole Juju client credential store (`~/.local/share/juju/credentials.yaml` on voffice1 holds BOTH `vr1-dc0-cred` and `vr1-dc1-cred`) to a DC host -- that single act would put dc1's credential on dc0's rack and destroy the per-DC isolation SEC-018/-019 exist to create. Verify after any client rebuild that `juju credentials --client` on a DC host lists exactly one. (2) ROTATE at v1 close, or immediately if the DC client host is rebuilt or shared. (3) SCOPE HARDENING CANDIDATE, Roosevelt-relevant: MAAS has no per-DC admin scope, so the blast radius is regional by construction; a narrower grant (or a per-DC MAAS region) is the fix and is deferred, not solved. (4) The residency must be re-asserted at every DC standup as part of D-138's definition-of-done. | | SEC-027 | 2026-07-30 | **Per-DC MAAS region controller credentials -- a NEW credential class, three secrets per DC.** D-132's amendment (RULED 2026-07-30) gives each DC its own MAAS region controller VM at utility-band `.6`, running its own `regiond` + PostgreSQL. Each region therefore mints and holds: (a) a PostgreSQL role password for the `maas` DB role, (b) a MAAS region `admin` account password (a HUMAN login), and (c) that admin's MAAS API key (3-part, service). dc0's are MINTED and consolidated to `~/vr1-dc0-creds/` (`maas-region-db-password`, `maas-region-admin-password`, `maas-region-api-key.txt`, all 0600, sha256-verified identical to the on-VM source, never printed). dc1's are NOT YET MINTED -- its region VM is authored but not applied. **These are NOT the Office1 region's credentials and must never be conflated with them**: the entire point of the per-DC region is that each DC's provider API is independent of Office1. | 2026-07-30 Stage-5 region build; D-132 amendment + addendum; capture `docs/audit/stage5-bootstrap-reachability-20260730.txt` | operator | **OPEN -- rotation obligation + two structural notes.** (1) ROTATE all three at v1 close, or immediately if the region VM is rebuilt or shared. (2) **RESIDUAL ARGV EXPOSURE, recorded rather than hidden:** `maas init` offers NO stdin or file option for `--database-uri`, so the DB password is briefly visible in that host's own `ps` output at init time and is then written to `/var/snap/maas/current/regiond.conf`. The URI was assembled inside the remote shell from a 0600 file so it never reached the operator terminal or the session transcript, but the argv exposure on the VM itself is unavoidable with this tool. Identical in shape to the existing Office1 region -- not a new exposure class. (3) **PROVENANCE DEBT, deliberate:** all five matrix rows carry `mint-ref=operator-terminal` because NO repo script mints these yet. That is truthful, not an oversight -- writing the region install into a runbook or script is what clears it, and until then these are not reproducible from the repo if the jumphost is rebuilt (research FINDING 1 class). (4) The `region` host-role token was added to `scripts/creds-matrix.py`'s enum for this class; `creds-manifests/vm-secret-locations` gained four rows, which is definition-of-done for a new mint site (an unlisted location is not audited -- how SEC-022 happened). | | SEC-028 | 2026-07-30 | **Per-DC JUJU SERVICE credential, and the RACK becomes a credential-bearing host for the first time.** D-132 q1 gives each DC its own MAAS region with its own database, so the Office1 `juju-vr1-dc0` user and its API key do NOT authenticate against dc0's region -- a fact that reads as a network fault at bootstrap rather than as an auth failure. dc0's `juju-vr1-dc0` was therefore MINTED IN THE NEW REGION 2026-07-30 (superuser, mirroring the measured Office1 shape, which MAAS 3.7 requires for machine allocate/deploy) together with its 3-part API key and account password. Minted ON the region VM, never printed, moved host-to-host with all three sha256 digests compared, staging shredded. Consolidated to `~/vr1-dc0-creds/` on the jumphost (0600) and distributed to the dc0 RACK (0600 in a 0700 folder) because **D-138 moved the cloud-facing Juju client INTO the DC** -- so `rack` is now a credential-bearing host-role, which it had never been. dc1's is NOT YET MINTED (its region VM is authored, not applied). | 2026-07-30 Stage-5 Juju re-point; D-132 q1 + D-138; captures in `docs/audit/dc0-node-carve-20260730.txt` and this session's changelog | operator ("Mint juju-vr1-dc0 on the new region (Recommended)") | **OPEN -- rotation obligation + three notes.** (1) ROTATE at v1 close, or immediately if the rack or region VM is rebuilt or shared. (2) **BLAST RADIUS IS DC-LOCAL BY CONSTRUCTION and this is strictly BETTER than the alternative considered:** the rejected option was pointing juju at the region ADMIN key already consolidated on vcloud, which would have placed an admin-scoped credential on the rack -- the residency SEC-026 exists to constrain. This key administers dc0's region ONLY; no cross-DC reuse, per SEC-012/-016/-018/-019. (3) **`vm-secret-locations` gained its FIRST `rack` rows** (four, both DCs) -- definition-of-done for a new mint site, since an unlisted location is not audited (how SEC-022 happened). It also now covers the rack's `~/.local/share/juju/*` credential store, where juju keeps its own runtime copy. (4) dc1's four matrix rows are the FORWARD REGISTER and FAIL S2 by design until dc1's region exists -- that failure is D-137 working, and the rows must NOT be deleted to go green. **These two NEW S2 findings are NOT covered by the operator's 2026-07-30 P5 acceptance, which enumerated six and said so explicitly.** | +| SEC-029 | 2026-07-30 | **Octavia PKI overlay resident on the DC RACK.** The overlay carries the Octavia controller CERT and its PRIVATE KEY, and `juju deploy` consumes it at deploy time. D-138 moved the cloud-facing juju client INTO the DC, and the deploy CANNOT run from `voffice1` at all -- there is no L3 path from the headend to the controller API on the provider plane. dc0's overlay was therefore copied to the dc0 rack 2026-07-30 (`~/repo-stage/overlays/vr1-dc0-octavia-pki.yaml`, `0600`, sha256 compared end to end and equal). dc1's is NOT yet copied. | 2026-07-30 Stage-5 bundle deploy; D-138; this session's changelog | operator ("Copy dc0's PKI overlay to the dc0 rack (Recommended)") | **OPEN -- residency, not a new key.** (1) This is a COPY of material that already exists on the headend (SEC-004 `n-overlay-in-clone`), not a new mint, so the rotation obligation remains the existing `octavia-pki.sh reissue` path -- **and that path must now update BOTH copies, or the rack will deploy a superseded cert.** (2) Per-DC isolation holds BY CONSTRUCTION: each rack receives ONLY its own DC's overlay, never the pair; a cross-DC copy would destroy the independence that `octavia-pki.sh verify`'s A11 assertion exists to prove. (3) `~/repo-stage/` on the rack is a STAGING directory created because the rack has NO REPO CLONE -- the same D-138 tooling gap as queued finding F1. If a clone is later placed on DC client hosts, this path moves and the `vm-secret-locations` row must move with it. |