OIDC / Structured Authentication
3 minute read
As of Kubernetes 1.32, the legacy oidcConfig field in the Shoot manifest is no longer permitted. Authentication via external identity providers is now configured exclusively through Structured Authentication Configuration — a Kubernetes-native format applied directly to the Shoot cluster’s kube-apiserver.
How It Works
The configuration is stored in a ConfigMap in the Gardener project namespace and referenced from the Shoot manifest. Changes to the ConfigMap are applied at the next Shoot reconciliation — a manual trigger is possible if immediate effect is required.
Configuration
Step 1: Create the ConfigMap
The ConfigMap must be created in the project namespace (e.g. garden-my-project) and contains the AuthenticationConfiguration in the config.yaml data field:
apiVersion: v1
kind: ConfigMap
metadata:
name: structured-authentication-config
namespace: garden-my-project
data:
config.yaml: |
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
jwt:
- issuer:
url: https://issuer.example.com
audiences:
- <client-id>
audienceMatchPolicy: MatchAny
claimMappings:
username:
claim: email
prefix: ""
groups:
claim: groups
prefix: ""
Multiple JWT authenticators can be defined in the jwt list, for example to support multiple identity providers.
Step 2: Reference in the Shoot Manifest
Reference the ConfigMap in the Shoot manifest under spec.kubernetes.kubeAPIServer.structuredAuthentication:
apiVersion: core.gardener.cloud/v1beta1
kind: Shoot
metadata:
name: mycluster
namespace: garden-my-project
spec:
kubernetes:
kubeAPIServer:
structuredAuthentication:
configMapName: structured-authentication-config
This change triggers a reconciliation. Other authentication methods (e.g. certificate-based) are not affected.
Claim Mappings
The claimMappings field controls how JWT claims are mapped to Kubernetes identities:
| Field | Description |
|---|---|
username.claim | JWT claim used as the Kubernetes username (e.g. email, sub). |
username.prefix | Optional prefix for the username to avoid conflicts. Empty string disables the prefix. |
groups.claim | JWT claim containing group membership (e.g. groups). |
groups.prefix | Optional prefix for group names. |
uid.expression | CEL expression to compute the UID (optional). |
CEL expressions can be used instead of static claim references:
claimMappings:
username:
expression: 'claims.email'
groups:
expression: 'claims.groups'
Claim Validation Rules
Optional validation rules can be defined to check incoming tokens:
claimValidationRules:
- expression: 'claims.hd == "example.com"'
message: "Only tokens from the domain example.com are permitted"
Migrating from oidcConfig
If the Shoot manifest still contains spec.kubernetes.kubeAPIServer.oidcConfig, it must be migrated to Structured Authentication — at the latest before upgrading to Kubernetes 1.32.
Example — existing oidcConfig:
spec:
kubernetes:
kubeAPIServer:
oidcConfig:
clientID: <client-id>
issuerURL: https://issuer.example.com
usernameClaim: email
groupsClaim: groups
groupsPrefix: "oidc:"
Equivalent Structured Authentication ConfigMap:
data:
config.yaml: |
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
jwt:
- issuer:
url: https://issuer.example.com
audiences:
- <client-id>
claimMappings:
username:
claim: email
prefix: ""
groups:
claim: groups
prefix: "oidc:"
Remove oidcConfig from the Shoot manifest and replace it with the structuredAuthentication block.
Anonymous Authentication
Anonymous authentication is disabled by default in PSKE clusters. It can be enabled for specific paths via Structured Authentication (requires Kubernetes 1.35 or later):
data:
config.yaml: |
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
anonymous:
enabled: true
conditions:
- path: /livez
kubectl Configuration (kubelogin)
For using OIDC with kubectl, the oidc-login plugin (also known as kubelogin) is recommended. Installation and configuration are covered in the tutorial Setting up OIDC/2FA.