feat(security): enforce declared cosign image signatures at the pull sites
New container::image_verify gates PodmanClient::pull_image and the dev-only DockerRuntime::pull_image. Signature claims classify three ways: absent/empty (pull unverified, logged), the literal 'cosign://...' placeholder every fleet manifest carries today (same — enforcement stays dormant until the signing ceremony ships real values), or a declared signature, which must verify via 'cosign verify --key /etc/archipelago/cosign.pub --insecure-ignore-tlog=true' (plus --allow-insecure-registry --allow-http-registry for the HTTP mirror; flags checked against cosign's own docs) before anything is fetched. Missing key, missing cosign binary, timeout, or verification failure all hard-fail the pull — a declared signature cannot be skipped on either runtime. Key path overridable via ARCHIPELAGO_COSIGN_PUBKEY for tests/staging. Deletes security::ImageVerifier: zero callers, blocking std::process::Command on would-be async paths, and a fantasy 'cosign verify --signature' invocation (that flag belongs to verify-blob). Activation ships with the Workstream B ceremony, in order: pin cosign.pub on nodes + install cosign, then publish real image_signature values in the catalog. Tests: archipelago-container 58/58 (5 new), archipelago container:: 159/159, security check clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
2c8c99fd28
commit
eed830e1ee
@@ -58,11 +58,19 @@ arbitrary app catalog to the entire fleet — fully unattended under
|
||||
`scripts/sign-manifest.sh` exists for re-signs. **Still open:** move the mirror
|
||||
to HTTPS + pinned cert (tracked with the next item); flip unsigned-manual-apply →
|
||||
hard-reject once the fleet is on a pinned-anchor binary.
|
||||
- [ ] 🔴 **Implement container image signature verification (cosign).**
|
||||
`container/src/podman_client.rs:255` — `pull_image(.., _signature)` silently discards
|
||||
the signature that the manifest threads all the way down
|
||||
(`prod_orchestrator.rs:1978/2435`). Wire `sigstore-rs`/`cosign verify` (or
|
||||
`podman pull --signature-policy`); hard-fail when a declared signature doesn't verify.
|
||||
- [x] 🔴 **Implement container image signature verification (cosign).** DONE 2026-07-04
|
||||
(code path; enforcement dormant until the ceremony): new `container::image_verify`
|
||||
gates BOTH pull sites (`PodmanClient::pull_image` + the dev-only `DockerRuntime`).
|
||||
Claims classify as None / the literal `cosign://...` placeholder (every fleet
|
||||
manifest today → pull proceeds, logged) / Declared → `cosign verify --key
|
||||
/etc/archipelago/cosign.pub --insecure-ignore-tlog=true` (+ both insecure-registry
|
||||
flags for the HTTP mirror; flags verified against cosign docs), hard-fail on missing
|
||||
key, missing cosign binary, timeout, or bad signature — a declared signature can
|
||||
never be skipped, on either runtime. Key path overridable via
|
||||
`ARCHIPELAGO_COSIGN_PUBKEY`. Deleted the caller-less, blocking, wrong-CLI
|
||||
`security::ImageVerifier`. **Activation = ceremony work**: pin cosign.pub on nodes +
|
||||
install cosign + publish real `image_signature` values (in that order); tracked with
|
||||
the Workstream B signing ceremony item.
|
||||
- [ ] 🟠 **Move the image mirror to HTTPS; drop `--tls-verify=false`.**
|
||||
`podman_client.rs:641` `INSECURE_REGISTRY_HOSTS = ["146.59.87.168:3000"]` +
|
||||
`config.rs:104,124` allowlist pull images over unauthenticated HTTP. Remove the raw-IP
|
||||
|
||||
Reference in New Issue
Block a user