Skip to main content
πŸŽ“ Claude Code Masterclass Learn AI-assisted development on Udemy β€” plus the companion book on Leanpub & Amazon. Start Learning
GitOps Secrets: Sealed Secrets vs SOPS vs External Secrets
DevOps

GitOps Secrets: Sealed Secrets vs SOPS vs External Secrets

Compare three approaches to secrets in GitOps workflows β€” Bitnami Sealed Secrets, Mozilla SOPS with age/KMS, and External Secrets Operator.

LB
Luca Berton
Β· 2 min read

The Problem: Secrets in Git

GitOps means everything in Git. But secrets can’t be stored in plaintext. Three solutions dominate:

SolutionEncryptionKey ManagementGitOps Native
Sealed SecretsAsymmetric (RSA)In-cluster controllerβœ…
SOPSSymmetric (age/KMS)External (AWS KMS, GCP, age)⚠️ (needs decrypt step)
External SecretsNone (reference only)External vaultβœ…

1. Bitnami Sealed Secrets

Encrypts secrets client-side; only the in-cluster controller can decrypt.

# Install controller
helm install sealed-secrets sealed-secrets/sealed-secrets -n kube-system

# Encrypt a secret
kubectl create secret generic db-creds \
  --from-literal=password=super-secret \
  --dry-run=client -o yaml | \
  kubeseal --format yaml > sealed-db-creds.yaml
# This is safe to commit to Git!
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: db-creds
spec:
  encryptedData:
    password: AgBy3i4OJSWK+PiTySYZZA9rO...  # RSA-encrypted

Pros/Cons

βœ… Pros❌ Cons
Simple workflowSecrets re-encrypted per cluster
No external dependenciesKey rotation requires re-seal all
Native K8s Secret outputCan’t use outside Kubernetes
Commit encrypted secrets to GitLosing the private key = lost secrets

2. Mozilla SOPS

Encrypts YAML/JSON values in-place using age, AWS KMS, GCP KMS, or Azure Key Vault.

# Create age key
age-keygen -o key.txt

# Encrypt
sops --encrypt --age age1... secret.yaml > secret.enc.yaml

# Decrypt (CI/CD or Flux)
sops --decrypt secret.enc.yaml | kubectl apply -f -
# Encrypted file β€” keys visible, values encrypted
apiVersion: v1
kind: Secret
metadata:
    name: db-creds
data:
    password: ENC[AES256_GCM,data:kE3l...,type:str]
sops:
    age:
        - recipient: age1...
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----

With Flux CD

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
spec:
  decryption:
    provider: sops
    secretRef:
      name: sops-age  # Age private key stored as K8s secret

Pros/Cons

βœ… Pros❌ Cons
Works anywhere (not K8s-specific)Extra tooling in CI/CD
Multiple key recipientsNeed SOPS binary everywhere
AWS/GCP KMS integrationMore complex key management
Diff-friendly (keys visible)Not native to Argo CD (plugin needed)

3. External Secrets Operator

Doesn’t store secrets in Git at all β€” just references.

# Only the reference is in Git (no secret data)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-creds
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault
  data:
    - secretKey: password
      remoteRef:
        key: production/database
        property: password

Pros/Cons

βœ… Pros❌ Cons
No secrets in Git (even encrypted)Requires external vault
Auto-rotationRuntime dependency on vault
Audit trail in vaultMore infrastructure to manage
Works with any vaultCluster needs vault access

Decision Matrix

RequirementSealed SecretsSOPSExternal Secrets
Small team, simple setupβœ… Best⚠️❌ Overkill
Multi-cloud/multi-clusterβŒβœ…βœ…
Compliance (secret never in Git)βŒβŒβœ… Best
Existing HashiCorp VaultβŒβš οΈβœ… Best
Air-gapped environmentsβœ…βœ…βŒ
Non-Kubernetes workloadsβŒβœ…βŒ

My Recommendation

For most organizations:

  1. Start with Sealed Secrets β€” lowest barrier to entry
  2. Graduate to External Secrets β€” when you have a vault and need rotation
  3. Use SOPS β€” for non-Kubernetes config or multi-tool environments

Free 30-min AI & Cloud consultation

Book Now