Configure OIDC for workload clusters
This page describes how to make the Kubernetes API servers of the workload clusters that NVIDIA Kubernetes Engine (NVKE) creates accept JSON Web Tokens (JWTs) from OpenID Connect (OIDC) identity providers (IdPs). Do it after Run NVKE end to end on one machine and before you create the workload clusters that need it: a workload cluster keeps the fleet-wide providers it was created with.
A workload cluster’s API server trusts two kinds of provider:
NVKE binds Kubernetes roles only to the management plane’s own identities. A fleet-wide provider authenticates users and grants them nothing: bind roles to its usernames and groups in each cluster with the admin kubeconfig, as described in Access a workload cluster.
Before you begin
-
You have completed Run NVKE end to end on one machine. You run the install and
kubectlcommands on the host you installed from, from the root of the samenvke/checkout, with the site spec,<CLUSTER_NAME>.kubeconfigand, if you installed from one,release.jsonin the directory above it. SetKUBECONFIGforkubectl: -
The shell you run the install from has the
NVKECTL_*variables from Run NVKE end to end on one machine exported, as described in Run NVKE end to end on one machine. -
For each fleet-wide provider you have its issuer URL, the audience its tokens carry, the claims that hold the username and groups, and the certificate authority (CA) certificates that sign its HTTPS certificate. Collect the identity provider values shows how to read the first three from the IdP’s discovery document and a token.
-
The control-plane nodes of your workload clusters reach each provider’s discovery document, and the
jwks_uriit names, over HTTPS. NVKE does not check this. -
The workload clusters that need fleet-wide providers run Kubernetes 1.34 or later. Supported platforms and versions lists the version this release supports.
Add fleet-wide providers
-
Write the providers to a values file named
oidc-values.yaml, in the directory above thenvke/checkout.<AUDIENCE>is theaudvalue of the provider’s tokens. Each provider takes these fields:usernamePrefixandgroupsPrefixmust not start withsystem:,kubeadm:,nke:,nvke:ornvidia:. Give each provider a different prefix, so that its users and groups cannot collide with another provider’s. See Reserved identities for what the API server refuses regardless of the prefix. -
Run the install command from Run NVKE end to end on one machine again, with the same flags and
--values-for controller=../oidc-values.yamladded.The wrapper reads its inputs from the
NVKE_*variables thatenv.shexports. If you passed other values files before, such as../auth-values.yamlfrom Secure the NVKE API or a values file for NVKE telemetry pipeline (NKTP) with--values-for nktp=, pass each of them again with its own--values-forflag: a file you leave out stops applying, and the deploy path’s own values turn API authentication off and send telemetry to the bundled development backend. The chart refuses to render more than five providers. -
Restart the controller so that it reads the new configuration.
The output ends with
successfully rolled out. The controller reads its configuration only when it starts, and the install does not restart it when only the configuration changes. If the rollout does not finish, the controller has refused the configuration and the NVKE API is unavailable until you fix it; see If the controller does not start. -
Create the workload clusters that need the providers, as described in Create a workload cluster. Clusters that already exist keep the providers they were created with.
Turn on the shared provider
The install configures the shared provider for the management cluster’s SPIRE server and leaves it off. nvkeOIDCAuth.issuerURL is https://nke.site-controller.internal, the issuer of SPIRE’s JWTs, and nvkeOIDCAuth.discoveryURL is https://<MANAGEMENT_ADDRESS>:30443/.well-known/openid-configuration, where <MANAGEMENT_ADDRESS> is the management cluster’s virtual IP address (VIP). The API server trusts the CA in the oidc-provider-upstream-ca Secret in the spire-server namespace.
-
Add the shared provider to
oidc-values.yaml. -
Run the install command and restart the controller, as in steps 2 and 3 of Add fleet-wide providers.
Every workload cluster you create from now on has the shared provider. Leave
nvkeOIDCAuth.enabledset totrueafterward: the chart grants the controller read access to the CA Secret only while it is set, and the controller reads that Secret whenever a control-plane node joins a cluster that has the shared provider. -
To turn the shared provider on for a workload cluster that already exists, patch the cluster with
enableOidc: true, as described in Change cluster settings after creation.The change cannot be undone. NVKE updates one control-plane node at a time, and each node’s API server must report ready before the next node starts. The rollout requires a cluster name that is a valid DNS subdomain, because the name is the token audience, and node agents on every control-plane node that support the
PatchAPIServerManifestremote procedure call (RPC).
Verify
-
Confirm that a workload cluster created after step 3 of Add fleet-wide providers accepts a token from a fleet-wide provider. Get an ID token for a test user from the provider, for example with
kubectl oidc-login get-tokenas in Secure the NVKE API, and save the cluster’s CA certificate from its admin kubeconfig.<API_ADDRESS>is the address from Access a workload cluster, and<ID_TOKEN>is the token. The output shows the username asusernamePrefixfollowed by the value ofusernameClaim, such asexample-idp:alice@example.com, and the groups fromgroupsClaim, each withgroupsPrefix, followed bysystem:authenticated.error: You must be logged in to the server (Unauthorized)means the API server rejected the token; see If a token is rejected. -
Confirm that a cluster has the shared provider. On the management cluster, read the mode label of the cluster’s management-plane kubeconfig.
The output is
spirewhen the management plane reaches the cluster with SPIFFE JWTs through the shared provider, andadminwhen it uses the admin kubeconfig. NVKE switches it tospireafter it applies its own role bindings in the cluster. If it staysadminafter the cluster isProvisionedor the rollout succeeds, the controller’s log says why: NVKE could not read thenke-rbacConfigMap innvke-systemor could not apply the role bindings.
How NVKE applies the providers
The chart renders both kinds of provider into nke-controller-config, the ConfigMap in the nke-controller namespace that holds the controller’s settings: nvkeOIDCAuth becomes the oidc.managementOIDCAuth key, with caBundleSecret renamed caBundleSecretRef, and oidc.providers keeps its name. The controller reads the file once, when it starts, and refuses to start when the file is invalid. It takes these settings only from the file: it ignores the NKE_OIDC_AUTH_* environment variables, and the chart refuses to render an env entry that sets one.
NVKE writes a workload cluster’s providers into /etc/kubernetes/oidc/auth-config.yaml on each control-plane node and passes it to the API server with --authentication-config. The two kinds of provider reach the file differently:
- Fleet-wide providers are fixed when the cluster is created. NVKE copies
oidc.providersinto the cluster’s record, andkubeadm init, every later control-plane join and theenableOidcrollout build the file from that copy, so every control-plane node has the same providers. Changingoidc.providersaffects only clusters created afterward. NVKE has no procedure to add, change or remove a fleet-wide provider on an existing cluster. - A cluster created on Kubernetes earlier than 1.34 gets no fleet-wide providers. Its API server cannot read the configuration NVKE renders. The controller logs
Creating cluster without the fleet-wide OIDC providers, and upgrading the cluster later does not add them. - The shared provider’s settings are read when a node joins. Whether a cluster has the shared provider is fixed at creation or by
enableOidc. Its issuer URL, discovery URL and CA bundle come from the controller’s current configuration each time a control-plane node joins, so a changed setting reaches new and replaced control-plane nodes but not existing ones. Do not change them while workload clusters with the shared provider exist.
Reserved identities
For each fleet-wide provider, NVKE adds Common Expression Language (CEL) validation rules to the API server’s configuration. The API server evaluates them after it maps the token’s claims, and rejects a token whose username or any of whose groups:
- starts with
system:,kubeadm:,nke:,nvke:ornvidia:; - starts with
spiffe://<TRUST_DOMAIN>/, where<TRUST_DOMAIN>is the management plane’s SPIFFE trust domain; - equals a user that NVKE’s own role bindings name, such as the management plane’s SPIFFE ID.
A fleet-wide provider therefore cannot sign in a user as a Kubernetes or kubeadm identity, such as a member of the kubeadm:cluster-admins group, or as the management plane, whatever its tokens claim. The shared provider has no such rules, because it is how the management plane authenticates.
If the controller does not start
Read the controller’s log.
The error begins Error loading configuration: invalid controller config and names the provider and the rule it breaks, for example oidc: providers[0] (example-idp): usernamePrefix "system:" is inside the reserved "system:" namespace. Fix oidc-values.yaml, then repeat steps 2 and 3 of Add fleet-wide providers.
If a token is rejected
The API server rejects a fleet-wide provider’s token when:
- the cluster was created before you added the provider, or on Kubernetes earlier than 1.34;
- the token’s
issclaim does not equalissuerURL, or itsaudclaim names none ofaudiences; - the token lacks
usernameClaim, or a claim inrequiredClaimsdoes not hold the required value; - the API server cannot fetch the discovery document or the signing keys, because the network blocks it or
caBundledoes not include the CA that signs the provider’s certificate; - the mapped username or a group is reserved. The API server logs
username uses a reserved prefixorgroups use a reserved prefix.
On a control-plane node, /etc/kubernetes/oidc/auth-config.yaml shows the providers that node’s API server was given.
If turning on the shared provider fails
When an enableOidc rollout fails, nvkectl get clusters <WORKLOAD_CLUSTER> shows STATUS UpdateFailed, and the cause is in the controller’s log. A failure can leave some API servers with the shared provider:
- When a node fails to apply the change, NVKE tries to undo it on the nodes it already updated, restoring each node’s previous configuration. The undo is best-effort.
- When a node fails its readiness check before it is changed, the rollout stops and the nodes already updated keep the change.
- When every node was updated and a later step fails, nothing is undone.
To retry, send the same patch again. Nodes that already have the change are left as they are.
Next steps
- Access a workload cluster, to give the customer the admin kubeconfig they bind roles with.
- Troubleshoot.