Kerberos keytab mount broken since 9.10.0 - path uses secret name instead of key, and missing subPath makes mount a directory
## Summary MR !4810 ("Make kerberos keytab updates dynamic", merged in 9.10.0 via 1704d8d7) introduced two bugs in charts/gitlab/templates/\_kerberos.tpl that break Kerberos authentication when the secret name differs from the key name. **Bug 1** - Wrong path in projected volume (line 24): path uses `.Values.global.appConfig.kerberos.keytab.secret` (the secret object name) instead of `.Values.global.appConfig.kerberos.keytab.key` (the key within the secret). This produces the wrong filename inside the projected volume. This was masked during MR review because the maintainer tested with secret: kerberos-keytab and key: tab — with those values the wrong path value (kerberos-keytab) was not obviously incorrect. The bug only manifests when the secret name and key name differ. **Bug 2** - Missing subPath on volumeMount (line 31): Without subPath, the projected volume is mounted as a directory at /etc/krb5.keytab instead of a file. The Kerberos library (GSSAPI) expects a file at that path. The subPath removal was intentional (to enable dynamic secret updates), but the mountPath and the hardcoded keytab: /etc/krb5.keytab in gitlab.appConfig.kerberos.configuration were not updated to account for a directory mount. ## Steps to reproduce 1. Deploy GitLab Helm chart \>= 9.10.0 with Kerberos enabled and a keytab secret where the secret name differs from the key name (see configuration below). 2. Wait for webservice pods to start. 3. Attempt Kerberos authentication (e.g. SPNEGO login). 4. Observe authentication failure. Inspect the pod filesystem: #### The mount is a directory, not a file: ``` kubectl exec -it <webservice-pod> -- ls -la /etc/krb5.keytab/ ``` Shows a file named after the secret (e.g. "my-kerberos-keytab") instead of "krb5.keytab" #### Compare with 9.8.x where it was a file: ``` kubectl exec -it <webservice-pod> -- file /etc/krb5.keytab ``` * 9.8.x: /etc/krb5.keytab: data (a valid keytab file) * 9.10.x: /etc/krb5.keytab: directory 5. Alternatively, render templates locally and compare: 9.10.x (broken) — note: path uses the secret name, subPath is absent ``` helm template test . \ --set certmanager-issuer.email=test@test.com \ --set global.appConfig.kerberos.enabled=true \ --set global.appConfig.kerberos.keytab.secret=my-kerberos-keytab \ --set global.appConfig.kerberos.keytab.key=krb5.keytab \ --show-only charts/gitlab/charts/webservice/templates/deployment.yaml \ | yq '.spec.template.spec | { "volumeMount": (.containers[0].volumeMounts[] | select(.name == "kerberos-keytab")), "volume": (.volumes[] | select(.name == "kerberos-keytab")) }' ``` ## Configuration used ```yaml global: appConfig: kerberos: enabled: true keytab: secret: my-kerberos-keytab key: krb5.keytab ``` ## Current behavior The rendered deployment YAML produces: ``` # Volume — path is wrong (uses secret name instead of key) volumes: - name: kerberos-keytab projected: sources: - secret: name: my-kerberos-keytab items: - key: krb5.keytab path: my-kerberos-keytab # BUG: should be "krb5.keytab" # VolumeMount — missing subPath, so /etc/krb5.keytab becomes a directory volumeMounts: - mountPath: /etc/krb5.keytab name: kerberos-keytab readOnly: true # BUG: no subPath — mount is a directory containing "my-kerberos-keytab" ``` Result: /etc/krb5.keytab is a directory containing a file named my-kerberos-keytab. GSSAPI expects a file at /etc/krb5.keytab and fails with: gss_acquire_cred did not return GSS_S_COMPLETE: Keytab FILE:/etc/krb5.keytab is nonexistent or empty ## Expected behavior The rendered deployment YAML should produce: ``` # Volume — path matches the key name volumes: - name: kerberos-keytab projected: sources: - secret: name: my-kerberos-keytab items: - key: krb5.keytab path: krb5.keytab # correct # VolumeMount — subPath ensures /etc/krb5.keytab is a file volumeMounts: - mountPath: /etc/krb5.keytab subPath: krb5.keytab # correct name: kerberos-keytab readOnly: true ``` Result: /etc/krb5.keytab is a file containing the keytab data. GSSAPI reads it successfully. Suggested fix ``` --- a/charts/gitlab/templates/_kerberos.tpl +++ b/charts/gitlab/templates/_kerberos.tpl @@ -22,13 +22,14 @@ items: - key: {{ .Values.global.appConfig.kerberos.keytab.key }} - path: {{ .Values.global.appConfig.kerberos.keytab.secret }} + path: {{ .Values.global.appConfig.kerberos.keytab.key }} {{- end -}} {{- end -}} - mountPath: "/etc/krb5.keytab" + subPath: {{ .Values.global.appConfig.kerberos.keytab.key }} name: kerberos-keytab readOnly: true ``` Note: Restoring subPath gives up the dynamic secret update goal from the original MR. If dynamic keytab rotation is still desired, a larger change is needed: mount to a directory (e.g. /etc/kerberos/), update keytab: in gitlab.appConfig.kerberos.configuration to /etc/kerberos/krb5.keytab, and verify CNG container compatibility. ## Proposed regression test Deliberately use a secret name that differs from the key to expose both bugs ## Versions - Chart: 9.10.0 through 9.10.3 (regression introduced in 9.10.0). Last working: 9.8.8. - Platform: - Cloud: (any) - Self-hosted: (any) - Kubernetes: (any version supporting projected volumes) - Helm: (any v3.x) ## Relevant logs From webservice pod (/var/log/gitlab/webservice/current or container stderr): ``` gss_acquire_cred did not return GSS_S_COMPLETE: Keytab FILE:/etc/krb5.keytab is nonexistent or empty ``` Inspecting the pod filesystem confirms the mount is a directory: ``` $ kubectl exec -it <webservice-pod> -- ls -la /etc/krb5.keytab/ total 4 drwxrwxrwt 3 root root 100 Apr 9 12:00 . drwxr-xr-x 1 root root 4096 Apr 9 12:00 .. drwxr-xr-x 2 root root 60 Apr 9 12:00 ..2025_04_09_12_00_00.123456789 lrwxrwxrwx 1 root root 32 Apr 9 12:00 ..data -> ..2025_04_09_12_00_00.123456789 lrwxrwxrwx 1 root root 25 Apr 9 12:00 my-kerberos-keytab -> ..data/my-kerberos-keytab ``` Note the file is named my-kerberos-keytab (the secret name) rather than krb5.keytab (the key).
issue