diff --git a/docs/changelog-20260724-caveman-disable.md b/docs/changelog-20260724-caveman-disable.md index e811ef2..1b0c5d9 100644 --- a/docs/changelog-20260724-caveman-disable.md +++ b/docs/changelog-20260724-caveman-disable.md @@ -201,3 +201,25 @@ deploy (`juju deploy ./bundle.yaml --overlay ./overlays/vr1-dc1-vips.yaml`). YAML valid (11 apps), repo-lint 0 fail. - Revert: `git revert ` (removes the overlay). No live/cloud state. + +## Item 9 -- Juju client setup on voffice1 (cloud + credentials) [client config, not a cloud mutation] + +- **Juju client location = voffice1** (operator-ruled after reconsideration): the + Office1 headend has a Roosevelt analog and D-128 runs MAAS-facing work there so + runbooks read "from the headend"; vcloud (substrate host) has no Roosevelt + analog, so driving the cloud from it would not transfer. Juju 3.6.25 (3/stable, + matches VR0 + the bundle's Juju 3.6 target) installed on voffice1; removed from + vcloud. +- `juju add-cloud --client vr1-maas` -- the ONE Office1 MAAS region + (type=maas, endpoint `http://10.10.0.20:5240/MAAS`). `juju add-credential` + both DCs: `vr1-dc0-cred` + `vr1-dc1-cred` from the staged keys, piped + vcloud->voffice1 into a home-dir yaml (snap can't read /tmp), never printed, + `shred -u`'d. Juju credential store on voffice1 now holds runtime copies (noted + on SEC-018/-019; canonical files stay on vcloud). Credentials validate at + bootstrap (juju does not pre-validate). +- Two snap gotchas measured + worked around: the juju snap has a private /tmp + (stage bundle/overlay/cred files under $HOME); voffice1 ssh sessions have + per-session /tmp. Both relevant to the deploy steps. +- Revert: `ssh voffice1 'juju remove-credential vr1-maas vr1-dc0-cred; juju + remove-credential vr1-maas vr1-dc1-cred; juju remove-cloud --client vr1-maas'`; + `git revert ` for the SEC/changelog rows. diff --git a/docs/security-ledger.md b/docs/security-ledger.md index a322b46..4c12636 100644 --- a/docs/security-ledger.md +++ b/docs/security-ledger.md @@ -29,9 +29,9 @@ | SEC-017 | 2026-07-24 | **Third-party Claude Code plugin `caveman@caveman` (JuliusBrussee/caveman) installed at USER scope on vcloud -- a standing per-session/per-prompt third-party code-execution surface on a credential-bearing jumphost.** SessionStart + UserPromptSubmit hooks run `node` on every session start and every prompt while `enabledPlugins` is true, INDEPENDENT of the `CAVEMAN_DEFAULT_MODE` guard (the env var gates terse-output ARMING, NOT hook EXECUTION). Inspected benign at SHA `0d95a81` by a 4-seat council audit + operator self-remeasure 2026-07-24: no network egress, no shell, one gated subprocess (`/caveman-stats` only), symlink-hardened flag I/O, zero PATH contribution/shadowing. This verdict is POINT-IN-TIME: `plugin.json` carries no `version` field (every git commit is a new "version"), the marketplace source tracks the default branch with no tag/SHA ref -> the code is NOT declaratively pinnable; third-party-marketplace auto-update is OFF by default (Claude Code 2.1.218) but flippable via the `/plugin` UI or managed settings. Baseline: git clone HEAD `0d95a81d35a9f2d123a5e9430d1cfc43d55f1bb0` (tree clean), executing cache copy == clone (only a `.in_use` runtime marker differs); 6 audited files' full sha256 recorded in the 2026-07-24 changelog. | docs/changelog-20260723-caveman-optin-guard.md (commit 338c919); docs/changelog-20260724-caveman-disable.md; this session's council audit | operator | **OPEN -- supply-chain re-verify obligation (NOT a credential rotation).** DISABLED on the live host 2026-07-24: `enabledPlugins."caveman@caveman"=false` at BOTH user (`~/.claude/settings.json`) and committed repo (`.claude/settings.json`, higher precedence) scope, `CAVEMAN_DEFAULT_MODE=off` retained -- this STOPS the per-turn hook execution from the next session start. Marketplace entry RETAINED so a deliberate re-enable for hardened-workflow deployment TESTING stays possible. STANDING DUTY: on ANY re-enable OR plugin update, RE-VERIFY the hooks against the baseline (confirm the clone is at `0d95a81`; re-hash + `diff` the cache copy vs the marketplace clone) BEFORE trusting -- the benign verdict does not survive a version bump. Keep-available-vs-uninstall decision DEFERRED (NOT yet ruled). Provenance for the disable: operator accepted the council-review recommendations this session (exact utterance: "I'll accept your recommendations"). Register note: OPS adoption, no D-number (GA-R3 -- no Roosevelt-delta; precedent D-129); this row is the durable home the ledger mandate requires ("row at discovery, never only a note"). Count note: this row takes open SEC rows 12 -> 13; CURRENT-STATE G14 reconciles the count at Stage 4 close per its existing deferral pattern. | -| SEC-018 | 2026-07-24 | **Dedicated dc0 MAAS admin API key (Juju -> MAAS cloud credential).** Created so the vr1-dc0 Juju controller can authenticate to the Office1 MAAS region (bootstrap + provision dc0 nodes). Per-DC credential isolation (SEC-012/-016 pattern; NEVER a cross-DC key): dedicated MAAS superuser `juju-vr1-dc0`, its API key staged at `~/vr1-dc0-creds/maas-api-key.txt` on vcloud (SEC-009, 0600), generated FROM the jumphost so it never persisted on the region, verified by FORMAT ONLY (parts=3, 70 chars), never printed/echoed/in argv. The user's password is random + UNSTORED (Juju auths via the key). GRANT: admin-scoped MAAS API (full machine/power/deploy). | 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.** Rotate at v1 close, or immediately if it leaks or the region/jumphost is rebuilt/shared. Note it also lands in whatever Juju add-credential store + the maas-provider state of any root that consumes it (same 0600 handling). Roosevelt: per-DC cloud credential. Custody off-repo per D-069. | +| SEC-018 | 2026-07-24 | **Dedicated dc0 MAAS admin API key (Juju -> MAAS cloud credential).** Created so the vr1-dc0 Juju controller can authenticate to the Office1 MAAS region (bootstrap + provision dc0 nodes). Per-DC credential isolation (SEC-012/-016 pattern; NEVER a cross-DC key): dedicated MAAS superuser `juju-vr1-dc0`, its API key staged at `~/vr1-dc0-creds/maas-api-key.txt` on vcloud (SEC-009, 0600), generated FROM the jumphost so it never persisted on the region, verified by FORMAT ONLY (parts=3, 70 chars), never printed/echoed/in argv. The user's password is random + UNSTORED (Juju auths via the key). GRANT: admin-scoped MAAS API (full machine/power/deploy). | 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.** Rotate at v1 close, or immediately if it leaks or the region/jumphost is rebuilt/shared. Note it also lands in whatever Juju add-credential store + the maas-provider state of any root that consumes it (same 0600 handling). **2026-07-24: a runtime copy now lives in Juju's client credential store on voffice1 (`~/.local/share/juju/credentials.yaml`, cloud `vr1-maas`, credential `vr1-dc0-cred`) -- the canonical file stays on vcloud; this is the operator-noted consequence of running the Juju client on the headend (voffice1) per D-128.** Roosevelt: per-DC cloud credential. Custody off-repo per D-069. | -| 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). Roosevelt: per-DC cloud credential. Custody off-repo per D-069. | +| 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. | **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,