feat(helm): support existing token Secret (SOPS) and scope token RBAC to namespace - #497
Conversation
namespace - add zxporter.existingSecret to read the token from a user-managed Secret instead of values; chart skips creating its own credentials Secret - guard against existingSecret.name colliding with tokenSecretName - drop redundant cluster-wide Secret grant (namespace Role already covers it) - docs: docs/existing-secret-sops.md
| {{- if and (empty .Values.zxporter.clusterToken) (empty .Values.zxporter.patToken) (empty (dig "existingSecret" "name" "" .Values.zxporter)) -}} | ||
| {{- fail "ERROR: A token must be provided. Set one of zxporter.clusterToken, zxporter.patToken, or zxporter.existingSecret.name (a pre-existing Secret holding the token)." -}} | ||
| {{- end -}} |
There was a problem hiding this comment.
⚠️ Edge Case: existingSecret satisfies validation but is ignored when useSecretForToken=false
zxporter.validateConfig now treats a non-empty existingSecret.name as satisfying the "a token is required" check, regardless of useSecretForToken.
However, existingSecret is only consumed by the deployment token block, which is entirely gated by {{- if .Values.zxporter.useSecretForToken }} (deployment.yaml:62). When useSecretForToken=false, tokens instead come from the ConfigMap (configmap.yaml:4-7), which only reads clusterToken/patToken — it never reads existingSecret.
So a user who sets existingSecret.name but has useSecretForToken=false (and leaves clusterToken/patToken empty) will pass helm install validation, but the rendered ConfigMap will have empty CLUSTER_TOKEN/PAT_TOKEN and no env vars are injected. The controller starts with no token and fails at runtime ("no URL or token was configured") — the exact silent failure the validation is meant to prevent.
Suggest making the validation reflect the actual usage: only accept existingSecret.name as a valid token source when useSecretForToken is true, or fail fast if existingSecret.name is set while useSecretForToken=false.
Only accept existingSecret.name when useSecretForToken is true, and fail fast on the incompatible combination.:
{{- $existingName := dig "existingSecret" "name" "" .Values.zxporter -}}
{{- $existingUsable := and $existingName .Values.zxporter.useSecretForToken -}}
{{- if and (empty .Values.zxporter.clusterToken) (empty .Values.zxporter.patToken) (not $existingUsable) -}}
{{- fail "ERROR: A token must be provided. Set zxporter.clusterToken, zxporter.patToken, or (with useSecretForToken=true) zxporter.existingSecret.name." -}}
{{- end -}}
{{- if and $existingName (not .Values.zxporter.useSecretForToken) -}}
{{- fail "ERROR: zxporter.existingSecret.name only works with useSecretForToken=true." -}}
{{- end -}}
Was this helpful? React with 👍 / 👎
Code Review
|
Summary by Gitar
existingSecretto source credentials from pre-managed Secrets, enabling SOPS/GitOps workflows.zxporter.validateConfiglogic to prevent naming collisions with the internaltokenSecretName.docs/existing-secret-sops.mdguide for using SOPS-encrypted secrets with the chart.deployment.yamlto injectCLUSTER_TOKENandPAT_TOKENfrom external secrets whenexistingSecretis configured.zxporter-rbac.yamlcontent, shifting to namespace-scoped token management.This will update automatically on new commits.