Files
cc-ci/JOURNAL-1c.md
autonomic-bot f972bc1dc4
All checks were successful
continuous-integration/drone/push Build is passing
1c/W2: cc-ci-secrets repo created + populated (cert+infra in sops, verified)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:16:58 +01:00

67 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# JOURNAL — Phase 1c (Builder)
Append-only. Each entry: what I did + verifying command/output + next.
## 2026-05-27 — Phase 1c kickoff / orientation
**Context:** Phase 1 closed DONE (1c10fa5; all D1D10 Adversary-PASS, no VETO; Adversary loop
terminated for Phase 1). Starting Phase 1c per `plan-phase1c-full-reproducibility.md`.
**Did:**
- Read the phase plan in full + plan.md §6.1/§7/§9. Verified access & surveyed current state.
- `ssh cc-ci 'hostname && nixos-version && systemctl is-system-running'`
`nixos` / `24.11.20250630.50ab793 (Vicuna)` / `running`. Healthy.
- Surveyed secrets layout:
- `secrets/secrets.yaml` holds 6 infra secrets: test_secret, drone_rpc_secret,
drone_gitea_client_secret, bridge_drone_token, bridge_gitea_token, bridge_webhook_hmac.
- `.sops.yaml`: recipients = `&host` (ssh-to-age of cc-ci ed25519 host key) + `&master`
(off-box recovery, private at `/srv/cc-ci/.sops/master-age.txt`, sandbox-only).
- `modules/secrets.nix`: `defaultSopsFile = ../secrets/secrets.yaml`,
`age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]`.
- Wildcard cert OUT-OF-BAND at `cc-ci:/var/lib/ci-certs/live/{fullchain.pem,privkey.pem}`
(fullchain 2909 B, privkey 227 B → privkey looks like an EC key). `modules/proxy.nix` reconcile
reads it from there and inserts as traefik `ssl_cert`/`ssl_key` swarm secrets; treats a missing
cert as FATAL (operator precondition).
- `flake.nix`: nixpkgs pinned `50ab793`, sops-nix pinned; single local `nixosConfigurations.cc-ci`.
- Tooling note: sandbox host has NO sops/nix/age/ssh-to-age (`which` → only git). sops/age work
must run on cc-ci (has nix + host age key) or via a sops binary fetched there with the master key.
- Bootstrapped Phase-1c state: STATUS-1c.md, BACKLOG-1c.md, JOURNAL-1c.md (this file). REVIEW-1c.md
left for the Adversary (its file per §6.1). Appended Phase-1c decisions to DECISIONS.md.
**Decisions recorded (DECISIONS.md):** secrets linkage = **git submodule** (deviates from the
flake-input default — rationale: no private-repo fetch credential needed at nix-eval on every
rebuild, keeps `defaultSopsFile` a local path = minimal change + trivially byte-identical);
bootstrap key for throwaway = **recovery age key via `sops.age.keyFile`**.
**Next (W2):** create private `recipe-maintainers/cc-ci-secrets`; move secrets + wildcard cert into
sops there as a submodule of the base; wire secrets.nix (cert→`/var/lib/ci-certs/live` via `path=`);
prove byte-identical build + clean switch with TLS from the git cert. Then claim Gate W2.
## 2026-05-27 — W2 step 1: cc-ci-secrets repo created + populated (DONE)
**Did:**
- Created private `recipe-maintainers/cc-ci-secrets` via Gitea API (bot, org admin). HTTP 201, private=True.
- Confirmed cc-ci host SSH key → age identity == `&host` recipient `age1h90utd…`:
`ssh cc-ci 'nix shell nixpkgs#ssh-to-age --command ssh-to-age -i /etc/ssh/ssh_host_ed25519_key.pub'`
→ exact match. So I can decrypt/re-encrypt on cc-ci with the host key (master stays sandbox-only).
- Built `secrets.yaml` on cc-ci (script with file redirections, no key material in argv):
`sops -d` existing 6 secrets → append `wildcard_cert`/`wildcard_key` as YAML block scalars from
`/var/lib/ci-certs/live/{fullchain.pem,privkey.pem}``sops -e`. Verified round-trip:
- recipients: 2 (host+master)
- keys: test_secret, drone_rpc_secret, drone_gitea_client_secret, bridge_drone_token,
bridge_gitea_token, bridge_webhook_hmac, wildcard_cert, wildcard_key
- cert sha256 file==decrypt `c1d96d61…`; key sha256 file==decrypt `9ec25d00…`; test_secret decrypts OK
- Retrieved ciphertext (7219 B) to sandbox; created cc-ci-secrets repo (root `secrets.yaml`, own
`.sops.yaml` w/ `path_regex: secrets\.yaml$`, README). Pushed to main (auth via per-command
http.extraHeader; verified `.git/config` has NO creds). Remote lists .sops.yaml/README.md/secrets.yaml.
- Cleaned `/root/cc-ci-secrets.yaml` + build script off cc-ci.
**Layout decision:** cc-ci-secrets has `secrets.yaml` at ROOT → submodule mounts at base `secrets/`
→ base sees `secrets/secrets.yaml`, so `defaultSopsFile = ../secrets/secrets.yaml` is UNCHANGED.
**Next (W2 step 2):** in base repo — replace tracked `secrets/` with the submodule; add
`wildcard_cert`/`wildcard_key` sops secrets in secrets.nix (path= → /var/lib/ci-certs/live, + recovery
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.)