Cyber Intelligence
Pod Security and Workload Hardening · Workload hardening

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.yaml

The 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:

MethodHow It WorksBest For
Vault Agent SidecarInjects secrets as files via init/sidecar containerLegacy apps that read config files
Vault CSI ProviderMounts secrets via the Secrets Store CSI driverStandard Kubernetes integration
Vault Secrets OperatorSyncs Vault secrets to Kubernetes SecretsTeams that want native Secret objects
The Vault Secrets Operator approach:
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-password

This keeps your cloud KMS as the source of truth while making secrets available as native Kubernetes Secrets.

Exam Focus Points
  • 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
Knowledge Check

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?