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
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:
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
28
STATUS-1c.md
28
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://<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 (C1–C7 — see phase plan §3)
|
||||
- [ ] C1 — Secrets-repo split (private `cc-ci-secrets`, base stays one parameterized repo, byte-identical build)
|
||||
|
||||
Reference in New Issue
Block a user