railiance-infra/docs/sops-rotation.md
codex 9886567b40
Some checks failed
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
CI Smoke / source-contract (push) Has been cancelled
Fix rotation review evidence and reconcile blocked S1 workplans
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e3b9-b19e-7ba1-9eb4-4faea76af3ea
2026-09-27 18:47:55 +02:00

1.6 KiB

Bounded SOPS Recipient Rotation

The default operation is metadata-only and does not decrypt values:

python3 scripts/sops_rotation.py --check

It compares each protected file's public age-recipient metadata with the first matching rule in .sops.yaml. CI runs this check to detect recipient drift. The JSON output includes the exact file paths, ciphertext SHA-256 hashes, and before/after recipient sets. Run without --check to inspect proposed drift.

An attended non-printing decryption check may emit a receipt:

python3 scripts/sops_rotation.py --check --verify-decryption \
  --receipt reports/sops-rotation-check.json

Decrypted bytes go directly to the null device. They are not retained in the receipt or command output.

Actual key updates require --apply and an approval YAML containing approved: true, approved_by, approved_at, and an exact changes list from the current plan (including each changed file's sha256). The command fails if that list differs from current metadata or the reviewed ciphertext has changed. Applied receipts retain the reviewed before/after recipient sets and original ciphertext hash, plus after_sha256 for the resulting ciphertext. Review and preserve recovery-key custody before approving recipient removal. Start from docs/sops-rotation-approval.example.yaml; the committed example is deliberately unapproved and contains no usable recipient.

Rollback is a reviewed restoration of the prior .sops.yaml recipient set followed by the same exact-plan approval, sops updatekeys, and non-printing decryption verification. Git history alone is not recovery-key custody.