An article published on the CNCF blog recommends treating access control for Kubernetes clusters as part of the basic configuration checklist, alongside networking and storage, particularly in self-hosted environments that typically do not provide ready-made IAM or SSO integration as managed Kubernetes services do. The central idea is to use an OIDC-compliant identity provider, such as Keycloak, while registering the client as a public client that uses PKCE, rather than as a confidential client carrying a shared secret.
In many local clusters, access relies on a static client certificate or a long-lived token issued once. These credentials remain valid even after an employee leaves, changes roles, or loses the device containing them. Revoking access also requires finding every copy of the certificate or token, a process whose completeness is difficult to guarantee when devices and users multiply. As the number of people grows and permission levels differ, distributing and managing files becomes a continuous operational task.
What Changes with OIDC?
Instead of tying authorization to a certificate file, it becomes linked to the user's account and membership in identity-provider groups. The integration consists of three interconnected parties: the kubectl tool with the kubelogin or kubectl oidc-login plugin, the identity provider that authenticates the user and issues the ID token, and the kube-apiserver, which verifies the token and extracts the username and groups, then leaves Kubernetes RBAC to determine the permitted operations.
kubectl does not first connect to the API server to start the login. Instead, the exec-credential plugin launches browser-based login with the identity provider, then returns the ID token to kubectl so it can be sent as bearer-token credentials. The API server verifies the token using the identity provider's public signing keys. According to the article, the server does not need a continuous connection to the identity provider, except to fetch those keys when necessary.
Why Should the Client Be Public?
A confidential client issues a secret that is added to kubelogin plugin settings and distributed to every device that needs access. The article argues that a secret that must be distributed to all clients is no longer truly secret; instead, it is a shared static credential that is difficult to rotate. For command-line and native applications, the more appropriate choice is a public client without a secret, with PKCE, or Proof Key for Code Exchange, enabled.
The client locally generates a random value and sends a hash of it in the initial login request, then proves possession of the original value when exchanging the authorization code for an access token. Therefore, someone who intercepts the authorization code alone cannot complete the process. The Keycloak settings described in the article recommend disabling client authentication, enabling the standard flow, disabling direct access grants, and enforcing PKCE with S256, while restricting redirect URIs and web origins to loopback addresses such as 127.0.0.1 and localhost.
Basic Configuration Steps
- Add the group-membership mapper to the client scope in Keycloak so that a claim named groups appears in the ID token.
- Configure kube-apiserver using flags such as oidc-issuer-url, oidc-client-id, oidc-username-claim, and oidc-groups-claim.
- Add oidc-ca-file if the identity provider uses a certificate that is not signed by a publicly trusted authority, so the API server can verify the TLS connection and fetch the signing keys.
- Modify kubeconfig to use an exec-credential entry through kubectl oidc-login instead of embedding certificates or static tokens, without adding a secret field.
- Map identity-provider groups to Kubernetes RBAC roles, such as mapping the platform-viewer group to the view role.
Practical Impact and Limitations
After this integration, access changes are made within the identity provider: adding a user to or removing a user from a group, rather than modifying the cluster or redistributing kubeconfig. The next token issued to the user receives the new group membership, so the associated RBAC rule is applied. The article explains that the first login opens the browser, while kubelogin reuses the cached token until it expires, then uses the refresh token without another browser round trip. The actual identity and groups can be verified with the kubectl auth whoami command.
This does not mean that the integration is free of operational requirements. The group claim must be configured precisely, the identity provider's certificate must be verified, redirect URIs must be restricted, and RBAC roles must be checked to ensure they reflect the required permissions. The article also does not provide independent measurements of setup time or operating cost; it estimates that preparation may be completed within a single work period, rather than through a full platform migration.
The main security and administrative benefit is that Kubernetes logs become associated with the user's actual identity. Logs that rely on a shared account such as cluster-admin do not distinguish between request executors, whereas every request issued through OIDC carries the username and associated groups. This is an editorial reading based on the article's details: the improvement is not only in the login method, but also in the ability to attribute actions to their owners, while making permission grants and revocations a centralized identity process instead of a search for distributed credential files.