# Secrets and Supply-Chain Security — Helm

Source: https://www.skillbyai.com/en/helm/q-security

> Keep secrets out of values files and verify the charts you install.

## Secrets do not belong in values.yaml

Anything in values ends up in the release record (a Secret, but readable by anyone with access to Secrets in the namespace), in `helm get values` output, and often in Git. Keep real secrets out of values. Common patterns: reference an **existing Secret** by name (`existingSecret: shop-db-credentials`) created by another process; use the **External Secrets Operator** to sync secrets from AWS Secrets Manager, Azure Key Vault, Google Secret Manager or Vault; use **Sealed Secrets** (encrypted Secrets safe to commit); or encrypt values files with **SOPS**, for example through the helm-secrets plugin. For supply-chain safety, pin chart versions and dependency versions, prefer charts from the software's own maintainers, and verify integrity: Helm supports **provenance files** (`helm package --sign`, `helm verify`, `--verify` on install), and charts stored in OCI registries can be signed and verified with **cosign**. Review a third-party chart's rendered RBAC and security contexts before installing.

## Referencing a secret instead of embedding it

The chart only knows the Secret's name; the value is managed elsewhere.

```yaml
# values.yaml
database:
  existingSecret: shop-db-credentials   # created by External Secrets / Sealed Secrets
  passwordKey: password

# templates/deployment.yaml (container env)
env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: {{ .Values.database.existingSecret }}
        key: {{ .Values.database.passwordKey }}
```

## A safe deposit box number, not the jewels

The values file should contain the number of the safe deposit box, not the jewels themselves. Anyone can read the number; only the bank (the secret store) can open the box.

**Quiz:** Why is putting a database password directly in a values file risky?

- [ ] Helm cannot render passwords
- [x] It is stored in the release record and often committed to Git, visible to many people
- [ ] Kubernetes rejects plain-text values
- [ ] It makes the chart larger than the limit

*Answer:* It is stored in the release record and often committed to Git, visible to many people. Values are persisted in release records and usually version control, widening who can read the secret.
