OpenID Connect (OIDC) allows Kubernetes users to authenticate using an external identity provider instead of static certificates or manually managed credentials. With OIDC authentication, you can log into your clusters managed by Syself Autopilot using existing organizational accounts while Kubernetes delegates authentication to a trusted identity provider. This approach simplifies access management and improves security for production Kubernetes environments: users authenticate with short-lived tokens instead of long-lived certificates or static kubeconfigs. ## Choosing an OIDC provider Before configuring Kubernetes OIDC authentication, you need an identity provider that supports OpenID Connect. Common options include: - Microsoft Entra ID (Azure AD) - Google Workspace - Keycloak - Okta - Authentik For self-hosted environments, Syself commonly recommends [Authentik](https://goauthentik.io/). It provides OpenID Connect support, user management, group synchronization, and Single Sign-On capabilities in a modern self-hosted platform. The identity provider is responsible for authenticating users and issuing the tokens Kubernetes uses for authentication and authorization. You also need to register an OIDC client (an application) for the cluster in your provider. From that client you get the two values used below: the **issuer URL** and the **client ID**. ## Implementing OIDC Authentication To enable OIDC authentication and authorization for your cluster, you need to set a couple of flags in the Kubernetes' API Server. To do this, set the variables below under `spec.topology.variables` in your Cluster resource: ```yaml - name: oidcIssuerUrl value: https://your.oidc-issuer.com - name: oidcClientID value: 123456789098765432@cluster-1 - name: oidcUsernameClaim value: sub - name: oidcGroupsClaim value: groups ``` Applying these variables triggers a control-plane rollout, since they change the API server configuration. The `oidcGroupsClaim` maps a claim in the token to Kubernetes groups, so you can grant access to a whole group with RBAC. Without it, the group binding below has nothing to match. ## Create and bind roles You are now ready to configure Cluster Roles. This sample role grants read-write access to pods and services: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: my-role rules: - apiGroups: [""] resources: ["pods", "services"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ``` And bind this role to a group in your OIDC provider: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: cluster-admins-binding subjects: - kind: Group name: my-group roleRef: kind: ClusterRole name: my-role apiGroup: rbac.authorization.k8s.io ``` ## Accessing the cluster Kubernetes does not automatically perform browser-based OIDC authentication for clients, such as kubectl. To simplify the authentication flow, we recommend using `kubelogin`, which handles token retrieval and automatically refreshes credentials when needed. You can use one of the following commands to install `kubelogin` ```console title="macOS, Linux, Windows, and ARM" $ kubectl krew install oidc-login ``` ```console title="Windows" $ choco install kubelogin ``` Alternatively, you can install it from a Github release. Then you need to make sure that it is in your path as `kubectl-oidc_login`. Now you need to change your `kubeconfig` file to authenticate using `kubelogin`. Add the snippet below to it: ```yaml users: - name: oidc user: exec: apiVersion: client.authentication.k8s.io/v1beta1 args: - oidc-login - get-token - --oidc-issuer-url=https://your.oidc-issuer.com - --oidc-client-id=123456789098765432@cluster-1 - --oidc-extra-scope=groups command: kubectl ``` The next time you run `kubectl` you'll be prompted to authenticate with your OIDC provider. ## Verify Confirm the token resolved to the identity and groups you expect: ```console $ kubectl auth whoami ``` The output shows the username and the groups the OIDC token carried. They should match what your RBAC bindings grant. ## Common Unauthorized causes - **Issuer URL mismatch.** `oidcIssuerUrl` must exactly match the `iss` claim in the token, including scheme and any trailing slash. - **Wrong client ID.** `oidcClientID` must match the client registered in your identity provider. - **Claim not in the token.** The claim named by `oidcUsernameClaim` or `oidcGroupsClaim` must be present. If groups are missing, the token was issued without the groups scope (see `--oidc-extra-scope=groups` above). - **No matching RBAC.** The user or group resolved, but no `ClusterRoleBinding` or `RoleBinding` grants it access. - **Expired token.** Re-authenticate; `kubelogin` refreshes tokens automatically. ## Related - [Access a cluster through a domain](/docs/hetzner/apalla/clusters/configure/access-through-a-domain), give the API server a stable domain name - [Headless access](/docs/hetzner/apalla/clusters/gitops/headless-access), non-interactive access for CI where the browser flow does not fit