diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index a31aae4..1103f9c 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -2236,6 +2236,46 @@ NOWHERE (B5 IP-ONLY; R5 refused setting it at Stage 5 as a D-019 repeat), so when Stage 7 turns FQDN endpoints on, both DCs' certs carrying `dc0.vr0` becomes wrong exactly when it starts mattering, and the likely disposition is REISSUE inside D-106's own FQDN-SAN step. +- **`scripts/octavia-pki.sh verify` BUILT 2026-07-29, and the PKI's IDENTITY IS NOW VERIFIED.** + Operator direction: *"Build the verify mode first, then we'll rule the guard fork."* The + script asserts what the runbook only hoped for, and it exists because prose cannot be tested: + F8's paste hazard yields a certificate with NO SANs while every command in the chain prints + OK, and **nothing in this repo asserted the SAN set**. + **SCOPE DELIBERATELY NARROW: `verify` only.** `generate` exits 2 by design -- whether a + sanctioned script may mint is **D-137 open fork 1, UNRULED**, and building it now would + silently convert the PreToolUse guard from "blocks secret minting" into "blocks secret minting + except through any script". That is a posture change reserved to the operator. Recorded also: + this script is the FIRST CONSUMER of the `creds-mint.sh` pattern (D-137 proposal 2(a), + unbuilt, queued by R13), not a rival to it -- if that tool is built it absorbs the generate + half. It CANNOT leak key material by construction (every `openssl` call `-noout`; contents + only counted or pattern-matched; no `cat`, no `base64`), which is what makes it agent-runnable. + **LIVE RESULT, both DCs: 23 assertions PASS, 3 FAIL -- and the 3 are the SAME known E2 mode + defect, nothing else.** Every IDENTITY assertion passes: CA subjects name the correct DC + (`VR1 DC0` / `VR1 DC1`, so `DC_LABEL` was set on both runs -- the unguarded-variable risk did + not bite); the chain verifies against the CONTROLLER CA **and correctly does NOT verify + against the issuing CA**, proving two distinct trust domains rather than only that one link + works; the SAN set carries 2 DNS names plus each DC's OWN provider v4 and v6 VIPs + (`10.12.4.57` + `2602:f3e2:f02:11::57`; `10.12.64.57` + `2602:f3e2:f03:11::57`), so **F8's + failure mode did NOT occur** and the D-109 v6-SAN ruling is satisfied in the artifact; + overlay mode/keys/ASCII/gitignore all pass; and per-DC independence holds. + **THE ONLY OUTSTANDING DEFECT IS E2** -- the three certificates per DC at mode 664. Remediation + is a `chmod`, operator-gated, not yet applied. + **HARNESS 15/15** (`tests/octavia-pki`, manifest 88 -> 89). T1 is the non-zero floor; **T2 is + F8's SAN-less certificate**; T13 guards the OPPOSITE error, since openssl prints v6 SANs + expanded and uppercase while the overlay carries the compressed form and a naive compare would + FAIL a CORRECT cert; T9/T10 prove REFUSE on the wrong host and on an absent binding; T11 proves + an un-generated DC FAILS rather than refusing, because absence there is a conclusive + observation. Host binding is READ from `creds-manifests/host-identity`, so the script cannot + drift from the register. + **A DEFECT THE DELIVERY ITSELF PRODUCED, caught and fixed:** `.gitignore` carried + `octavia-pki/`, which git matches at ANY depth, so it silently swallowed `tests/octavia-pki/` + -- the first commit added the manifest entry and the script but git REFUSED the harness + directory and the commit succeeded anyway. A fresh clone would then have failed the gauntlet on + a harness that was never pushed, and **repo-lint cannot catch it** because the files exist + locally. Anchored to `/octavia-pki/` and verified three ways: the harness is trackable, a + root-level workspace copy is still ignored, and both per-DC overlays remain ignored. Same class + as F4 -- a gitignore pattern whose real scope differed from its intent, this time in the + direction that LOSES data rather than leaks it. **F3 -- both `~/octavia-pki/` and `overlays/octavia-pki.yaml` are ABSENT here** (existence checked, no contents read). So this is generation FROM SCRATCH for both DCs: there is nothing to reuse, which retires the reuse-vs-regenerate choice