L9. Secrets Management: Native Secrets, Sealed Secrets and Vault
Video generating
Check back soon for the video lesson on Secrets Management: Native Secrets, Sealed Secrets and Vault
Kubernetes Secrets are base64-encoded, not encrypted. Learn the spectrum of secrets management from native secrets to Sealed Secrets for GitOps and HashiCorp Vault for enterprise workloads.
Native Kubernetes Secrets
Kubernetes Secrets store sensitive data like passwords, tokens, and TLS certificates. They are stored in etcd and can be mounted into pods as files or environment variables.
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
type: Opaque
data:
username: YWRtaW4=
password: cDRzc3cwcmQ=
The critical limitation: Secret values are base64-encoded, not encrypted. Without encryption at rest (covered in lesson 3), anyone with etcd access can read them. Even with RBAC, anyone with get secrets permission in a namespace can read all secrets there.
RBAC for Secrets
Restrict secrets access with precise RBAC rules:
rules:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">apiGroups: [""]</li>
</ul>
resources: ["secrets"]
verbs: ["get"]
resourceNames: ["db-credentials"]Use resourceNames to limit access to specific secrets rather than granting blanket get secrets across the namespace.
Sealed Secrets for GitOps
Sealed Secrets solves the problem of storing encrypted secrets in Git. The Sealed Secrets controller runs in the cluster and decrypts SealedSecret resources into regular Secrets.
kubeseal --format yaml < secret.yaml > sealed-secret.yamlThe encrypted SealedSecret can be safely committed to Git. Only the controller in the cluster can decrypt it because the private key never leaves the cluster. Best practice: Rotate the SealedSecrets encryption key periodically and back up the private key securely. If you lose the key, you cannot decrypt any SealedSecrets.
HashiCorp Vault Integration
For enterprise environments, HashiCorp Vault provides dynamic secrets, automatic rotation, audit logging, and fine-grained access control.
Integration methods:
| Method | How It Works | Best For |
|---|---|---|
| Vault Agent Sidecar | Injects secrets as files via init/sidecar container | Legacy apps that read config files |
| Vault CSI Provider | Mounts secrets via the Secrets Store CSI driver | Standard Kubernetes integration |
| Vault Secrets Operator | Syncs Vault secrets to Kubernetes Secrets | Teams that want native Secret objects |
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: db-creds
spec:
vaultAuthRef: default
mount: secret
path: production/db
destination:
name: db-credentials
create: true
refreshAfter: 60s
External Secrets Operator
If you use AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager, the External Secrets Operator syncs cloud secrets into Kubernetes Secrets:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: azure-keyvault
kind: SecretStore
target:
name: db-credentials
data:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300">secretKey: password</li>
</ul>
remoteRef:
key: production-db-passwordThis keeps your cloud KMS as the source of truth while making secrets available as native Kubernetes Secrets.
- ✓Kubernetes Secrets are base64-encoded, not encrypted: without encryption at rest anyone with etcd access can read them
- ✓Use resourceNames in RBAC rules to limit access to specific secrets rather than all secrets in a namespace
- ✓Sealed Secrets encrypts secrets for safe Git storage: only the in-cluster controller can decrypt them
- ✓HashiCorp Vault provides dynamic secrets, automatic rotation, and fine-grained audit logging
- ✓External Secrets Operator syncs cloud KMS secrets (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) into native Kubernetes Secrets
1. How can you limit RBAC access to a single specific secret instead of all secrets in a namespace?
2. What happens if you lose the Sealed Secrets controller private key?
3. Which Vault integration method syncs Vault secrets into native Kubernetes Secret objects?