Working with Secrets and Sensitive Data

1. Creating Secret Templates

Example: Opaque Secret

apiVersion: v1
kind: Secret
metadata:
  name: {{ include "myapp.fullname" . }}-secret
type: Opaque
stringData:
  api-key: {{ required "apiKey required" .Values.apiKey | quote }}
  db-url:  {{ printf "postgres://%s:%s@db:5432/api" .Values.db.user .Values.db.password | quote }}

2. Encoding Secret Values

FieldEncoding
dataBase64-encoded values required; use | b64enc
stringDataPlain strings; K8s base64-encodes on write

3. Using External Secrets

Example: ExternalSecret CR

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: {{ include "myapp.fullname" . }}
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secretsmanager
    kind: ClusterSecretStore
  target:
    name: {{ include "myapp.fullname" . }}-secret
  data:
    - secretKey: api-key
      remoteRef: { key: prod/api, property: apiKey }

4. Integrating with HashiCorp Vault

MethodPattern
Vault Agent InjectorAnnotate pods; sidecar fetches secrets at runtime
External Secrets OperatorSecretStore kind: Vault
CSI Secrets StoreMount as volume via secrets-store.csi.k8s.io

5. Using SOPS for Encryption

Example: helm-secrets plugin

helm plugin install https://github.com/jkroepke/helm-secrets
sops -e -i values-prod.yaml         # encrypt in place
helm secrets upgrade api ./chart -f secrets://values-prod.yaml

6. Managing TLS Certificates

Example: cert-manager Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: {{ include "myapp.fullname" . }}-tls
spec:
  secretName: {{ include "myapp.fullname" . }}-tls
  issuerRef: { name: letsencrypt-prod, kind: ClusterIssuer }
  dnsNames: [{{ .Values.host | quote }}]

7. Using Sealed Secrets

StepCommand
Install controllerhelm install sealed-secrets sealed-secrets/sealed-secrets -n kube-system
Encryptkubeseal -f secret.yaml > sealed.yaml
CommitSealedSecret CR safe to store in Git
Controller decryptsProduces a regular Secret in target namespace

8. Passing Secrets via Values

Example: CI injection

# Never commit secrets — read from CI vault
helm upgrade --install api ./chart \
  --set-file dbPassword=<(vault kv get -field=password kv/db)

9. Using Secret Files

FlagUse
--set-file key=pathRead file as value (escapes contents)
--values secrets-file.yamlPull from gitignored or SOPS-decrypted file

10. Avoiding Hardcoded Secrets

Warning: Anything in values.yaml, Chart.lock, or templates is plaintext in source control. Hard-coded credentials are the #1 chart vulnerability. Use external secret backends.