Skip to content

Bring your own identity provider

The short-lived admin kubeconfig is ideal for bootstrap, automation, and break-glass access. For day-to-day team access, you can connect your own OpenID Connect (OIDC) identity provider instead: your cluster’s API server then trusts logins from your IdP — Entra ID, Okta, Keycloak, Auth0, Google, or any other OIDC-compliant provider.

What you gain over shared kubeconfigs:

  • Named userskubectl actions are attributable to a person, not to “whoever held the kubeconfig”.
  • Your access rules — RBAC bound to your IdP’s users and groups, your MFA policy, your session lifetimes.
  • Instant offboarding — disable the account in your IdP and cluster access stops with it.

Your identities stay entirely in your IdP — paasbox only configures your cluster to trust it, and never sees your users or their credentials.

Availability. During early access, BYO-IdP is enabled per cluster by support — send us the values from step 2 and we’ll apply them. Self-service configuration in the console is planned.

paasbox configures your cluster’s API server (via Gardener’s structured authentication) to accept ID tokens from your issuer. Tokens are mapped to Kubernetes identities like this:

Token claimKubernetes identity
emailusername oidc:alice@example.com
groups claim (optional)groups oidc:<group>, e.g. oidc:platform-team

The oidc: prefix keeps your users cleanly separated from system identities. You then grant permissions with ordinary RBAC (step 3). The admin kubeconfig keeps working alongside — it stays your break-glass path.

Create a native / public client (Authorization Code + PKCE) in your identity provider:

  • Redirect URIs: http://localhost:8000 and http://localhost:18000 (the local callback ports the kubectl login plugin listens on).
  • Scopes: openid, email, profile — plus offline_access if your IdP requires it for refresh tokens.
  • Note the issuer URL and the client ID.

The issuer must be reachable over public HTTPS. Verify:

Terminal window
curl https://<your-issuer>/.well-known/openid-configuration

Some providers only issue clients with a secret. That works too — but the secret ends up in every team member’s kubeconfig, so prefer a public PKCE client when your IdP offers one.

Send support (or, later, enter in the console) for the cluster:

  • Issuer URL — exactly as it appears in the discovery document, including any trailing slash.
  • Client ID — becomes the accepted token audience.
  • Groups claim (optional) — e.g. groups, if you want group-based RBAC.

The change is applied as a control-plane update and takes effect within a few minutes; your workloads are not affected. On high-availability clusters the API server rolls with no downtime; on non-HA clusters expect a brief API interruption (seconds to a minute) while the change applies — the same holds for later changes or removal of this configuration.

OIDC users have no permissions until you grant them. Using your admin kubeconfig, bind roles to the mapped identities — read-only for one user:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-viewer-alice
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: oidc:alice@example.com

or admin for a whole IdP group:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-admin-platform-team
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: oidc:platform-team

Team members install the kubelogin plugin once:

Terminal window
kubectl krew install oidc-login # or: brew install kubelogin

Then use a kubeconfig whose cluster section is copied from any downloaded paasbox kubeconfig (it carries the API server URL and CA), with an OIDC user instead of the certificate:

apiVersion: v1
kind: Config
clusters:
- name: my-cluster # copy this block from your downloaded kubeconfig
cluster:
server: https://api.<your-cluster-domain>
certificate-authority-data: <copied>
contexts:
- name: my-cluster-oidc
context: { cluster: my-cluster, user: oidc }
current-context: my-cluster-oidc
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=https://<your-issuer>
- --oidc-client-id=<client-id>
- --oidc-extra-scope=email,profile

This file contains no secret (with a public client) — it’s safe to commit to your team’s dotfiles or onboarding repo.

The first kubectl call opens a browser for login, then caches the token:

Terminal window
kubectl auth whoami # attributes: oidc:alice@example.com
kubectl auth can-i list pods # yes (per your RBAC)
kubectl get pods -A
  • invalid issuer / audience errors — the issuer URL must match the discovery document character for character (trailing slash included), and the client ID you registered must be the token’s audience.
  • Stale login — clear the token cache with rm -rf ~/.kube/cache/oidc-login and log in again.
  • Unauthorized despite a successful login — usually missing RBAC (step 3), or the username claim doesn’t match the binding — check with kubectl auth whoami using the admin kubeconfig equivalent, or re-check the subject name including the oidc: prefix.
  • Groups don’t work — make sure your IdP actually puts the groups claim in the ID token (some providers need this enabled per client), and that you told us the claim name in step 2.
  • Login rejected even though RBAC is correct — because your email is the username, the API server rejects tokens where the IdP reports email_verified: false. Make sure the account’s email address is verified in your IdP.
  • Login succeeds but cluster access is denied — the ID token must actually contain the email claim, and some providers only include it with an explicit per-application setting (Zitadel: “User Info inside ID Token”; check your provider’s equivalent). Requesting the email scope alone isn’t always enough.
  • Login succeeds at the IdP but never returns to the terminal (kubelogin eventually fails with context deadline exceeded) — most IdPs can require users to be explicitly assigned to an application before it may issue them tokens (Entra ID “user assignment required”, Okta app assignments, Zitadel project authorization checks). Assign the user to the client you registered in step 1. Also check nothing else on your machine is occupying the callback port — kubelogin listens on localhost:8000/18000.
  • Offboarding: disable the user in your IdP — new logins and token refreshes stop immediately. Remember they may also hold a portal account that can issue admin kubeconfigs; remove that too.
  • Break-glass: keep the admin kubeconfig path for emergencies — if your IdP is down, OIDC logins are too.