diff --git a/creds-manifests/vr1-dc0.manifest b/creds-manifests/vr1-dc0.manifest index f8f8563..edc3762 100644 --- a/creds-manifests/vr1-dc0.manifest +++ b/creds-manifests/vr1-dc0.manifest @@ -15,3 +15,15 @@ vr1-dc0_svc_ed25519 600 local vr1-dc0_svc_ed25519.pub 644 local +# Edge service keypair (D-112(c) console bootstrap; minted on vcloud at the dc0 +# edge-bootstrap step). BACKFILL 2026-07-25: these rows were the queued finding +# named in creds-manifests/vr1-dc1.manifest -- dc1 declared its equivalents at +# mint time, dc0's never were, so both showed as UNDECLARED creds-audit FAILs. +vr1-dc0-edge_ed25519 600 local +vr1-dc0-edge_ed25519.pub 644 local +# Dedicated dc0 MAAS admin API key for the Juju cloud credential (SEC-018; +# MAAS superuser juju-vr1-dc0). Generated FROM the jumphost 2026-07-24 so it +# never persisted on the region -- hence provenance "local", not a :. +# A runtime copy also lives in Juju's client credential store on voffice1 +# (off-manifest -- that store is not this folder). Declared 2026-07-25. +maas-api-key.txt 600 local diff --git a/creds-manifests/vr1-dc1.manifest b/creds-manifests/vr1-dc1.manifest index d53bd99..161e4ed 100644 --- a/creds-manifests/vr1-dc1.manifest +++ b/creds-manifests/vr1-dc1.manifest @@ -28,3 +28,10 @@ # voffice1's region MAAS snap (off-manifest -- the snap is not this folder). vr1-dc1-maas-power_ed25519 600 local vr1-dc1-maas-power_ed25519.pub 644 local +# Dedicated dc1 MAAS admin API key for the Juju cloud credential (SEC-019; +# MAAS superuser juju-vr1-dc1). Generated FROM the jumphost 2026-07-24 so it +# never persisted on the region -- hence provenance "local", not a :. +# A runtime copy also lives in Juju's client credential store on voffice1 +# (off-manifest -- that store is not this folder). Declared 2026-07-25; it was +# an UNDECLARED creds-audit FAIL until then. +maas-api-key.txt 600 local diff --git a/creds-manifests/vr1-office1.manifest b/creds-manifests/vr1-office1.manifest index 3b6f8eb..0beaaf5 100644 --- a/creds-manifests/vr1-office1.manifest +++ b/creds-manifests/vr1-office1.manifest @@ -9,6 +9,24 @@ # office1-netbox:/root/netbox-secrets/api.token went # un-consolidated until it was needed). # +# MAAS region GUI/superuser passwords (SEC-020, 2026-07-25). +# maas-admin-password -- the `admin` superuser's password, MINTED ON THE REGION VM +# by scripts/site-headend-install.sh:452 (newpass -> 28 chars, alphanumeric, NO +# trailing newline) and left root-only at /root/maas-secrets/admin.pass until this +# consolidation. This is the SEC-009 miss class the NetBox token established: a +# VM-minted secret with no forcing function to reach the folder. Byte-identical +# copy (sha256-verified); the VM copy remains source-of-record, this is the working +# copy. `admin` doubles as the automation identity (the `maas admin` CLI profile, +# 19 call sites), which is WHY nobody ever needed its password -- see SEC-020. +# maas-operator-password -- the `operator` superuser, minted 2026-07-25 for HUMAN GUI +# login so a person no longer has to authenticate as the service identity. 32-char +# base64, generated on vcloud, set via stdin (never argv, per SEC-018 discipline). +# STILL UN-CONSOLIDATED on voffice1 (logged finding, NOT actioned -- hard rule 1): +# /root/maas-secrets/{admin.apikey,db.pass,lxd-trust.pass}. admin.apikey is trivially +# regenerable (`maas apikey --username=admin`) so it is deliberately NOT copied here; +# db.pass + lxd-trust.pass are region infrastructure, out of scope of this task. +maas-admin-password 600 voffice1:/root/maas-secrets/admin.pass +maas-operator-password 600 local office1_svc_ed25519 600 local office1_svc_ed25519.pub 644 local opnsense-api.txt 600 local diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index ba6d7b8..6cb227d 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -224,6 +224,26 @@ 12 -> 15, phase-4 runbook:192 "no designate".** The reconciliation backlog (the "what else to queue" answer, P0-P2) is in the record; extend `netbox/sandbox-fidelity-check.py` FIRST (it gates every apex recon). + - **MAAS REGION ACCOUNTS -- recovered/consolidated 2026-07-25 (SEC-020; capture + `docs/audit/maas-admin-recovery-20260725.txt`).** The 2026-07-25 ledger claim that + MAAS web-GUI login "does NOT exist / was never minted" is **FALSIFIED**: the `admin` + superuser's password was minted 2026-07-13 by `site-headend-install.sh:452` and is + MEASURED working (login 204 with the stored value vs 400 wrong-password control; + `has_usable_password=True` for all accounts). The real defect was narrower -- it sat + root-only at `voffice1:/root/maas-secrets/admin.pass`, un-consolidated (the SEC-009 + miss class). Operator-ruled scope "New account + consolidate only": `admin` password + CONSOLIDATED byte-identical (sha256-verified) to `~/vr1-office1-creds/maas-admin-password` + -- **the VM copy REMAINS source-of-record; any future rotation must update both copies + or the VM copy becomes a stale trap**; NEW superuser `operator` minted for human GUI + login (password via stdin, never argv). NO existing password rotated -- `juju-vr1-dc0/dc1` + stay random+unstored BY RULING (their SEC-018/019 API keys are load-bearing for the + bootstrap below, and passwords are independent of API keys). `MAAS` + `maas-init-node` + are MAAS-internal, untouched. `creds-audit` now CLEAN on all THREE sites (was RED: dc0 3 + + dc1 1 undeclared files, incl. the dc0 edge-keypair rows that were a queued backfill + finding). ROOT CAUSE recorded: `admin` doubles as the automation identity (its API key + drives the `maas admin` CLI profile across 19 call sites in 4 scripts), so automation + never needed the password and nothing forced it into the folder -- proposable as the + next-free D-number [ARCH], NOT assigned. - **THEN, gated (per the D-104-amendment + the open items above):** per-role MAAS tags; author + apply the 10th controller VM (egress OPEN); resolve the vault-VIP + phasing; fix the deploy-gate scripts; `juju bootstrap` (controller tag, egress OPEN) -> deploy. diff --git a/docs/audit/maas-admin-recovery-20260725.txt b/docs/audit/maas-admin-recovery-20260725.txt new file mode 100644 index 0000000..3267604 --- /dev/null +++ b/docs/audit/maas-admin-recovery-20260725.txt @@ -0,0 +1,42 @@ +=== MAAS admin-account recovery -- measured evidence, 2026-07-25 === +Host: vcloud (jumphost). Region: http://10.10.0.20:5240/MAAS (measured from `maas --help`). +Scope RULED by operator: "New account + consolidate only" -- no existing password rotated. +NO secret VALUES appear in this capture (format/hash/status only). + +--- 1. MAAS users AFTER the change (cmd: maas admin users read) --- + MAAS superuser=True email=maas@localhost + admin superuser=True email=admin@office1.local + juju-vr1-dc0 superuser=True email=juju-vr1-dc0@vr1.local + juju-vr1-dc1 superuser=True email=juju-vr1-dc1@vr1.local + maas-init-node superuser=False email=node-init-user@localhost + operator superuser=True email=jesse.austin@neumatrix.com + +--- 2. Django password state (cmd: maas-region shell; booleans only) --- + MAAS super=True active=True usable_pw=True + admin super=True active=True usable_pw=True + juju-vr1-dc0 super=True active=True usable_pw=True + juju-vr1-dc1 super=True active=True usable_pw=True + maas-init-node super=False active=False usable_pw=True + operator super=True active=True usable_pw=True + +--- 3. GUI login probes, each with a wrong-password CONTROL (204=auth, 400=reject) --- + admin stored_password=204 wrong_password_control=400 + operator stored_password=204 wrong_password_control=400 + +--- 4. admin password consolidation fidelity (sha256, first 16 hex) --- + source voffice1:/root/maas-secrets/admin.pass = be9d791d108d9b44 + copy ~/vr1-office1-creds/maas-admin-password = be9d791d108d9b44 + verdict=BYTE-IDENTICAL + +--- 5. stored file metadata (mode/bytes; no values) --- + maas-admin-password mode=600 bytes=28 + maas-operator-password mode=600 bytes=32 + +--- 6. creds-audit all three sites (cmd: bash scripts/creds-audit.sh ) --- + creds-audit vr1-office1: CLEAN + creds-audit vr1-dc0: CLEAN + creds-audit vr1-dc1: CLEAN + harness: creds-audit: 7/7 PASS + +--- 7. automation unaffected (admin CLI profile / 19 `maas admin` call sites) --- + maas admin users read -> 6 users returned, profile functional diff --git a/docs/changelog-20260725-maas-admin-recovery.md b/docs/changelog-20260725-maas-admin-recovery.md new file mode 100644 index 0000000..d03c0e2 --- /dev/null +++ b/docs/changelog-20260725-maas-admin-recovery.md @@ -0,0 +1,144 @@ +# Session changelog 2026-07-25 -- MAAS admin-account recovery + creds consolidation + +Branch `dc-dc-stage4-phase3-maas-deploy`. Operator task: "complete the recovery of +the MAAS admin accounts ... complete password resets, and save the creds in their +proper folders so I can retrieve them." Status lives ONLY in `docs/CURRENT-STATE.md` +(GA-R1); this changelog is the review surface -- each item states what / why / revert. + +Measured evidence for every claim below: +`docs/audit/maas-admin-recovery-20260725.txt` (42 lines, no secret values). + +**The task premise was FALSIFIED by measurement before any mutation.** The +session-ledger's 2026-07-25 "IMMEDIATE NEXT" asserted MAAS web-GUI login "does NOT +exist ... never minted; no prior task did it". It did exist: the `admin` superuser's +password was minted 2026-07-13 by `scripts/site-headend-install.sh:452` and is +MEASURED working (login POST 204 with the stored value, 400 with a wrong-password +control; `has_usable_password=True`). It was merely root-only on voffice1 at +`/root/maas-secrets/admin.pass` and never consolidated to `~/vr1-office1-creds/` -- +the SEC-009 miss class, not a missing account. Only the ledger's `juju-*` clause was +correct. That finding was reported and the scope RE-RULED by the operator before +execution: **"New account + consolidate only"** -- no existing password rotated. + +## Item 1 -- NEW MAAS superuser `operator` (live region mutation, gated) + +**What:** minted MAAS superuser `operator` / `jesse.austin@neumatrix.com` on the +Office1 region for HUMAN GUI login. Password 32-char base64, generated ON vcloud +straight into `~/vr1-office1-creds/maas-operator-password` (0600), then fed to +`maas createadmin` over **stdin** -- never in argv, never printed, never in context. +Verified: account present + `superuser=True`; stored password authenticates (204) +against a wrong-password control (400). +**Why:** operator-ruled scope. Gives a human identity distinct from the service +identity -- until now the only usable GUI login was `admin`, which is simultaneously +the automation identity (item 6). Note `maas changepassword` has NO `--password` +flag and `createadmin --password` would place the secret in argv (the shape +`site-headend-install.sh:452` uses); the stdin path satisfies the SEC-018 +"never printed/echoed/in argv" discipline and is the transferable technique. +**Revert:** `ssh voffice1 'maas admin user delete operator'` then +`rm ~/vr1-office1-creds/maas-operator-password` and drop its manifest row (item 3). + +## Item 2 -- `admin` password CONSOLIDATED to the jumphost (no rotation) + +**What:** copied `voffice1:/root/maas-secrets/admin.pass` -> +`~/vr1-office1-creds/maas-admin-password` (0600, 28 bytes). Byte-identical, +sha256-verified both ends. Value moved over ssh into the file; never printed. +Verified the CONSOLIDATED copy authenticates as `admin` (204). +**Why:** closes the SEC-009 miss for this secret -- it is now retrievable from the +operator's own folder instead of being root-only on a VM. Deliberately NOT rotated +(operator ruling), so **the VM copy REMAINS source-of-record** and the vcloud file is +a working copy; a future `admin` rotation must update BOTH in one operation or the VM +copy becomes a stale trap. Recorded in SEC-020. +**Revert:** `rm ~/vr1-office1-creds/maas-admin-password` + drop its manifest row. +No loss -- the source-of-record copy on voffice1 was never modified. + +## Item 3 -- `creds-manifests/vr1-office1.manifest`: two new declared secrets + +**What:** declared `maas-admin-password` (provenance +`voffice1:/root/maas-secrets/admin.pass` -- the `:` class the manifest +format exists for) and `maas-operator-password` (`local`), with a header comment +recording the mint mechanism, the byte format, and the still-un-consolidated +residue (item 7). +**Why:** the manifest is the forcing function -- an undeclared secret is exactly how +the NetBox token went missing. Declaring makes `creds-audit` enforce presence+mode. +**Revert:** `git checkout HEAD -- creds-manifests/vr1-office1.manifest`. + +## Item 4 -- dc0/dc1 manifest BACKFILL -> `creds-audit` CLEAN on all three sites + +**What:** declared the four files that were failing `creds-audit` as UNDECLARED: +dc0 `maas-api-key.txt` + `vr1-dc0-edge_ed25519{,.pub}`, dc1 `maas-api-key.txt`. +Provenance `local` for all four (SEC-018/019 state the API keys were generated FROM +the jumphost so they never persisted on the region; the edge keypair likewise). +**Why:** `creds-audit` was RED on two of three sites at session open (dc0 3 fails, +dc1 1 fail) -- the same convention the operator's task is about, so leaving the gate +red would have been incoherent. The dc0 edge-keypair rows were a KNOWN queued +finding, named in `creds-manifests/vr1-dc1.manifest:18-20` ("dc0 precedent, whose +manifest rows are a queued backfill finding") -- this closes it. +Result: `creds-audit` CLEAN x3 (13/5/8 entries), harness 7/7. +**Revert:** `git checkout HEAD -- creds-manifests/vr1-dc0.manifest creds-manifests/vr1-dc1.manifest` +(returns both sites to FAIL). + +## Item 5 -- SEC-020 opened (register of record) + +**What:** new row in `docs/security-ledger.md` covering (a) the un-consolidated +VM-minted `admin` password + the falsified "no GUI login" claim, (b) the human/service +identity conflation that CAUSED the miss, (c) the new `operator` standing credential. +Status: OPEN -- rotation obligation on TWO region superusers, plus three logged-not- +actioned residues. Open SEC rows 15 -> 16. +**Why:** ledger mandate -- every credential exposure/obligation gets a row, never +only a comment. A new standing credential is a new rotation obligation. +**Revert:** delete the SEC-020 row. + +## Item 6 -- session-ledger: falsified claim corrected + machine block re-seeded + +**What:** (a) struck the 2026-07-25 "IMMEDIATE NEXT" block and annotated it +FALSIFIED + RESOLVED with what was actually true and what was done. (b) Re-seeded the +machine-derived block from a fresh `ledger-scan.sh`: it was stale on EVERY line -- +open SEC 12 -> **16**, next-free D 133 -> **137** / DOCFIX 200 -> **204** / +BUNDLEFIX 052 -> **053**, and D-136 was missing from the open-decision list while +D-071/D-129 were still listed despite being ADOPTED/RESOLVED. +**Why:** (a) GA-R1 -- a falsified claim left standing misdirects the next session, +and this one would have sent it to create an account that already existed. (b) my +SEC-020 changes the count that block carries, so re-seeding is required by this +change, not added scope; the block's own rule is "regenerate, never hand-edit". +**Revert:** `git checkout HEAD -- docs/session-ledger.md`. + +## Item 7 -- Findings LOGGED, not executed (hard rule 1) + +**What:** recorded in SEC-020, no action taken: +- (i) `voffice1:/root/maas-secrets/{admin.apikey,db.pass,lxd-trust.pass}` remain + un-consolidated. `admin.apikey` deliberately NOT copied -- trivially regenerable + (`maas apikey --username=admin`) so a second copy is pure added surface; + `db.pass`/`lxd-trust.pass` are region infrastructure, outside this task's scope. +- (ii) the DURABLE fix for the miss class is a `site-headend-install.sh` amendment to + consolidate at mint time (the script currently leaves all four secrets on the VM). + Queued, unruled -- a script change needs its harness and a ruling. +- (iii) the human/service conflation is proposable as the next-free D-number, [ARCH]: + `admin` is both the GUI login and the automation identity (its API key drives the + `maas admin` CLI profile across **19 call sites in 4 scripts** -- + `site-headend-install.sh` 10, `phase-04-network-verify.sh` 5, + `phase-04-network-create.sh` 3, `phase-00-teardown-release.sh` 1). Roosevelt-delta: + per-identity MAAS separation / audit attribution on a multi-tenant cloud. NOT + assigned -- GA-R3 doubt-resolves-DOWN, operator's call. +**Why:** findings are logged, never executed mid-task. +**Revert:** n/a (records only). + +## Item 8 -- evidence capture + +**What:** `docs/audit/maas-admin-recovery-20260725.txt` -- generated, not +hand-written: user list, Django password-state booleans, both login probes with +wrong-password controls, the sha256 fidelity compare, file modes/sizes, `creds-audit` +x3 + harness, and an automation-unaffected check. Machine-scanned for password bytes +(0 hits) before commit. +**Why:** GA-R1 rule 2 -- claims are quoted from captured command output, never prose. +**Revert:** `git rm docs/audit/maas-admin-recovery-20260725.txt`. + +## Not done / still open + +- `admin`, `juju-vr1-dc0`, `juju-vr1-dc1` passwords UNCHANGED by ruling. The two + `juju-*` passwords remain random + unstored; their API keys are load-bearing for the + blocked Stage-5 bootstrap and `operator` removes any need to log in as them. +- `MAAS` and `maas-init-node` are MAAS-internal accounts -- deliberately untouched + (`maas-init-node` is also `is_active=False`). +- Items 7(i)-(iii) above. +- Pre-existing, NOT touched by this session: CURRENT-STATE G14 SEC count (reads 12, + actual 16) and section 4 ("RULED-BUT-NOT-BUILT", flagged comprehensively stale + 2026-07-25) -- both already operator-deferred to Stage 4 close. diff --git a/docs/security-ledger.md b/docs/security-ledger.md index 4c12636..9573324 100644 --- a/docs/security-ledger.md +++ b/docs/security-ledger.md @@ -33,6 +33,8 @@ | SEC-019 | 2026-07-24 | **Dedicated dc1 MAAS admin API key (Juju -> MAAS cloud credential).** Same as SEC-018 for the vr1-dc1 Juju controller: dedicated MAAS superuser `juju-vr1-dc1`, key staged at `~/vr1-dc1-creds/maas-api-key.txt` on vcloud (0600), generated from the jumphost, format-verified (parts=3, 70 chars), never printed; random unstored password. GRANT: admin-scoped MAAS API. | 2026-07-24 driven creation (as-executed `2026-07-24-dc-maas-creds`); phase-4 Step 2.0; docs/changelog-20260724-caveman-disable.md item 7 | operator | **OPEN -- rotation obligation** (same disposition as SEC-018). **2026-07-24: runtime copy now in Juju's client credential store on voffice1 (`vr1-maas` / `vr1-dc1-cred`); canonical file stays on vcloud.** Roosevelt: per-DC cloud credential. Custody off-repo per D-069. | +| SEC-020 | 2026-07-25 | **MAAS region superuser passwords: an un-consolidated VM-minted secret, plus a new human GUI identity -- and the human/service identity conflation underneath both.** (a) The `admin` superuser's password was minted ON the region VM by `scripts/site-headend-install.sh:452` (`newpass` -> 28 chars alphanumeric, no trailing newline) and sat root-only at `voffice1:/root/maas-secrets/admin.pass` since 2026-07-13, never consolidated to `~/vr1-office1-creds/` -- the SAME SEC-009 miss class the NetBox token established (a site-VM-minted secret with no forcing function to reach the folder). It was NOT lost and NOT unset: MEASURED working this session (login POST 204 with the stored value vs 400 with a wrong-password control; Django `has_usable_password=True`). The prior claim that MAAS web-GUI login "does NOT exist / was never minted" (session-ledger 2026-07-25 close) is FALSIFIED and corrected in the same commit. (b) ROOT CAUSE of the miss: `admin` is simultaneously the human GUI login AND the automation identity -- the installer mints its API key (`:453`) and logs the CLI in as profile `admin` (`:455`), and 19 `maas admin ...` call sites across 4 scripts (`site-headend-install.sh` 10, `phase-04-network-verify.sh` 5, `phase-04-network-create.sh` 3, `phase-00-teardown-release.sh` 1) hardcode that profile. Automation only ever needed the KEY, so nobody ever needed the PASSWORD, so nothing forced it into the folder. (c) NEW standing credential: superuser `operator` (email `jesse.austin@neumatrix.com`) minted 2026-07-25 for HUMAN GUI login, 32-char base64 generated on vcloud, set via **stdin -- never argv** (SEC-018 discipline; note `maas changepassword` has no `--password` and `createadmin --password` would expose it in argv, the shape `site-headend-install.sh:452` uses). Both passwords now at `~/vr1-office1-creds/{maas-admin-password,maas-operator-password}` 0600, declared in `creds-manifests/vr1-office1.manifest`, `creds-audit vr1-office1` CLEAN. | this session (operator-ruled scope: "New account + consolidate only" -- no existing password rotated); measured captures in `docs/changelog-20260725-maas-admin-recovery.md`; `scripts/site-headend-install.sh:452-455` | operator | **OPEN -- rotation obligation on TWO credentials** (`admin` + `operator` region superusers; rotate at v1 close, or immediately if vcloud/the region is rebuilt or shared). `admin`'s password was deliberately NOT rotated this session (operator-ruled) -- so `voffice1:/root/maas-secrets/admin.pass` REMAINS source-of-record and the vcloud file is a byte-identical (sha256-verified) working copy; **any future `admin` rotation MUST update both copies in one operation or the VM copy becomes a stale trap.** ALSO OPEN, un-actioned by ruling (hard rule 1, findings are logged not executed): (i) `voffice1:/root/maas-secrets/{admin.apikey,db.pass,lxd-trust.pass}` are still un-consolidated -- `admin.apikey` is deliberately NOT copied (trivially regenerable via `maas apikey --username=admin`, and a second copy is pure added surface), `db.pass`/`lxd-trust.pass` are region infrastructure and out of this task's scope; (ii) the DURABLE fix for the miss class is a `site-headend-install.sh` amendment to consolidate at mint time (queued, unruled); (iii) the human/service conflation in (b) is proposable as the next-free D-number, tagged [ARCH], a Roosevelt-delta (per-identity MAAS separation / audit attribution on a multi-tenant cloud) -- NOT assigned, GA-R3 doubt-resolves-DOWN, operator's call. Count note: this row takes open SEC rows 15 -> 16; CURRENT-STATE G14 (which still reads 12) reconciles at Stage 4 close per its existing deferral. Custody off-repo per D-069. | + **STANDING CONVENTION (SEC-009, 2026-07-15): per-site credential/env consolidation.** ALL sensitive files AND environment/config files for a site live in a single `~/-creds/` folder on vcloud, mode 0700, files 0600 (public keys 0644). No loose env files in `~`. Sites: `~/vr1-office1-creds/` diff --git a/docs/session-ledger.md b/docs/session-ledger.md index e2eb552..de43b23 100644 --- a/docs/session-ledger.md +++ b/docs/session-ledger.md @@ -30,27 +30,26 @@ ## Machine-derived (re-seed from `scripts/ledger-scan.sh`; do not hand-edit) -_Re-seeded from the 2026-07-23 close scan (post-queue-pass; scanner amendment-attribution -fix verified -- D-132 restored to the list). Re-run `bash scripts/ledger-scan.sh` to refresh._ +_Re-seeded from a 2026-07-25 scan (SEC-020 session; the prior seeding was the 2026-07-23 close and +had gone stale on every line -- counts and next-free both). Re-run `bash scripts/ledger-scan.sh` to refresh._ -- **PROPOSED / OPEN decisions:** D-068 (Vault substrate hardening, Roosevelt), D-071 ADOPTED - 2026-07-21 (all four points ruled -- drops off the scan), D-129 (RESOLVED as a decision 2026-07-21: all four subs ruled -- (i) COS scrapes edge per-DC, - (ii) os-frr to Roosevelt design, (iii) per-site Tailscale = dedicated node not edge, (iv) MAAS - NTP hierarchy stays; office1 live install + qga retrofit remain as G13 execution items; entry - drops off the scan's open list), D-131 (node-facing DNS strategy for - rack-only controllers -- PARTIALLY RULED: sub-1 ruled + delivered 2026-07-21, sub-2 ruled - 2026-07-21 (metal-admin only), sub-3 resolved 2026-07-21 (no defect), sub-4 open + pinned - DNS architectural review; - now surfaced by the scan itself after the PARTIAL fix), D-132 (Roosevelt per-DC MAAS - topology -- PROPOSED 2026-07-21, operator-pinned to the next deployment). Status lines in - `docs/design-decisions.md` are the only ruling authority. -- **OPEN security rows:** 12 open per `bash scripts/ledger-scan.sh` (re-verified at G12 close - 2026-07-23; SEC-013 surface NARROWED 2026-07-21; SEC-015 (transient dc1 edge key on rack, - remediated) + SEC-016 (dedicated dc1 MAAS->libvirt power key, per-DC isolation) OPENED - 2026-07-23, both rotation obligations). The SEC register of record +- **PROPOSED / OPEN decisions (4):** D-068 (Vault substrate hardening, Roosevelt -- sole remainder + is Q2 path selection at Roosevelt Vault design time), D-131 (node-facing DNS strategy for + rack-only controllers [ARCH] -- PARTIALLY RULED: sub-1 ruled + delivered 2026-07-21, sub-2 ruled + 2026-07-21 (metal-admin only), sub-3 resolved 2026-07-21 (no defect), sub-4 open + pinned DNS + architectural review), D-132 (Roosevelt per-DC MAAS topology [ARCH] -- PROPOSED 2026-07-21, + operator-pinned to the next deployment), D-136 (NetBox-coupled per-DC render pipeline for bundle + overlays and tfvars [ARCH] -- PROPOSED 2026-07-25 in Chat, non-gating for the dc1 deploy). + D-071 and D-129 previously listed here are ADOPTED/RESOLVED and correctly drop off the scan. + Status lines in `docs/design-decisions.md` are the only ruling authority. +- **OPEN security rows:** 16 open per `bash scripts/ledger-scan.sh` (re-seeded 2026-07-25). Since the + last seeding this went 12 -> 16: SEC-017 (caveman plugin supply-chain re-verify), SEC-018/-019 + (per-DC MAAS API keys for the Juju cloud credentials), SEC-020 (MAAS region superuser passwords -- + the `admin` un-consolidation + the new `operator` human GUI identity). The SEC register of record is `docs/security-ledger.md`; row-level dispositions live THERE only (GA-R4 amendment F3) -- - this block carries pointer + count, never rows. -- **Next-free numbers:** D = **133**, DOCFIX = **200**, BUNDLEFIX = 052. + this block carries pointer + count, never rows. NOTE the CURRENT-STATE G14 gate row still reads + 12 and is a known-stale surface, deferred to Stage 4 close by its existing deferral. +- **Next-free numbers:** D = **137**, DOCFIX = **204**, BUNDLEFIX = 053. - **Standing numbering rule:** never write an identifier-shaped token (D-/DOCFIX-/BUNDLEFIX-NNN) ABOVE the real high-water mark anywhere in `docs/` or `runbooks/` prose -- historically a decoy token in prose inflated the next-free counter (hardened in DOCFIX-174); the authoring discipline @@ -346,10 +345,20 @@ - Status ONLY in CURRENT-STATE.md. Changelog: docs/changelog-20260724-caveman-disable.md. ## SESSION CLOSE 2026-07-25 -- handoff-pack execution + recon + Chat D-136 coupling (bounded, GA-R4) -- **IMMEDIATE NEXT (do FIRST):** MAAS WEB-GUI login does NOT exist -- SEC-018/019 are API/Juju-only +- ~~**IMMEDIATE NEXT (do FIRST):** MAAS WEB-GUI login does NOT exist -- SEC-018/019 are API/Juju-only keys; the juju-vr1-dc0/dc1 superusers have RANDOM UNSTORED passwords, so the operator is locked out of the MAAS webpage (never minted; no prior task did it). Fix, operator-run on voffice1: - `sudo maas createadmin --username= --email=` (or `maas changepassword `); +SEC row. + `sudo maas createadmin --username= --email=` (or `maas changepassword `); +SEC row.~~ + **-> FALSIFIED + RESOLVED 2026-07-25 (SEC-020).** The premise was wrong: GUI login DID exist. The + `admin` superuser's password was minted 2026-07-13 by `site-headend-install.sh:452` and MEASURED + working this session (login 204 with the stored value vs 400 wrong-password control) -- it was + merely root-only on voffice1 and un-consolidated (the SEC-009 miss class, not a missing account). + Only the two `juju-*` clause was correct. DONE under operator-ruled scope "New account + + consolidate only": `admin` password consolidated byte-identical to `~/vr1-office1-creds/` + (VM copy stays source-of-record, NOT rotated); NEW `operator` superuser minted for human GUI + login (stdin, never argv); dc0/dc1 manifest backfill -> `creds-audit` CLEAN all three sites. + The `juju-vr1-dc0/dc1` passwords remain random+unstored BY RULING -- their API keys are + load-bearing for the blocked Stage-5 bootstrap, and `operator` removes any need to log in as them. - RECORD PHASE DONE + pushed (thru 87cec53): Rulings 1/2/3 (GA-R5 verbatim), D-136 PROPOSED (NetBox render pipeline, opt C, non-gating), DOCFIX-201 (D-020 not D-036, 7 sites)/-202/-203; pack-review committee + Chat open-Q5 (Jenkins IS the runner) folded in. DC0 mirror COMPLETE (949G+342M). lint 0.