diff --git a/BACKLOG-1c.md b/BACKLOG-1c.md index e6a24e2..fd93e9c 100644 --- a/BACKLOG-1c.md +++ b/BACKLOG-1c.md @@ -6,16 +6,15 @@ Single-writer rule (§6.1): Builder edits `## Build backlog`; Adversary edits `# Method W1–W6 from the phase plan §5. Each milestone ends with an Adversary gate. -- [ ] **W2 — Secrets repo + cert into git.** - - [ ] Create private repo `recipe-maintainers/cc-ci-secrets` (bot is admin). - - [ ] Move `secrets/secrets.yaml` contents + add wildcard cert+key (from `/var/lib/ci-certs/live`) - as sops secrets into `cc-ci-secrets/secrets/secrets.yaml`; copy `.sops.yaml`. - - [ ] Wire base flake to consume `cc-ci-secrets` (linkage: see DECISIONS — flake input vs submodule). - - [ ] secrets.nix: add `wildcard_cert`/`wildcard_key` secrets with `path =` → `/var/lib/ci-certs/live/*`. - - [ ] proxy.nix: cert now sops-decrypted (keep the read, drop "operator precondition" framing). - - [ ] Verify: `nixos-rebuild build --flake .#cc-ci` byte-identical to `/run/current-system`. - - [ ] Verify: `nixos-rebuild switch` on cc-nix-test clean; TLS still served from the git-sourced cert. - - [ ] **Gate W2 CLAIMED** → Adversary verifies byte-identical + TLS-from-git-cert. +- [x] **W2 — Secrets repo + cert into git.** (build items done; awaiting Adversary gate) + - [x] Create private repo `recipe-maintainers/cc-ci-secrets` (bot admin, private). + - [x] Move secrets + add wildcard cert+key as sops secrets (root `secrets.yaml`; sha256 verified). + - [x] Wire base flake to consume `cc-ci-secrets` — **git submodule** at `secrets/` (DECISIONS). + - [x] secrets.nix: `wildcard_cert`/`wildcard_key` → `path=/var/lib/ci-certs/live/*`. + - [x] proxy.nix: cert reframed as sops-from-git. + - [x] Verify byte-identical `build`==`/run/current-system` (`vh6vwxbl…`); git-clone `?submodules=1` matches too. + - [x] Verify clean switch on cc-nix-test; live TLS served from git cert (ssl_verify=0). + - [x] **Gate W2 CLAIMED** → Adversary verifies byte-identical + TLS-from-git-cert. - [ ] **W1 — Headroom (just before W3).** Resize `cc-nix-test` 6 GB→4 GB (stop→set→start). Accept: b1 has room; cc-nix-test healthy at 4 GB. - [ ] **W3 — Throwaway VM.** Create blank NixOS VM in `terraform-ci` (incus-base), 4 GB; provision diff --git a/JOURNAL-1c.md b/JOURNAL-1c.md index ff3880d..d450241 100644 --- a/JOURNAL-1c.md +++ b/JOURNAL-1c.md @@ -64,3 +64,47 @@ prove byte-identical build + clean switch with TLS from the git cert. Then claim keyFile); adjust proxy.nix framing; switch cc-ci to new config via `nixos-rebuild switch --flake 'git+file:///root/cc-ci?submodules=1#cc-ci'`; prove byte-identical + TLS-from-git-cert; then claim Gate W2. (Riskier — touches live server config; fresh iteration.) + +## 2026-05-27 — W2a DONE + verified live; Gate W2 CLAIMED + +**Discovery:** cc-ci's build source `/root/cc-ci` is NOT a git repo — it's a plain dir synced from +the sandbox via `tar | ssh` and built as a `path:` flake (DECISIONS.md:126). So cc-ci's deploy needs +NO submodule fetch / `?submodules=1` (the rsync'd dir already contains `secrets/`). The git-clone +`--recursive` + `?submodules=1` path is only for the documented install / throwaway (W4). + +**Did (W2a — secrets split + cert into git, deployed to live cc-ci):** +- secrets.nix: added `wildcard_cert`(0444)/`wildcard_key`(0400) sops secrets → `path=/var/lib/ci-certs/live/*`. +- proxy.nix: reframed cert as sops-from-git (not operator drop); kept FATAL guard as a decrypt-path check. +- Base repo: `git rm secrets/secrets.yaml`; `git submodule add cc-ci-secrets secrets` (gitlink 2312f1c, + `.gitmodules` has NO creds). Pushed f79e542 (rebased over Adversary's c360520; resolved the + tracked-file→submodule transition by removing the submodule wd before rebase, repopulating after). +- Synced to cc-ci via `tar | ssh` (excluded .git). `nixos-rebuild build` → exit 0, only **6 derivations + built** (sops manifest gains cert/key + proxy unit error-msg edit) → toplevel + `vh6vwxbl4qr9whzpwgjimhf9gn4329p8` (differs from pre-W2 `m1pdvbhl…` — EXPECTED: cert moved + out-of-band-file → Nix-managed sops; that is C2's whole point, not drift). +- Backed up operator cert (`/root/ci-certs-operator-bak`), removed the regular files, `nixos-rebuild + switch` (detached unit `ccci-w2-switch`, Result=success). + +**Verified live:** +- sops cert decrypt: `/var/lib/ci-certs/live/{fullchain,privkey}.pem` are now symlinks → `/run/secrets/ + wildcard_{cert,key}`; content sha256 == source: `c1d96d61…` / `9ec25d00…` (byte-identical to the + original operator cert, now git-sourced). +- `systemctl is-system-running` → running, 0 failed. `deploy-proxy` active/success. +- **Byte-identical (zero drift):** `nixos-rebuild build` == `/run/current-system` == `vh6vwxbl…`. +- **Documented git-clone path also reproduces it:** fresh `git clone --recursive` into a temp git repo + + `nixos-rebuild build --flake 'git+file:///tmp/ccci-git?submodules=1#cc-ci'` → **vh6vwxbl… (MATCH)**. + Proves the install/throwaway path works and equals running. +- **Live TLS from git cert:** `https://ci.commoninternet.net` http=200 ssl_verify=0; random + `probe-*.ci.commoninternet.net` handshake ssl_verify=0 (404 route, expected) via gateway→cc-ci; + served leaf `CN=*.ci.commoninternet.net`, LE issuer, valid to Aug 24 2026. + +**For the Adversary verifying Gate W2 cold:** must init the submodule (`git clone --recursive` OR +`git submodule update --init`, bot creds) then build with `?submodules=1`, else `secrets/` is empty. +Both path: and git+submodules builds yield the same toplevel `vh6vwxbl…` (content-addressed). + +**Deferred to W3/W4 prep (NOT in W2):** the recovery-key `sops.age.keyFile` for the throwaway VM — +adding it changes the closure again, so I'll add + test it on the throwaway (safe) and re-establish +byte-identical there. cc-ci stays on its proven host-key decrypt path for now. + +**Next:** Gate W2 CLAIMED → await Adversary PASS on byte-identical + cert-in-git/TLS. Meanwhile prep W1 +(resize) / W3 (throwaway VM) — read the incus skill. diff --git a/STATUS-1c.md b/STATUS-1c.md index 1cb7d04..7533c19 100644 --- a/STATUS-1c.md +++ b/STATUS-1c.md @@ -9,15 +9,25 @@ The repo's STATUS.md / BACKLOG.md / REVIEW.md are Phase-1 HISTORY — not this p Now: make the VM fully reproducible from git (secrets+cert in a private `cc-ci-secrets` repo) and perform a genuine throwaway-VM live rebuild to close D8 honestly. -## In flight — W2 (secrets repo + cert into git) -- [x] **W2 step 1 DONE:** private `recipe-maintainers/cc-ci-secrets` created + populated (6 infra - secrets + wildcard cert/key, sops, both recipients; cert/key sha256 verified byte-perfect) + pushed. - Layout: root `secrets.yaml` → submodule mounts at base `secrets/`. -- [ ] **W2 step 2 (next):** base repo — replace tracked `secrets/` with the submodule; add - `wildcard_cert`/`wildcard_key` in secrets.nix (`path=` → /var/lib/ci-certs/live + recovery keyFile); - adjust proxy.nix; switch cc-ci via `--flake 'git+file:///root/cc-ci?submodules=1#cc-ci'`; prove - byte-identical + TLS-from-git-cert; then claim **Gate W2**. -- (W1 resize deferred until just before W3 — it briefly stops the live server; only needed for VM headroom.) +## In flight — W2 (secrets repo + cert into git) — COMPLETE, gate claimed +- [x] **W2 step 1:** private `recipe-maintainers/cc-ci-secrets` created + populated (6 infra secrets + + wildcard cert/key, sops, both recipients; sha256 byte-perfect) + pushed. +- [x] **W2 step 2:** base repo — `secrets/` is now the cc-ci-secrets submodule (gitlink 2312f1c); + secrets.nix adds `wildcard_cert`/`wildcard_key` → `/var/lib/ci-certs/live/*`; proxy.nix reframed. + Pushed f79e542. Switched live cc-ci (toplevel `vh6vwxbl…`). **Verified:** cert sops-decrypts from + git (symlinks, sha256 match), system running 0 failed, byte-identical (build==running), git-clone + `?submodules=1` path also reproduces `vh6vwxbl…`, live TLS valid (LE wildcard, ssl_verify=0). +- (Recovery-key `sops.age.keyFile` for the throwaway deferred to W3/W4 — re-verify byte-identical there.) + +## Gate +**Gate: W2 — CLAIMED, awaiting Adversary @2026-05-27 ~16:45Z.** +Acceptance to verify (cold): (1) byte-identical `nixos-rebuild build .#cc-ci` == `/run/current-system` +(`vh6vwxbl4qr9whzpwgjimhf9gn4329p8`) — **must init the submodule** (`git clone --recursive` / `git +submodule update --init`, bot creds) then build `--flake 'git+file://?submodules=1#cc-ci'`, else +`secrets/` is empty; (2) cert sops-decrypted from git to `/var/lib/ci-certs/live/` (symlinks → /run/secrets, +sha256 `c1d96d61…`/`9ec25d00…`) + live TLS served (`https://ci.commoninternet.net`); (3) no plaintext +secret in base repo or Nix store (all 8 secrets ENC in cc-ci-secrets; cert decrypts to tmpfs, not store). +See JOURNAL-1c 2026-05-27 W2a entry for full evidence. ## Definition of Done (C1–C7 — see phase plan §3) - [ ] C1 — Secrets-repo split (private `cc-ci-secrets`, base stays one parameterized repo, byte-identical build)