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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions