Secrets: SOPS & Sealed Secrets
Encrypted secrets in Git.
Flux faces the same GitOps secrets problem — no plaintext in Git — and integrates the standard solutions natively. SOPS is first-class: the kustomize-controller can decrypt SOPS-encrypted files at reconcile time using a key it holds (age or a cloud KMS), so encrypted secrets live safely in Git and are decrypted only in-cluster during apply. Sealed Secrets and the External Secrets Operator also work, since Flux just applies whatever CRDs you give it.
apiVersion: kustomize.toolkit.fluxcd.io/v1kind: Kustomizationspec:path: ./appsdecryption:provider: sopssecretRef: { name: sops-age } # the age/KMS key Flux decrypts with# secrets in Git are SOPS-encrypted; Flux decrypts them at apply time only# create the key: `flux create secret` / an age key stored as a Secret
Where the trust sits
With SOPS, the decryption key Flux holds is the crown jewel — anyone with it decrypts every secret, so store it as a tightly-controlled Secret (or, better, keep the key in a cloud KMS Flux calls, so the raw key never sits in the cluster). With External Secrets, the trust moves to the operator’s access to Vault/the cloud store. Either way, the pattern is the same: ciphertext or references in Git, the unlocking key protected and scoped, and plaintext existing only transiently in-cluster.
# encrypt a secret for Git with SOPS (age); Flux decrypts it at reconcile$ sops --encrypt --age $AGE_PUBKEY db-secret.yaml > db-secret.enc.yaml$ git add db-secret.enc.yaml # safe: ciphertext only