How do you integrate Helm with secrets management using the helm-secrets plugin, SOPS, and External Secrets Operator, and when should each approach be used?
Quick Answer
The helm-secrets plugin with SOPS encrypts values files at rest so secrets can be committed to Git safely, while External Secrets Operator synchronizes secrets from external stores like Vault or AWS Secrets Manager into Kubernetes Secrets that Helm charts reference. Use helm-secrets for small teams with GitOps workflows and External Secrets Operator for enterprise environments where a central secrets management platform already exists.
Detailed Answer
Think of two ways to send a confidential letter. The first is putting the letter in a locked envelope that only the recipient can open — this is helm-secrets with SOPS, where the secret is encrypted in the file itself. The second is sending a reference card that says 'go to the vault on Floor 3 and ask for Document #4782' — this is External Secrets Operator, where the Kubernetes cluster fetches the actual secret from an external vault at runtime. Both deliver the secret, but the trust model, rotation story, and operational complexity differ significantly.
The helm-secrets plugin wraps Helm commands to transparently decrypt SOPS-encrypted values files during install or upgrade. SOPS (Secrets OPerationS) encrypts individual YAML values while leaving keys readable, using encryption backends like AWS KMS, GCP KMS, Azure Key Vault, or PGP keys. Developers edit secrets with helm secrets edit secrets.yaml, which decrypts in a temporary file, opens an editor, and re-encrypts on save. The encrypted file is committed to Git, and CI/CD pipelines decrypt using IAM roles or service account keys that have access to the KMS key.
External Secrets Operator takes a fundamentally different approach. Instead of encrypting secrets in Git, it deploys a Kubernetes controller that watches ExternalSecret custom resources. Each ExternalSecret specifies a SecretStore (like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault), a remote key path, and a target Kubernetes Secret name. The operator polls or watches the external store and creates or updates the Kubernetes Secret automatically. Helm charts simply reference the Kubernetes Secret by name without knowing where the value originates. This separates secret lifecycle from chart lifecycle entirely.
At production scale, the choice depends on organizational maturity. Helm-secrets with SOPS works well for teams of 5-20 engineers with a strong GitOps culture — everything is in Git, audit trails come from commit history, and rotation means re-encrypting and committing. External Secrets Operator is better for enterprises with hundreds of engineers, centralized security teams, and existing investments in Vault or cloud-native secrets managers. It supports automatic rotation without redeploying charts, cross-cluster secret synchronization, and integration with secrets management policies that predate Kubernetes adoption. Many organizations use both: SOPS for non-sensitive configuration that benefits from Git history, and ESO for high-value credentials like database passwords and API keys.
The non-obvious gotcha with helm-secrets is that decrypted values exist briefly on disk or in environment variables during CI/CD execution, creating a window where secrets can leak into build logs or artifact caches. With External Secrets Operator, the gotcha is that the operator itself becomes a critical dependency — if it fails, secrets stop refreshing, and new deployments that need freshly created Secrets will fail. Architects should monitor ESO reconciliation errors, set refreshInterval appropriately to balance freshness against API rate limits on the secrets backend, and ensure the operator has HA with multiple replicas.