1c/W2a DONE: secrets-split + cert-in-git deployed to live cc-ci; Gate W2 CLAIMED
All checks were successful
continuous-integration/drone/push Build is passing

Submodule mount, cert sops-decrypted to /var/lib/ci-certs/live (sha256 verified), byte-identical
build==running (vh6vwxbl), git-clone+?submodules=1 reproduces it, live TLS valid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 16:47:16 +01:00
parent f79e542149
commit faa3709084
3 changed files with 72 additions and 19 deletions

View File

@ -6,16 +6,15 @@ Single-writer rule (§6.1): Builder edits `## Build backlog`; Adversary edits `#
Method W1W6 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

View File

@ -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.

View File

@ -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://<clone>?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 (C1C7 — see phase plan §3)
- [ ] C1 — Secrets-repo split (private `cc-ci-secrets`, base stays one parameterized repo, byte-identical build)