What
The typed Kubernetes app OIDC knob spec.oidc.mode: CustomConfig (and System) mounts the AuthenticationConfiguration and adds --authentication-config=... to the tenant kube-apiserver, but does NOT add --requestheader-uid-headers=X-Remote-Uid (nor the RemoteRequestHeaderUID feature gate needed on k8s ≤ 1.33). packages/apps/kubernetes/templates/cluster.yaml injects only the --authentication-config arg + volume; a repo-wide grep for requestheader-uid / RemoteRequestHeaderUID hits only docs and the manual controlPlane.apiServer.extraArgs escape hatch (README.md:188, values.yaml:222, api/.../types.go:55) and a passthrough test — never the knob's own rendering.
Consequence
The primary consumer of tenant OIDC is an aggregated apiserver behind the tenant kube-apiserver (e.g. a portal). Those apiservers require the authenticated user's UID, which only crosses the aggregation layer when the kube-apiserver forwards it via --requestheader-uid-headers. Without it, SelfSubjectReview on the kube-apiserver correctly shows the uid, but every aggregated call returns 500 user UID is empty. So oidc.mode: CustomConfig looks wired (login works, kubeconfig works) yet the main reason to enable tenant OIDC is broken until the operator hand-adds the header arg through extraArgs.
Reproduction
Kamaji tenant cluster (Cozystack v1.6.0-rc.2), spec.oidc.mode: CustomConfig with an issuer mapping uid from sub, plus a cozyportal accounting/iam aggregated apiserver in the tenant cluster. Observed 2026-07-20: 500 user UID is empty until --requestheader-uid-headers=X-Remote-Uid + --feature-gates=RemoteRequestHeaderUID=true were added to the KamajiControlPlane apiServer extraArgs.
Lineage
Closed #3074 documents the requirement (--authentication-config plus --requestheader-uid-headers). #3123 answered it with the generic extraArgs passthrough; #3044 then added the typed oidc.mode knob but did not carry the UID-header wiring into it. So the mechanism is known to maintainers; the gap is that the typed knob leaves it as a documented manual step.
Ask
When oidc.mode is System/CustomConfig, have the app also render --requestheader-uid-headers=X-Remote-Uid (and the RemoteRequestHeaderUID gate for k8s ≤1.33) on the tenant apiserver, so aggregated-API consumers work out of the box.
What
The typed
Kubernetesapp OIDC knobspec.oidc.mode: CustomConfig(andSystem) mounts theAuthenticationConfigurationand adds--authentication-config=...to the tenant kube-apiserver, but does NOT add--requestheader-uid-headers=X-Remote-Uid(nor theRemoteRequestHeaderUIDfeature gate needed on k8s ≤ 1.33).packages/apps/kubernetes/templates/cluster.yamlinjects only the--authentication-configarg + volume; a repo-wide grep forrequestheader-uid/RemoteRequestHeaderUIDhits only docs and the manualcontrolPlane.apiServer.extraArgsescape hatch (README.md:188,values.yaml:222,api/.../types.go:55) and a passthrough test — never the knob's own rendering.Consequence
The primary consumer of tenant OIDC is an aggregated apiserver behind the tenant kube-apiserver (e.g. a portal). Those apiservers require the authenticated user's UID, which only crosses the aggregation layer when the kube-apiserver forwards it via
--requestheader-uid-headers. Without it,SelfSubjectReviewon the kube-apiserver correctly shows the uid, but every aggregated call returns500 user UID is empty. Sooidc.mode: CustomConfiglooks wired (login works, kubeconfig works) yet the main reason to enable tenant OIDC is broken until the operator hand-adds the header arg throughextraArgs.Reproduction
Kamaji tenant cluster (Cozystack v1.6.0-rc.2),
spec.oidc.mode: CustomConfigwith an issuer mappinguidfromsub, plus a cozyportal accounting/iam aggregated apiserver in the tenant cluster. Observed 2026-07-20:500 user UID is emptyuntil--requestheader-uid-headers=X-Remote-Uid+--feature-gates=RemoteRequestHeaderUID=truewere added to the KamajiControlPlane apiServer extraArgs.Lineage
Closed #3074 documents the requirement (
--authentication-configplus--requestheader-uid-headers). #3123 answered it with the generic extraArgs passthrough; #3044 then added the typedoidc.modeknob but did not carry the UID-header wiring into it. So the mechanism is known to maintainers; the gap is that the typed knob leaves it as a documented manual step.Ask
When
oidc.modeisSystem/CustomConfig, have the app also render--requestheader-uid-headers=X-Remote-Uid(and theRemoteRequestHeaderUIDgate for k8s ≤1.33) on the tenant apiserver, so aggregated-API consumers work out of the box.