helm template, --dry-run, and all Argo CD / Flux renders return nil from lookup. This means all four secrets regenerate on every sync:
The root password hash changes, locking out the UI.
The pepper rotates, invalidating every non-root user's bcrypt hash.
Even in the standard CLI workflow, the root password is not restored from the looked-up secret across upgrades — only the pepper is.
Describe the solution you'd like
Short term:
Restore `GRAYLOG_ROOT_PASSWORD_SHA2` from the looked-up secret in `config/secret/secrets.yaml` (alongside the existing pepper restore — ~3 lines).
Add a "GitOps users" callout to the README: `global.existingSecretName` is required under Argo CD / Flux. Document what happens if it is not set (secrets regenerate on every sync).
Medium term:
Add a secrets.management: helm | external mode with a hard fail when lookup returns nil in helm mode.
Longer term: a pre-install Job that writes secrets once, removing the lookup dependency entirely.
Additional context
The __secretsChecksum render-once pattern works because Helm passes the same values-map pointer to every template in a single render. This is undocumented behavior — it deserves a code comment and a helm-unittest canary verifying checksum consistency across NOTES.txt, the test secret, and the main secret.
Review IDs: C-01, C-02
helm template, --dry-run, and all Argo CD / Flux renders return nil from lookup. This means all four secrets regenerate on every sync:
Describe the solution you'd like
Short term:
Medium term:
Additional context
The __secretsChecksum render-once pattern works because Helm passes the same values-map pointer to every template in a single render. This is undocumented behavior — it deserves a code comment and a helm-unittest canary verifying checksum consistency across NOTES.txt, the test secret, and the main secret.
Review IDs:
C-01,C-02