Access control belongs on the same day-zero checklist as networking and storage. Managed cloud Kubernetes ships IAM or SSO integration out of the box. Self-hosted clusters don't. Access defaults to a static client certificate or a long-lived token, issued once and rarely revisited. That certificate keeps working long after the person it was issued to has left, changed roles, or lost the device it lives on. Nothing in the cluster's authentication path checks whether they should still have access. Revoking it means finding every copy of a file, and in practice, that doesn't happen completely.

The moment more than one or two people need different levels of access, managing that per person, per file, becomes its own ongoing job. Put an identity provider (Keycloak or any OIDC-compliant provider) in front of the cluster instead. Access should follow an account and its group membership, not a certificate file. Configure it with a public OIDC client using PKCE, not a confidential client with a secret. Access changes become identity operations: add someone to a group, remove someone from a group. No file distribution required.

The integration has three components that need to agree with each other: kubectl authenticates against the identity provider, then presents the resulting token to kube-apiserver, which validates it and hands it off to RBAC. kubectl never talks to the API server first. A kubectl exec-credential plugin (kubelogin, also distributed as "kubectl oidc-login") intercepts the request, drives the browser-based login against the IdP, and hands the resulting ID token back to kubectl as a bearer credential. The API server validates that token directly against the IdP's public signing keys.

It never needs network access to the IdP itself beyond fetching those keys once. Configure this client as public, not confidential. A confidential client issues a client secret, which then gets pasted into the kubelogin plugin config, and ships to every machine that needs cluster access. A secret that has to be distributed to every client that uses it isn't functioning as a secret. It's a shared static credential with extra steps, and rotating it means a coordinated config push to every machine rather than disabling one compromised identity. 1 already settles this for native and command-line applications.