- config/cosign/cosign.pub: public verification key committed to repo (safe);
cosign private key lives in /home/roof/.pic-secrets/ and is NEVER committed
- api/config_manager.py: image_verification config block (modes: off|warn|enforce,
default: warn) so existing deployments are unaffected until images are signed
- api/service_composer.py: cosign verify before pull/up; enforce aborts the
operation, warn logs and proceeds, off skips entirely; also fixes the prior
unsafe proceed-on-pull-failure path
- api/service_store_manager.py: store-image digest requirement (warn default,
reject under enforce)
- api/Dockerfile: cosign binary copied from the official cosign image
- docker-compose.yml: config/cosign/ bind-mounted into cell-api container
- install.sh: ensure/verify bundled cosign pubkey on new cell installs
- api/manifest_validator.py: validate_build_context() — Dockerfile lint
- tests: full coverage for config modes, composer verify paths, store digest
guard, and validate_build_context
Verification defaults to warn so nothing breaks in production until images are
signed (phase 2). Private key stored outside git at /home/roof/.pic-secrets/.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>