In this lesson, you will learn how to transition from insecure environment variables to production-grade secret injection using Sealed Secrets and External Secrets within a GitOps workflow.
Managing sensitive data like database passwords or API keys in a GitOps repository creates a significant security dilemma: you want your configuration to be declarative and version-controlled, but you must never store plaintext secrets in Git. To solve this across multiple environments (e.g., staging vs. production), we move away from manually creating Kubernetes Secret objects and toward automated secret injection.
Sealed Secrets: Encrypted GitOps
The Sealed Secrets approach uses a controller running in your cluster and a client-side CLI tool (kubeseal). You take your raw secret manifest and encrypt it into a SealedSecret custom resource.
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-credentials
spec:
encryptedData:
password: AgBf... # This can be safely pushed to Git
Because the encrypted payload is tied to the specific cluster's public key, even if your Git repo is compromised, the data remains useless. The controller in the target cluster decrypts it only when it’s synced during the GitOps loop.
External Secret Managers: Dynamic Injection
For more complex environments where secrets change frequently, External Secrets Operator (ESO) acts as a bridge. Instead of sealing secrets in Git, you define an ExternalSecret resource that references a backend provider (like AWS Secrets Manager, HashiCorp Vault, or GCP Secret Manager).
- The
ExternalSecretpoints to the remote key path. - The controller fetches the value from the provider.
- It creates a native Kubernetes
Secreton-the-fly for your application to consume.
This decouples your application configuration from the actual sensitive values. In a multi-environment setup, you simply point your Staging ExternalSecret to the Staging Vault path and your Production ExternalSecret to the Production Vault path. Both environments use the same declarative manifest structure, but the underlying secrets are siloed by infrastructure, providing a clean separation of concerns without manual intervention.
Key Takeaway: Never store plaintext secrets in Git; use Sealed Secrets for immutable encrypted versioning or External Secret Managers to dynamically map cluster resources to centralized vault backends.