Secrets in Kubernetes

In Kubernetes, inject secrets through Secret resources or an external secret integration. Do not embed them in code, configuration files committed to a repository or ConfigMaps.

When to use this guide

  • A service deployed on Kubernetes has secrets in code or configuration files.
  • A ConfigMap contains passwords, API keys or tokens.
  • A Deployment uses hardcoded environment variable values.

Recommended approach

  • Use Secret resources or an external integration such as External Secrets Operator.
  • Inject values into Pods through env.valueFrom.secretKeyRef or volume mounts.
  • Do not write literal secret values in Helm values, ConfigMaps or Deployment manifests.
  • Base64 encoding alone does not protect a Secret. Also check the cluster’s etcd encryption at rest settings where possible.

Examples

Before

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:latest
          env:
            - name: API_KEY
              value: "sk-prod-123456"

After

This excerpt shows only secret injection. Configure the Deployment’s selector, Pod labels and other settings separately. ${REAL_SECRET_VALUE} is a placeholder for a value securely supplied by the deployment tooling; Kubernetes does not automatically substitute an environment variable for it.

yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
stringData:
  API_KEY: ${REAL_SECRET_VALUE}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:latest
          env:
            - name: API_KEY
              valueFrom:
                secretKeyRef:
                  name: app-secret
                  key: API_KEY

Remediation steps for the owner

  1. Remove real secret values from Deployments, Helm charts, values files and ConfigMaps.
  2. Create a Kubernetes Secret or an external secret integration resource.
  3. Configure the application to receive values through secretKeyRef or a Secret volume.
  4. Rotate any previously exposed value immediately.
  5. Check that kubectl describe, logs and debug scripts do not expose secrets.

Example instructions for the owner

  • “Remove hardcoded secrets from Deployments and ConfigMaps and use Kubernetes Secrets.”
  • “Inject values into Pods through secretKeyRef or a Secret volume; do not write the actual values directly in manifests.”
  • “Revoke and replace an exposed value before moving to a Secret resource.”

Additional checks

  • Are any secrets mistakenly stored in a ConfigMap?
  • Does Helm values.yaml contain real production values?
  • Is Base64 encoding being mistaken for protection?
  • Is encryption at rest enabled for secrets in the cluster?