nebari-dev / nebari-dev/data-science-pack
Security(M-07): Hub OIDC login credential reused for Admin API and forwarded to japps with broad realm roles
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5
- Forks
- 7
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 13
Description
Summary
The hub's OIDC login client doubles as its Keycloak Admin API service account, and the same client secret is forwarded into the user-facing japps service. The login client is granted broad realm-management read roles, so compromise of this widely distributed credential permits realm-wide enumeration of users, groups, clients, and configuration.
Severity: Medium · CWE-250 (Execution with Unnecessary Privileges)
Validation: Confirmed against HEAD f932d80 on 2026-07-14 (assessed at 69c84f7; unchanged since).
Evidence
- Login credentials reused for Admin API:
config/jupyterhub/00-gateway-auth.py:480-490builds the Admin API client from the same OAuthclient_id/client_secret, and_client_credentials_token(00-gateway-auth.py:149-161) performs aclient_credentialsgrant with them. - Secret forwarded to japps:
config/jupyterhub/02-jhub-apps.py:79-84injectsJUPYTERHUB_OIDC_CLIENT_SECRETinto the japps subprocess environment. - Broad roles:
files/keycloak_rbac_bootstrap.py:64assignsview-clients,view-groups,view-realm,view-users. Note thevalues.yaml:266comment advertises only three of these (it omitsview-users), so the docs understate what the code grants.
Impact
The platform needs limited authorization-lookup capability, but binding realm-management roles to the login credential and then forwarding that credential to a user-facing service means a single compromise can enumerate every user, group, and client in the realm.
Remediation
- Separate login credentials from administration credentials.
- Use a purpose-specific identity or an authorization broker that exposes only the required group/profile decision.
- Never forward administrative credentials into a user-facing service.
- Rotate the existing secret.
- Fix the
values.yamlcomment to match the roles actually granted.
Acceptance criteria
- The login client has no realm-management roles.
- Compromise of the login client cannot enumerate unrelated realm objects.
Source: data-science-pack 0.1.0 security assessment (pinned commit 69c84f72df259ec755ed40bfc83f20158c550d55), finding M-07.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading config/jupyterhub/00-gateway-auth.py, config/jupyterhub/02-jhub-apps.py, files/keycloak_rbac_bootstrap.py, and values.yaml at the referenced lines. Trace how the login client is used and how its secret and realm roles are configured; identify a design that meets the required authorization lookup without exposing administrative credentials. Done means the login client has no realm-management roles and cannot enumerate unrelated realm objects.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, yaml
- Domain
- authentication, authorization, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100