Skip to content

[BUG] Bundled subcharts hardcode securityContext.runAsUser/runAsGroup → not deployable on OpenShift (restricted-v2 dynamic UID range) #2079

Description

@davidkarlsen

Summary

Several bundled subcharts pin securityContext.runAsUser / runAsGroup (and one podSecurityContext) to fixed UIDs in their default values. On OpenShift this makes the chart undeployable out of the box: each namespace is assigned a dynamic UID range and the restricted-v2 SCC rejects any pod whose runAsUser falls outside that range. The affected Deployments stay at 0/1 with a FailedCreate event, and every component has to be overridden to an in-range UID by hand.

Relates to #459 ("[FEATURE] OpenShift support", closed as stale).

Affected defaults (chart 0.9.9)

component file value
grafana-mcp charts/grafana-mcp/values.yaml (securityContext) runAsUser: 1000, runAsGroup: 999
querydoc charts/querydoc/values.yaml (securityContext) runAsUser: 14000, runAsGroup: 14000
oauth2-proxy (vendored dependency) charts/oauth2-proxy/values.yaml (podSecurityContext) runAsUser: 2000, runAsGroup: 2000
bundled demo PostgreSQL values.yaml (...postgresql.podSecurityContext) runAsUser: 999, runAsGroup: 999, fsGroup: 999

Impact / symptom

On OpenShift (e.g. restricted-v2 SCC), the API server rejects the pod at admission. Representative event:

Error creating: pods "grafana-mcp-..." is forbidden: unable to validate against any
security context constraint: ... runAsUser: Invalid value: 1000: must be in the
ranges: [1001150000, 1001159999]

The Deployment then sits at 0/1. To install the chart we currently have to override each component's securityContext.runAsUser/runAsGroup to a value inside the namespace's assigned range — which is cluster/namespace-specific and not knowable ahead of time.

Proposed fix

Don't pin runAsUser/runAsGroup in the subchart default values. Keep the rest of the hardening that is already there (runAsNonRoot: true, capabilities.drop: [ALL], readOnlyRootFilesystem: true, seccompProfile). With no runAsUser set:

  • OpenShift injects a valid in-range UID automatically via the SCC.
  • Vanilla Kubernetes runs as the image's USER and runAsNonRoot: true still enforces non-root.

This assumes the grafana-mcp / querydoc images declare a non-root USER. If they don't, the alternative is to make the UID cleanly nullable/overridable (so it can be unset) and document the OpenShift guidance, rather than shipping a hardcoded out-of-range default.

For the vendored oauth2-proxy dependency, surfacing/recommending an override (or unsetting it via the umbrella values) would cover it.

I'm happy to send a PR for the grafana-mcp and querydoc subcharts once you confirm the preferred approach (unset default vs. nullable+documented).

Environment

  • kagent helm chart 0.9.9 (oci://ghcr.io/kagent-dev/kagent/helm/kagent)
  • OpenShift (ARO), restricted-v2 SCC with per-namespace dynamic UID ranges

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions