diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index ba11311..bf1bb32 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -1056,12 +1056,18 @@ files now 0600 and the E2 finding cleared. **SEVERITY CORRECTED first:** the row's original "group- and world-readable" overstated it -- `opentofu/` is 0700 and `~` is 0750, so no other account could traverse to it, and neither file is git-tracked, so - SEC-004 was never implicated. It was defence-in-depth, not live exposure. The RETENTION - question on the two `pre-*` state-surgery snapshots is operator-DEFERRED to stage close - (both gates CLOSED, but deletion is irreversible with no other copy of that state). The - umask CAUSE was out of ruled scope, so a future apply may rewrite 0664 -- P5 will catch - it. The key reaching state files in plaintext at all remains DOCFIX-175, rotation owed - under SEC-018/-019. + SEC-004 was never implicated. It was defence-in-depth, not live exposure. **The RETENTION + question is RULED 2026-07-27 (GA-R5). Question as presented: whether to delete both + `pre-*` state-surgery snapshots (cleanest, closes SEC-024 fully), keep both and let P5 + keep watching them, or keep `pre-G6` and delete `pre-G16`; noting both gates are CLOSED, + both carry the MAAS API key in plaintext per DOCFIX-175, and deletion is irreversible + with no other copy of that pre-surgery state. Operator answer, exact utterance: "Keep + both".** So `terraform.tfstate.pre-G6-20260719` and `.pre-G16-20260721` are RETAINED as + the only record of what the state looked like before the two direct tfstate edits; both + are 0600 and neither is git-tracked. SEC-024 stays OPEN as a standing WATCH rather than + an open remediation: its mode defect is remediated, but the umask CAUSE was out of ruled + scope, so a future apply may rewrite 0664 -- P5 is the detection. The key reaching state + files in plaintext at all remains DOCFIX-175, rotation owed under SEC-018/-019. **STILL OUTSTANDING (not done, not silently dropped):** ruling 1's TIER 2 remote `Pn` (tier 1 + tier-2-local ARE wired -- see the tier-2 gate block below); `--render`'s source-field derivation and the manifest flip to generated output; and the `cardinality` diff --git a/docs/changelog-20260727-creds-consolidation.md b/docs/changelog-20260727-creds-consolidation.md index e3bcd27..98c8fdb 100644 --- a/docs/changelog-20260727-creds-consolidation.md +++ b/docs/changelog-20260727-creds-consolidation.md @@ -385,6 +385,23 @@ auto-created empties, and 192.168.1.0/24 was a superseded factory address. The nginx purge reverts with `apt-get install nginx` (dc1 has no use for it while it is the proxy DC). +## 11. SEC-024 retention RULED -- keep both state-surgery snapshots + +**RULING (GA-R5), 2026-07-27.** Question as presented: delete both `pre-*` state-surgery +snapshots (cleanest, closes SEC-024 fully), keep both and let P5 keep watching them, or keep +`pre-G6` and delete `pre-G16` -- noting both gates are CLOSED, both carry the Office1 MAAS API +key in plaintext per DOCFIX-175, and deletion is irreversible with no other copy of that +pre-surgery state. Operator answer, exact utterance: **"Keep both"**. + +`opentofu/terraform.tfstate.pre-G6-20260719` and `.pre-G16-20260721` are RETAINED at 0600, +neither git-tracked, as the only record of what the state looked like before the two direct +tfstate edits (G6 autostart injection, G16 `channels = []`). + +SEC-024 therefore stays **OPEN as a standing WATCH, not an open remediation**: its mode defect +is fixed, but the umask CAUSE was out of ruled scope, so a future apply may rewrite 0664 and +preflight P5 is the detection. Recorded in both the SEC-024 disposition cell and CURRENT-STATE. +Open SEC count unchanged at 21. + --- ## Findings LOGGED, not actioned (hard rule 1) diff --git a/docs/security-ledger.md b/docs/security-ledger.md index 7de158d..a0ffb3a 100644 --- a/docs/security-ledger.md +++ b/docs/security-ledger.md @@ -41,7 +41,7 @@ | SEC-023 | 2026-07-25 | **Sprawl detection has systematic blind spots, and one exposure is already PREDICTED for Stage 5.** `scripts/creds-audit.sh:72-73` sprawl-globs exactly `*.env`, `.*.env`, `*appcred*`, `*-cred*.txt`, `*authkey*`, `*.token`. That set misses whole file classes this repo actually uses: `admin.pass`, `*.apikey`, `*.key`, `*.pem`, `*_ed25519`, and `maas-api-key.txt` (which is manifest-declared in TWO sites yet would not be caught loose). PREDICTED EXPOSURE: `scripts/phase-03-admin-openrc.sh:32` writes `RC="${RC:-$HOME/admin-openrc}"` and `:72` writes `export OS_PASSWORD='$ADMIN_PASS'` into it -- a credential-bearing file in the HOME ROOT, outside any `*-creds/` folder, whose filename matches NONE of the sprawl globs. It does not exist yet (Stage 5 has not run), so no discovery sweep can flag it today; it is recorded here in advance so the mint is not missed when Stage 5 executes. NOTE the keystone admin password is CHARM-generated but OPERATOR-materialized (`:52` extracts it via `juju run keystone/leader get-admin-password`) -- the operator-ruled "materialization test" puts it firmly in scope. | measured read-only this session; `scripts/creds-audit.sh:72-73`; `scripts/phase-03-admin-openrc.sh:32,52,72`; D-137 research finding F4 | operator | **OPEN -- latent, becomes live at Stage 5.** Two remediations, both UNRULED and NOT built: widen the sprawl globs (cheap, independent of D-137), and add an expected-state row so the openrc credential is asserted rather than discovered. Until then, whoever runs Stage 5 phase-03 must consolidate `~/admin-openrc` into the site creds folder BY HAND at mint time. Count note: SEC-021/-022/-023 take open SEC rows 16 -> 19. Custody off-repo per D-069. | -| SEC-024 | 2026-07-26 | **`opentofu/terraform.tfstate.backup` carries the Office1 MAAS API key in PLAINTEXT at file mode 0664.** SEVERITY CORRECTED 2026-07-26 (measured, same day the row was opened): the original wording called it "group- and world-readable", which overstated it. The FILE BITS are 0664, but `opentofu/` is **0700** and `~` is 0750, so no other account can traverse to it and it is NOT effectively readable today. This is a DEFENCE-IN-DEPTH defect -- one `chmod` on the directory, a `cp -p` elsewhere, or an archive/extract would expose it -- not a live exposure. DOCFIX-175 records that `maas_api_key` reaches the OpenTofu state file in clear; the live `terraform.tfstate` is correctly 0600, but its automatically-written `.backup` sibling is 0664. MEASURED `stat -c '%n %a'` this session on the jumphost clone. FOUND BY the D-137 credential matrix on its first run after the committee fixes: the world-readable check had been gated to `custody=consolidated` rows (43 of 77 rows unchecked), and the tfstate siblings were not declared locations at all -- so neither the mode nor the file was visible to any control. Of the two `terraform.tfstate.pre-*` snapshots, `pre-G16-20260721` is also 0664 and `pre-G6-20260719` is 0600 -- an inconsistency consistent with an accidental umask at write time rather than a deliberate mode. Neither snapshot nor the backup is git-TRACKED (both match `.gitignore:72-73`), so SEC-004's public-repo exposure is NOT implicated. Other accounts exist on the host (`logxen` uid 1000, `libvirt-qemu`), which is why the directory mode is the only thing standing between them and the key. | measured 2026-07-26; `creds-matrix.py --tier2` E2 WORLD-READABLE; DOCFIX-175; capture `docs/audit/d137-tier2-postcommittee-20260726.txt` | operator | **OPEN -- logged, NOT actioned (hard rule 1).** Remediation is a `chmod` on the jumphost plus a decision about whether the historical snapshots should be retained at all; both are mutations and neither is in this step's scope. Rotation of the underlying key remains the SEC-018/-019 obligation. Custody off-repo per D-069. | +| SEC-024 | 2026-07-26 | **`opentofu/terraform.tfstate.backup` carries the Office1 MAAS API key in PLAINTEXT at file mode 0664.** SEVERITY CORRECTED 2026-07-26 (measured, same day the row was opened): the original wording called it "group- and world-readable", which overstated it. The FILE BITS are 0664, but `opentofu/` is **0700** and `~` is 0750, so no other account can traverse to it and it is NOT effectively readable today. This is a DEFENCE-IN-DEPTH defect -- one `chmod` on the directory, a `cp -p` elsewhere, or an archive/extract would expose it -- not a live exposure. DOCFIX-175 records that `maas_api_key` reaches the OpenTofu state file in clear; the live `terraform.tfstate` is correctly 0600, but its automatically-written `.backup` sibling is 0664. MEASURED `stat -c '%n %a'` this session on the jumphost clone. FOUND BY the D-137 credential matrix on its first run after the committee fixes: the world-readable check had been gated to `custody=consolidated` rows (43 of 77 rows unchecked), and the tfstate siblings were not declared locations at all -- so neither the mode nor the file was visible to any control. Of the two `terraform.tfstate.pre-*` snapshots, `pre-G16-20260721` is also 0664 and `pre-G6-20260719` is 0600 -- an inconsistency consistent with an accidental umask at write time rather than a deliberate mode. Neither snapshot nor the backup is git-TRACKED (both match `.gitignore:72-73`), so SEC-004's public-repo exposure is NOT implicated. Other accounts exist on the host (`logxen` uid 1000, `libvirt-qemu`), which is why the directory mode is the only thing standing between them and the key. | measured 2026-07-26; `creds-matrix.py --tier2` E2 WORLD-READABLE; DOCFIX-175; capture `docs/audit/d137-tier2-postcommittee-20260726.txt` | operator | **OPEN -- logged, NOT actioned (hard rule 1).** Remediation is a `chmod` on the jumphost plus a decision about whether the historical snapshots should be retained at all; both are mutations and neither is in this step's scope. Rotation of the underlying key remains the SEC-018/-019 obligation. **RETENTION RULED 2026-07-27 (GA-R5) -- question as presented: delete both `pre-*` state-surgery snapshots, keep both, or keep `pre-G6` and delete `pre-G16`, noting both gates are CLOSED and deletion is irreversible with no other copy of that pre-surgery state. Operator answer, exact utterance: "Keep both".** Both snapshots are RETAINED at 0600, neither git-tracked, as the only record of state prior to the two direct tfstate edits (G6 autostart, G16 channels). This row therefore stays OPEN as a standing WATCH, not an open remediation: the mode defect is fixed, but the umask CAUSE was out of ruled scope so a future apply may rewrite 0664 -- preflight P5 is the detection. Custody off-repo per D-069. | | SEC-025 | 2026-07-27 | **NetBox web-GUI `admin` password consolidated to the jumphost -- a HUMAN GUI login that had never left the VM it was minted on.** Found by the 2026-07-27 consolidation audit, which enumerated the accounts that ACTUALLY EXIST instead of the ones the register already knew about. The password was minted on `office1-netbox` at stage 2 (`operator-terminal`, no repo mint command -- research FINDING 1 class) and sat ONLY at `/root/netbox-secrets/admin.pass` (0600, root-owned, 28 bytes). This is the THIRD instance of one miss class: the founding SEC-009 defect (`api.token`), SEC-020 (`admin.pass` for MAAS), and now this -- a VM-minted human credential with no forcing function to reach the operator's folder, so the human who needs it cannot find it and no audit reports it missing. It was structurally invisible: the matrix carried the row as `off-manifest-known`, which asserts nothing about the jumphost. REMEDIATED THE SAME DAY (this row is opened for the exposure the remediation CREATES, not for the gap it closed): a byte-identical copy now sits at `~/vr1-office1-creds/netbox-admin-password` (0600 in a 0700 dir), sha256-verified at both ends, value never printed or echoed. The VM copy REMAINS source-of-record. | 2026-07-27 consolidation audit, capture `docs/audit/creds-consolidation-audit-20260727.txt`; matrix rows `netbox-admin` (netbox=source-of-record, jumphost=verbatim-copy); `creds-manifests/vr1-office1.manifest` | operator | **OPEN -- rotation obligation + a stale-copy hazard.** (1) ROTATE at v1 close, or immediately if the jumphost is rebuilt or shared -- the same obligation SEC-007 and SEC-020 carry for the other consolidated human passwords. (2) STALE-COPY HAZARD: two copies now exist and nothing keeps them in step, so any future rotation MUST update BOTH or the jumphost copy becomes a trap that reads healthy -- identical to the caveat SEC-020 records for `maas-admin-password`. D-137 tier 3 (V1) now asserts byte-identity between them, so a divergence is at least DETECTABLE, which it was not before. (3) Distinct identity from `netbox-secret-key` (a service secret) and from the two NetBox API tokens -- do not merge them; note SEC-006's upstream token is separately declared burned with revocation ruled-deferred. Custody off-repo per D-069. |