Skip to content

Support externally-managed secrets (existingSecret) and fix hook lifecycle #35

@darkhonor

Description

@darkhonor

Description

The chart has no way to reference pre-existing Kubernetes Secrets for application credentials, and the pre-install hook lifecycle has gaps that cause failures on retries and upgrades.

We patched existingSecret support and hook-delete-policy into our fork. The db-init-job hook annotation changes (pre-upgrade, hook-delete-policy) are suggested fixes we haven't patched yet.

Environment

  • KASM Workspaces: 1.18.1
  • Kubernetes: RKE2 v1.33
  • Secrets Management: HashiCorp Vault via Vault Secrets Operator

Findings

1. No existingSecret support

All secretKeyRef entries (admin-password, manager-token, service-token, user-password) are hardcoded to {{ .Release.Name }}-secrets. There is no option to reference an externally-managed secret from HashiCorp Vault, AWS Secrets Manager, sealed-secrets, or any other secrets management solution.

This is a standard Helm convention (see bitnami charts, external-secrets, etc.).

Impact: When using Vault Secrets Operator (or similar), the external secret is created before the Helm install. The pre-install hook then fails with secrets "kasm-secrets" already exists.

Suggested fix — values.yaml: Add existingSecret block after the database: section:

# -- Pre-existing Kubernetes Secret for KASM application credentials.
# When `existingSecret.name` is set, the pre-install password generation
# hook is disabled and templates reference this secret instead.
existingSecret:
  # existingSecret.name -- Name of existing Secret. Leave empty to auto-generate.
  name: ""
  keys:
    # existingSecret.keys.managerToken -- Key name for the manager token
    managerToken: "manager-token"
    # existingSecret.keys.serviceToken -- Key name for the service registration token
    serviceToken: "service-token"
    # existingSecret.keys.adminPassword -- Key name for the default admin password
    adminPassword: "admin-password"
    # existingSecret.keys.userPassword -- Key name for the default user password
    userPassword: "user-password"

Suggested fix — kasm-password-secret.yaml: Skip hook when existingSecret is set:

+{{- if not .Values.existingSecret.name }}
 {{- $namespace := .Release.Namespace }}
 ...
 data:
   {{ $key }}: {{ $constantsecret | quote }}
     {{- end }}
   {{- end }}
+{{- end }}
 {{- end }}

Suggested fix — db-init-job.yaml secretKeyRef entries: Each of the four credential references (admin-password, manager-token, service-token, user-password) needs a conditional:

            - name: DEFAULT_ADMIN_PASSWORD
              valueFrom:
                secretKeyRef:
                  {{- if .Values.existingSecret.name }}
                  name: {{ .Values.existingSecret.name }}
                  key: {{ .Values.existingSecret.keys.adminPassword }}
                  {{- else }}
                  name: {{ .Release.Name }}-secrets
                  key: admin-password
                  {{- end }}

Same pattern for DEFAULT_MANAGER_TOKEN (.existingSecret.keys.managerToken / manager-token), DEFAULT_REGISTRATION_TOKEN (.existingSecret.keys.serviceToken / service-token), and DEFAULT_USER_PASSWORD (.existingSecret.keys.userPassword / user-password).

Suggested fix — guac-deployment.yaml, rdp-gateway-deployment.yaml, rdp-https-gateway-deployment.yaml: Each has a REGISTRATION_TOKEN secretKeyRef that needs the same conditional:

            - name: REGISTRATION_TOKEN
              valueFrom:
                secretKeyRef:
                  {{- if .Values.existingSecret.name }}
                  name: {{ .Values.existingSecret.name }}
                  key: {{ .Values.existingSecret.keys.serviceToken }}
                  {{- else }}
                  name: {{ .Release.Name }}-secrets
                  key: service-token
                  {{- end }}

2. Missing hook-delete-policy on kasm-password-secret

kasm-password-secret.yaml has no helm.sh/hook-delete-policy annotation. If a previous install attempt left a stale Secret, the next install fails because the resource already exists.

Suggested fix:

   annotations:
     helm.sh/hook: pre-install
+    helm.sh/hook-delete-policy: before-hook-creation

3. db-init-job missing pre-upgrade hook

The db-init-job is annotated with helm.sh/hook: pre-install only. On helm upgrade, Alembic database migrations do not run. This means schema changes between versions are never applied via Helm lifecycle.

Suggested fix:

   annotations:
-    helm.sh/hook: pre-install
+    helm.sh/hook: pre-install,pre-upgrade
+    helm.sh/hook-delete-policy: before-hook-creation

4. db-init-job missing hook-delete-policy

Same as #2 — the db-init-job has ttlSecondsAfterFinished: 100 but no helm.sh/hook-delete-policy. If TTL cleanup didn't fire (common edge case), a stale Job blocks the next hook run.

Workaround

We forked the chart and added existingSecret support + hook-delete-policy on the secret hook. The db-init-job hook annotation changes are on our backlog. Happy to submit a PR if there's interest.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions