nebari-dev / nebari-dev/data-science-pack

Security(H-05): RBAC bootstrap Job runs a mutable image with the Keycloak master-realm admin password

Open
#167 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: security priority: high 🔥
Dominant language
Python
Stars
5
Forks
7
Avg merge
1d 20h
Merged PRs (30d)
13

Description

Summary

The Keycloak RBAC bootstrap runs by default on NebariApp deployments as a post-install/post-upgrade Job. It pulls the mutable python:3.12-slim tag, receives the Keycloak master-realm admin password in its environment, and authenticates as admin to the master realm to reconfigure clients, mappers, roles, and redirects. The Job has no security context, no token opt-out, no resource limits, and no egress policy.

Severity: High · CWE-494 (Download of Code Without Integrity Check)
Validation: Confirmed against HEAD f932d80 on 2026-07-14 (assessed at 69c84f7; unchanged since).

Evidence

  • Default-enabled: templates/keycloak-rbac-bootstrap-job.yaml:27 gates on nebariapp.enabled (values.yaml:47 true) AND rbac.bootstrap.enabled (values.yaml:279 true) AND a non-empty credential secret (values.yaml:288 keycloak-admin-credentials).
  • Mutable image: values.yaml:326 python:3.12-slim, referenced at keycloak-rbac-bootstrap-job.yaml:91, no digest.
  • Master admin password in env: keycloak-rbac-bootstrap-job.yaml:98-102 injects KC_ADMIN_PASSWORD from the credential secret.
  • Master-realm password grant as admin: files/keycloak_rbac_bootstrap.py:105 (/realms/master/protocol/openid-connect/token) and :124-129 (grant_type=password&client_id=admin-cli&username=admin&password=...).
  • Mutations performed (files/keycloak_rbac_bootstrap.py:474-502): group-membership mapper, hub OIDC client + service-account settings, redirect/rootUrl config, realm-management role binding, shared-directory client role, group-to-role assignment.
  • Missing hardening: no pod/container securityContext in the Job spec (keycloak-rbac-bootstrap-job.yaml:87-126), so it runs as root; no automountServiceAccountToken: false; no resource requests/limits; no egress NetworkPolicy.

Partial mitigations already present: the password is delivered via secretKeyRef (not hardcoded), the script ConfigMap is mounted read-only mode 0555, and ttlSecondsAfterFinished: 600 bounds the pod lifetime. These reduce but do not remove the exposure, since the password is readable in the running pod's environment and the container runs as root.

Impact

A compromised or moved image tag can read the master admin password and take control of Keycloak: alter clients, redirects, group assignments, roles, and identities across every service that trusts the realm. Pinning the Helm chart tag does not pin these runtime bytes.

Remediation

  • Use a purpose-built image pinned by digest, signed, attested, and admission-verified.
  • Replace the persistent master password with a narrowly scoped, short-lived provisioning identity, or move provisioning to a separately controlled infrastructure workflow.
  • Disable the Job after one-time provisioning.
  • Add token opt-out, strict egress, read-only filesystem, seccomp, capability, and resource controls.
  • Rotate the admin password after migration.

Acceptance criteria

  • No application-chart Job receives the master admin password.
  • The provisioning identity cannot administer unrelated realms or clients.
  • A mutable or unsigned bootstrap image is rejected.
  • The Job can reach only the intended Keycloak endpoint.

Related

  • #129 asks to set runAsNonRoot: true / non-zero runAsUser on this Job (or document why not). This issue also covers the mutable image tag, the master-password model, token opt-out, resource limits, and egress policy.

Source: data-science-pack 0.1.0 security assessment (pinned commit 69c84f72df259ec755ed40bfc83f20158c550d55), finding H-05.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with templates/keycloak-rbac-bootstrap-job.yaml and values.yaml to trace when the Job is enabled, its image, credentials, and pod settings. Read files/keycloak_rbac_bootstrap.py around the token request and mutation calls, then review the related #129 work. Done means all listed acceptance criteria are met and the bootstrap path no longer exposes or over-privileges the master password.

Written by the indexing model from the issue text.

Assessment

Tech stack
helm, kubernetes, python
Domain
authentication, authorization, devops, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.