This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 2, 2026. Spotted a mistake? Tell us.
The Kubernetes API server can authenticate users with OpenID Connect. Instead of distributing client certificates or static tokens, the cluster trusts a JWT issued by an identity provider, and Kubernetes uses the token's claims as the user's identity for RBAC.
This is the cleanest way to give engineers kubectl access without handing out long-lived credentials. The identity provider handles login, MFA and group membership; Kubernetes only validates the token and maps the claims to permissions.
What the API server needs
The API server is configured with three things:
- An issuer URL. The HTTPS URL of the identity provider. Kubernetes fetches the discovery document and the signing keys from it.
- A client ID. The audience that the token must be issued for.
- Optional claim mappings. Which claim is the username, which claim contains groups, and optionally which claim contains the user's UID.
The issuer URL must use HTTPS. Kubernetes will not accept an HTTP issuer, so the identity provider has to be reachable over TLS.
Step 1: create the application in the IdP
In the identity provider, create an application for Kubernetes and note the client ID and client secret. The application needs the authorization code grant for interactive kubectl login; add the client credentials grant if you also want service accounts to obtain tokens.
In Casdoor, create an application and a user in the same organization, and enable the grant types the cluster will use. The token's aud claim must include the client ID you configure on the API server.
Step 2: configure the API server
The flags are:
--oidc-issuer-url=https://<casdoor-host>
--oidc-client-id=<client-id>
--oidc-username-claim=preferred_username
--oidc-groups-claim=groups
How you set them depends on the cluster:
- kubeadm: add the flags under apiServer.extraArgs in the kubeadm configuration.
- minikube: pass them as extra-config flags at start.
- Managed clusters: the cloud provider usually has an OIDC or identity provider setting in its console; use that instead of editing the API server directly.
For a local test with minikube:
minikube start \
--extra-config=apiserver.oidc-issuer-url=https://<casdoor-host> \
--extra-config=apiserver.oidc-client-id=<client-id>
If the identity provider uses a private CA, also set --oidc-ca-file to the CA bundle, otherwise the API server cannot verify the discovery document.
Step 3: get a token for kubectl
The old auth-provider block in kubeconfig was removed from kubectl, so the practical way to log in interactively is kubelogin, an OpenID Connect plugin for kubectl. It opens the browser, completes the authorization code flow with PKCE, and writes the token into the kubeconfig.
Install kubelogin, then configure a user:
kubectl oidc-login setup \
--oidc-issuer-url=https://<casdoor-host> \
--oidc-client-id=<client-id> \
--oidc-client-secret=<client-secret>
The resulting kubeconfig uses the oidc-login credential plugin. When the token expires, kubelogin refreshes it, so the user does not have to sign in again for every command.
For automation, a service account can request a token with the client credentials grant and call the API with an Authorization: Bearer header. That token has no user, so use a dedicated identity and scope its RBAC accordingly.
Step 4: map identities to RBAC
Kubernetes does not read roles from the token. It authenticates the user and groups, then RBAC decides what they can do. A group claim is the useful part: bind a role to a group once, and every member inherits it.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: platform-viewers
subjects:
- kind: Group
name: platform-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
The group name in the binding must match the value in the token exactly. A mismatch is the most common reason a user authenticates successfully but sees "forbidden" on every request.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| API server fails to start with an OIDC error | The issuer URL is not HTTPS, or the API server cannot reach the discovery document. |
| unauthorized: authentication failed | The issuer or client ID does not match the token. Check aud and iss. |
| Authenticated but forbidden | The username or group claim is missing, or the RBAC binding uses a different name. |
| Token works once, then fails | The token expired and kubectl is not refreshing it. Use kubelogin, not a pasted token. |
| Groups are empty | The identity provider does not include groups in the token, or the group claim name is wrong. |
| x509 errors | The API server cannot verify the provider's TLS certificate; set --oidc-ca-file. |
FAQ
Does Kubernetes support SAML? Not directly. The API server speaks OIDC. If your identity provider only speaks SAML, put a broker in front that exposes OIDC, or use an OIDC-capable provider.
Can I use the same identity provider for kubectl and the cluster's workloads? Yes, but keep the identities separate. Human users should use the authorization code flow through kubelogin; workloads should use service accounts or workload identity, not a human's token.
How long should a kubectl token last? Short enough to limit the damage from a stolen token, long enough to avoid constant re-login. Many teams use 1 to 8 hours with refresh through kubelogin.
Do I need a client secret for kubectl? A public client can use PKCE without a secret. A confidential client uses a secret. kubelogin supports both, depending on the provider's application type.
If you want one identity provider for Kubernetes and the rest of your platform, Casdoor supports OIDC, SAML, CAS, LDAP and SCIM. Casdoor Cloud starts at $6.67/month billed yearly for a dedicated instance. See the Casdoor Kubernetes guide for the exact flags.
Sources
- Kubernetes authentication documentation
- Kubernetes RBAC documentation
- kubelogin
- Casdoor Kubernetes integration
- OpenID Connect Core 1.0
Product names are trademarks of their respective owners.