Summary
The Keycloak RBAC bootstrap job (templates/keycloak-rbac-bootstrap-job.yaml) re-derives the hub OIDC client id from a hardcoded convention instead of reading the actual id that nebari-operator provisioned. When the deployed operator names clients differently than the chart assumes, the job fails:
RuntimeError: client 'jupyterhub-data-science-pack-nebari-data-science-pack' not found in realm 'nebari'
Detail
The job computes the client id as jupyterhub-<release>-<chart>:
# templates/keycloak-rbac-bootstrap-job.yaml
{{- $hubClientId := .Values.rbac.bootstrap.hubClientId | default (printf "jupyterhub-%s-%s" .Release.Name .Chart.Name) }}
with the comment "Matches the nebari-operator NebariApp client-id pattern: jupyterhub-<release>-<chart>."
But (at least one released) nebari-operator names the client <namespace>-<NebariApp-name>. With release data-science-pack in namespace data-science, the operator created:
data-science-data-science-pack-nebari-data-science-pack
while the job looked up jupyterhub-data-science-pack-nebari-data-science-pack → "client not found".
Notably, hub login is unaffected — 00-gateway-auth.py reads the real client id from the operator-provisioned secret mounted at /etc/oauth. Only the bootstrap job, which derives the name independently, breaks. So the chart already has the correct value available; it just isn't used by the job.
Impact
On any cluster whose nebari-operator uses a client-id convention other than jupyterhub-<release>-<chart>, the RBAC bootstrap job fails on a fresh install — blocking the group-membership mapper / shared-mount role setup. The rbac.bootstrap.hubClientId override works around it but bakes the namespace/release into the value.
Proposed fix
Have the bootstrap job read the hub client id from the operator-provisioned OIDC client Secret (the same {Release.Name}-{Chart.Name}-oidc-client Secret the hub reads from /etc/oauth) rather than re-deriving it. That removes the dependency on the operator's naming convention entirely and keeps the job in sync with whatever the operator actually created.
Alternatively, document the operator-version ↔ chart-version compatibility (which client-id convention each operator release uses) and surface a clearer error than "client not found".
Workaround
Set rbac.bootstrap.hubClientId to the operator's actual client id, e.g.:
rbac:
bootstrap:
hubClientId: data-science-data-science-pack-nebari-data-science-pack
Environment
- Chart:
nebari-data-science-pack 0.1.0-alpha.16
- nebari-operator client-id convention observed:
<namespace>-<NebariApp-name>
Summary
The Keycloak RBAC bootstrap job (
templates/keycloak-rbac-bootstrap-job.yaml) re-derives the hub OIDC client id from a hardcoded convention instead of reading the actual id thatnebari-operatorprovisioned. When the deployed operator names clients differently than the chart assumes, the job fails:Detail
The job computes the client id as
jupyterhub-<release>-<chart>:with the comment "Matches the nebari-operator NebariApp client-id pattern:
jupyterhub-<release>-<chart>."But (at least one released) nebari-operator names the client
<namespace>-<NebariApp-name>. With releasedata-science-packin namespacedata-science, the operator created:while the job looked up
jupyterhub-data-science-pack-nebari-data-science-pack→ "client not found".Notably, hub login is unaffected —
00-gateway-auth.pyreads the real client id from the operator-provisioned secret mounted at/etc/oauth. Only the bootstrap job, which derives the name independently, breaks. So the chart already has the correct value available; it just isn't used by the job.Impact
On any cluster whose nebari-operator uses a client-id convention other than
jupyterhub-<release>-<chart>, the RBAC bootstrap job fails on a fresh install — blocking the group-membership mapper / shared-mount role setup. Therbac.bootstrap.hubClientIdoverride works around it but bakes the namespace/release into the value.Proposed fix
Have the bootstrap job read the hub client id from the operator-provisioned OIDC client Secret (the same
{Release.Name}-{Chart.Name}-oidc-clientSecret the hub reads from/etc/oauth) rather than re-deriving it. That removes the dependency on the operator's naming convention entirely and keeps the job in sync with whatever the operator actually created.Alternatively, document the operator-version ↔ chart-version compatibility (which client-id convention each operator release uses) and surface a clearer error than "client not found".
Workaround
Set
rbac.bootstrap.hubClientIdto the operator's actual client id, e.g.:Environment
nebari-data-science-pack0.1.0-alpha.16<namespace>-<NebariApp-name>