Skip to Content
Security featuresGenerated secrets

Generated secrets

generatedSecrets produces one Opaque Secret per entry, named <fullname>-gen-<name>, filled with credential material the cluster generates rather than a value a human writes into values.yaml:

generatedSecrets: - name: admin # -> Secret <fullname>-gen-admin keys: - key: password kind: password # randAlphaNum length: 32 # 16–128, default 32 - key: auth kind: htpasswd # bcrypt "user:$2a$..." line username: admin passwordFrom: password # sibling key of kind password

Key kinds

  • passwordlength (16–128, default 32) random alphanumeric characters via randAlphaNum.
  • htpasswd — a bcrypt user:$2a$... line via username plus either passwordFrom (the name of a sibling password-kind key in the same entry) or an inline password string. password and passwordFrom are mutually exclusive — set exactly one, or the render fails with a named error.

Reconciliation, not regeneration

On upgrade, the existing Secret is looked up and every requested key is reconciled independently:

  • a key already present in the live Secret is reused verbatim,
  • a key not yet present is generated fresh,
  • a key no longer listed in values is dropped from the Secret — values are the contract, not an accumulating superset.

An htpasswd key sourced via passwordFrom is regenerated whenever its source password key was itself freshly generated this render (a bcrypt hash of a rotated password is invalid the moment the password rotates), so the two stay consistent without you having to bump both by hand.

There’s no expiry or rotation tracking — unlike tlsSelfSigned and webhooks, which track a platform/tls-not-after annotation and rotate automatically near expiry, credential Secrets here don’t expire. Rotate by deleting the key (or the whole Secret) and running helm upgrade; a deleted key is treated as absent and regenerated, and a deleted Secret is recreated from scratch.

Validation

Entry name and each keys[].key are required and pattern-checked (name: DNS-1123 label; key: [A-Za-z0-9._-]+). Names are also checked against a reserved-suffix list (-tls, -ca, -secret, -webhook-cert, -mtls-client-*) so a generatedSecrets entry can never collide with a release-managed Secret name from another feature. Duplicate entry names, duplicate keys within an entry, and an entry with an empty keys list all fail the render with a message naming the offending index.

Offline renders

helm template and client-side --dry-run never perform the Secret lookup — every key generates fresh, every time. That’s why every rendered Secret here carries the platform/generated: "true" annotation: the lint gate’s golden-snapshot normalization redacts data: under that marker so goldens stay byte-stable across runs instead of failing on every render because of fresh random data.

Last updated on