boma/docs/security/service-checklist.md
sjat 2f4218814a Reconcile image pinning to a tiered tag@digest rule
Resolve the conflict between ADR-011 (tags-not-digests) and the security work
(digest pinning) with one coherent rule that respects ADR-011's stateless/stateful
split:

- Stateful → pin `tag@digest` (readable tag + integrity digest): legible diffs AND
  tamper-evidence. Snapshots cover broken updates; the digest covers swapped images.
- Stateless → rolling tags (latest/stable); digest-pinning would defeat the rolling
  design. Integrity rests on official/verified images + disposability.

Aligned across ADR-011 (decision 2), ADR-004 (image management), ADR-002
(supply-chain row), accepted-risk R1, the service checklist, and TODO 15.6.
TODO 16.7 marked decided.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 19:21:36 +02:00

2.4 KiB

Per-service security checklist

The bar every service (a per-service role — ADR-004) must clear before deploy, especially anything reachable beyond its own host. Established by ADR-002 (Security baseline and strategy); referenced from docs/runbooks/new-role.md. Enforced manually in review today; the planned /security-review skill (see docs/TODO.md) will automate the check.

Treat each item as must-pass unless a deviation is recorded in docs/security/accepted-risks.md with a rationale and a revisit trigger.

This checklist is the generic bar. Each service answers it in its own roles/<service>/SECURITY.md (the "Checklist status" section), created from docs/security/service-security-template.md — see ADR-004.

Secrets & credentials

  • All secrets live in an encrypted vault.yml (vault.<service>.<key>); none in plaintext files, templates, or Compose env literals
  • No default or vendor-shipped credentials remain — admin passwords/tokens are generated and stored in vault
  • Nothing secret is baked into an image or committed to git (gitleaks must pass)

Least privilege

  • Container runs as a non-root user where the image supports it
  • No privileged: true and no host network mode unless explicitly justified
  • Only the volumes/paths the service needs are mounted; read-only where possible
  • Linux capabilities dropped to what's required (no blanket grants)

Network & exposure

  • Every listening port is declared in group_vars firewall definitions — never opened ad-hoc on a host
  • The service is not published directly to a LAN/WAN port if it can sit behind the reverse proxy instead
  • Anything reachable beyond the srv VLAN is behind the reverse proxy with authentication (and TLS)
  • Inter-service reach follows least privilege — no broad srvsrv access where a single declared dependency suffices

Updates & provenance

  • Image pinned per ADR-011's tiered rule — stateful: tag@digest; stateless: rolling tag (latest/stable) acceptable
  • The update path is known — how this service gets patched

Operability (security-adjacent)

  • Logs go somewhere reviewable (central aggregation when available)
  • Backup/restore is covered if the service holds state

Deviations are allowed but must be conscious: record them in docs/security/accepted-risks.md, don't leave them implicit.