# .sops.yaml — SOPS creation rules for the platform repo (ADR-0007, R-SEC-01). # # ───────────────────────────────────────────────────────────────────────────── # EFFECTIVE LOCATION: this file must live at the REPOSITORY ROOT to govern # encryption of secrets under platform/** and apps/**. It is AUTHORED here in # bootstrap/sops/ (the security engineer's subtree); the PM/clusters owner # installs it at the repo root (copy or symlink). See bootstrap/sops/README.md # "Interface / handoff". SOPS discovers .sops.yaml by walking UP from the file # being encrypted to the repo root, so it only takes effect from root. # ───────────────────────────────────────────────────────────────────────────── # # HOW ENCRYPTION WORKS HERE: # - Only committed secrets are encrypted; plaintext never enters git. # - `encrypted_regex` encrypts ONLY the value fields (data/stringData), leaving # keys and structure in cleartext → readable, reviewable diffs (ADR-0007). # - `age` recipient below is the PUBLIC key from age-keygen.sh. Filling it is a # bootstrap step; the matching PRIVATE key is installed in-cluster as the # `sops-age` Secret (age-key-secret.md) so Flux can decrypt at reconcile. # # TO ENCRYPT A SECRET (operator, not agents): # sops --encrypt --in-place path/to/secret.sops.yaml # # picks up the age recipient + rules below automatically. creation_rules: # Platform + app Secrets. Convention: encrypted files are named `*.sops.yaml` # or live under a `secrets/` directory anywhere in the tree. - path_regex: (^|/)(platform|apps|catalog)/.*(secret|sops)\.ya?ml$ encrypted_regex: "^(data|stringData)$" # >>> REPLACE-ME <<< paste the age PUBLIC recipient printed by age-keygen.sh. # Example shape (NOT a real key): age1qy...placeholder...0abcd age: "REPLACE-ME-AGE-PUBLIC-RECIPIENT" - path_regex: (^|/)secrets/.*\.ya?ml$ encrypted_regex: "^(data|stringData)$" # >>> REPLACE-ME <<< same age PUBLIC recipient as above. age: "REPLACE-ME-AGE-PUBLIC-RECIPIENT"