πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Security advanced ⏱ 45 minutes K8s 1.28+

K8s OIDC Integration with Enterprise SSO

Configure Kubernetes API server OIDC authentication with Keycloak, Azure AD, or Okta for enterprise single sign-on and group-based RBAC.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Configure the kube-apiserver with --oidc-issuer-url, --oidc-client-id, and --oidc-groups-claim flags to authenticate users via your enterprise IdP (Keycloak, Azure AD, Okta). Map IdP groups to Kubernetes ClusterRoleBindings for automated RBAC.

The Problem

Enterprise organizations need centralized identity management. Local Kubernetes service accounts and client certificates don’t integrate with corporate SSO, lack MFA, and create audit gaps. You need API server authentication that flows through your existing identity provider with group-based access control.

flowchart LR
    USER["Developer"] -->|kubectl| APISERVER["kube-apiserver"]
    APISERVER -->|Validate JWT| IDP["Enterprise IdP<br/>(Keycloak/Azure AD/Okta)"]
    IDP -->|Groups claim| APISERVER
    APISERVER -->|Match groups| RBAC["ClusterRoleBindings<br/>Group β†’ Role mapping"]
    RBAC -->|Authorize| RESOURCE["K8s Resources"]

The Solution

Configure kube-apiserver for OIDC

Add OIDC flags to the API server manifest:

# /etc/kubernetes/manifests/kube-apiserver.yaml (kubeadm)
apiVersion: v1
kind: Pod
metadata:
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
    - name: kube-apiserver
      command:
        - kube-apiserver
        # ... existing flags ...
        - --oidc-issuer-url=https://keycloak.example.com/realms/kubernetes
        - --oidc-client-id=kubernetes
        - --oidc-username-claim=preferred_username
        - --oidc-username-prefix="oidc:"
        - --oidc-groups-claim=groups
        - --oidc-groups-prefix="oidc:"
        - --oidc-ca-file=/etc/kubernetes/pki/oidc-ca.pem

Keycloak Configuration

# Create Kubernetes realm client in Keycloak
# 1. Create a new client: kubernetes
# 2. Set Access Type: confidential
# 3. Add mappers:
#    - groups: Type=Group Membership, Token Claim Name=groups
#    - audience: Type=Audience, Included Client Audience=kubernetes

# Example Keycloak groups:
# - k8s-admins      β†’ cluster-admin
# - k8s-developers  β†’ namespace edit
# - k8s-viewers     β†’ namespace view

Azure AD Configuration

# Register application in Azure AD
az ad app create --display-name "Kubernetes OIDC" \
  --sign-in-audience AzureADMyOrg

# API server flags for Azure AD
--oidc-issuer-url=https://login.microsoftonline.com/<TENANT-ID>/v2.0
--oidc-client-id=<APPLICATION-ID>
--oidc-username-claim=email
--oidc-groups-claim=groups

Group-Based RBAC Bindings

# Map IdP group to cluster-admin
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: oidc-cluster-admins
subjects:
  - kind: Group
    name: "oidc:k8s-admins"
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
# Map IdP group to namespace developer
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: oidc-developers
  namespace: app-team-a
subjects:
  - kind: Group
    name: "oidc:k8s-developers"
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io
---
# Read-only for viewers
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: oidc-viewers
subjects:
  - kind: Group
    name: "oidc:k8s-viewers"
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

Configure kubectl for OIDC

# Install kubelogin (OIDC helper)
kubectl krew install oidc-login

# Configure kubeconfig
kubectl config set-credentials oidc-user \
  --exec-api-version=client.authentication.k8s.io/v1beta1 \
  --exec-command=kubectl \
  --exec-arg=oidc-login \
  --exec-arg=get-token \
  --exec-arg=--oidc-issuer-url=https://keycloak.example.com/realms/kubernetes \
  --exec-arg=--oidc-client-id=kubernetes \
  --exec-arg=--oidc-client-secret=<CLIENT-SECRET>

# Test authentication
kubectl --user=oidc-user get pods
# Browser opens β†’ SSO login β†’ kubectl authorized

Audit Logging for Compliance

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # Log all authentication events
  - level: RequestResponse
    users: ["system:anonymous"]
    resources:
      - group: ""
        resources: ["*"]
  # Log OIDC user actions at metadata level
  - level: Metadata
    userGroups: ["oidc:*"]
  # Log privilege escalation attempts
  - level: RequestResponse
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings"]

Common Issues

IssueCauseFix
Unauthorized after loginOIDC issuer URL mismatchVerify --oidc-issuer-url matches IdP exactly (trailing slash matters)
Groups not mappedMissing groups claim mapperAdd Group Membership mapper in Keycloak with groups token claim
Token expired during sessionShort token lifetimeConfigure IdP refresh tokens, use kubelogin for auto-refresh
oidc: verify failedCA cert mismatchAdd IdP CA to --oidc-ca-file on API server
Azure AD groups show as GUIDsDefault Azure behaviorMap GUIDs to friendly names in RoleBindings or use --oidc-groups-claim=roles

Best Practices

  • Use group-based RBAC β€” never bind individual users; always map IdP groups to K8s roles
  • Prefix OIDC identities β€” --oidc-username-prefix and --oidc-groups-prefix prevent collisions with local accounts
  • Require MFA at the IdP level β€” Kubernetes doesn’t handle MFA; enforce it in Keycloak/Azure AD/Okta
  • Rotate client secrets β€” schedule secret rotation in your IdP at least every 90 days
  • Audit everything β€” enable API server audit logging for all OIDC user actions
  • Break-glass accounts β€” maintain emergency client certificate or service account access in case IdP is down

Key Takeaways

  • OIDC integrates Kubernetes with enterprise SSO (Keycloak, Azure AD, Okta) for centralized identity
  • Map IdP groups to K8s ClusterRoleBindings/RoleBindings for automated group-based RBAC
  • Use kubelogin for seamless browser-based SSO with kubectl
  • Always prefix OIDC identities to distinguish from local service accounts
#oidc #enterprise-sso #keycloak #rbac #authentication
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens