Docs/ Authenticate to Kubernetes with OIDC

Authenticate to Kubernetes with OIDC

Authenticate to Kubernetes clusters using OIDC identity tokens

Static kubeconfig tokens and shared service account credentials are hard to audit and easy to leak. Kubernetes supports OpenID Connect (OIDC) as a first-class authentication method, letting you replace static credentials with short-lived identity tokens.

Vouch acts as an OIDC provider for your Kubernetes clusters. After a YubiKey tap, the CLI fetches an OIDC ID token and presents it to the API server — no cloud-specific plugins, no static tokens, and every kubectl command traces back to a hardware-verified identity.

Using Amazon EKS? EKS has its own token mechanism based on AWS IAM. See Amazon EKS for EKS-specific setup.

How it works

The authentication flow chains three components:

vouch login --> vouch credential k8s --> kubectl
  1. vouch login — The developer authenticates with their YubiKey and receives an OIDC session from the Vouch server.
  2. vouch credential k8s — The CLI requests an OIDC ID token with the audience set to match the cluster’s --oidc-client-id (default: kubernetes). It outputs a Kubernetes ExecCredential JSON object containing the token and its expiration.
  3. kubectl — The Kubernetes client sends the token to the API server. The API server validates it against the Vouch server’s OIDC discovery endpoint (/.well-known/openid-configuration) and applies RBAC rules based on the token claims.

Because every step uses short-lived credentials, there are no static kubeconfig tokens to manage or rotate.


Prerequisites

Before setting up Kubernetes OIDC authentication with Vouch, ensure you have:

  • Vouch CLI installed and enrolled — Complete the Getting Started guide.
  • kubectl installed (kubectl version --client).
  • A Kubernetes cluster with OIDC authentication configured on the API server (see below).

Configuring the API server

The Kubernetes API server must be configured to trust the Vouch server as an OIDC provider. Add the following flags to your kube-apiserver configuration:

--oidc-issuer-url=https://us.vouch.sh
--oidc-client-id=kubernetes
--oidc-username-claim=sub
FlagDescription
--oidc-issuer-urlThe Vouch server URL. The API server fetches /.well-known/openid-configuration from this URL to discover the JWKS endpoint.
--oidc-client-idThe expected aud (audience) claim in the ID token. Must match the --audience flag used with vouch credential k8s (default: kubernetes).
--oidc-username-claimThe token claim to use as the Kubernetes username. Set to sub to use the developer’s email address.
--oidc-groups-claim(Optional) The token claim to use for group membership in RBAC rules.
--oidc-username-prefix(Optional) Prefix added to usernames to avoid collisions with other authentication methods (e.g., vouch:).

How you set these flags depends on your Kubernetes distribution:

  • kubeadm: Add to ClusterConfiguration.apiServer.extraArgs in the kubeadm config.
  • k3s: Pass as arguments to k3s server, e.g., k3s server --kube-apiserver-arg="oidc-issuer-url=https://us.vouch.sh".
  • GKE: Use GKE Identity Service to configure OIDC.
  • AKS: Use AKS OIDC configuration.

Important: The API server must be able to reach https://us.vouch.sh/.well-known/openid-configuration and the JWKS endpoint to validate tokens. Ensure your network policies allow outbound HTTPS from the control plane to the Vouch server.


Setup

Configure kubectl to use your Vouch-backed OIDC credentials:

vouch setup k8s \
  --cluster my-cluster \
  --server https://k8s.example.com:6443 \
  --certificate-authority /path/to/ca.pem

Required flags:

FlagDescription
--clusterA name for this cluster (used in kubeconfig entries and as a cache key)
--serverThe Kubernetes API server URL

Optional flags:

FlagDescription
--certificate-authorityPath to the cluster’s CA certificate file (PEM format). The certificate is base64-encoded and embedded in the kubeconfig.
--audienceOIDC audience — must match --oidc-client-id on the API server (default: kubernetes)
--kubeconfigPath to kubeconfig file (defaults to ~/.kube/config)

This command writes or updates your kubeconfig with:

  • A cluster entry named after the --cluster value with the server URL and CA certificate.
  • A user entry named vouch-k8s-{cluster} configured to call vouch credential k8s as an exec-based credential plugin.
  • A context named {cluster}-vouch linking the cluster and user entries.

Verify the kubeconfig

Check that the context is set and working:

kubectl config use-context my-cluster-vouch
kubectl get pods

Usage

With everything configured, daily usage is straightforward:

# Start your day
vouch login

# Switch to your Vouch K8s context
kubectl config use-context my-cluster-vouch

# Use kubectl as normal
kubectl get pods
kubectl get namespaces
kubectl logs deployment/my-app

All authentication happens transparently. The exec credential plugin fetches a fresh OIDC token for each kubectl invocation. If your session expires (after 8 hours), run vouch login again.


RBAC configuration

With OIDC authentication, the Kubernetes username is the developer’s email address (from the sub claim). Use standard Kubernetes RBAC to map users to permissions.

Cluster-wide admin access

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: vouch-cluster-admin
subjects:
  - kind: User
    name: alice@example.com
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

Namespace-scoped access

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: vouch-developer-edit
  namespace: staging
subjects:
  - kind: User
    name: bob@example.com
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io

Group-based access

If you configure --oidc-groups-claim on the API server, you can assign permissions by group:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: vouch-team-viewers
subjects:
  - kind: Group
    name: engineering@example.com
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

Troubleshooting

“error: You must be logged in to the server (Unauthorized)”

  • Confirm you have an active Vouch session: vouch status.
  • Verify the API server has OIDC configured and can reach the Vouch server’s OIDC discovery endpoint.
  • Check that the --oidc-client-id on the API server matches the --audience used during setup (default: kubernetes).
  • Inspect the token: vouch credential k8s --cluster my-cluster and decode the JWT to check the aud and iss claims.

“Unable to connect to the server”

  • Verify the API server URL: kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'.
  • Check that the CA certificate is correct if connecting to a cluster with a private CA.
  • Ensure your network allows connections to the API server endpoint.

“No active session”

  • Run vouch login to authenticate with your YubiKey.

Token audience mismatch

  • The --audience flag in vouch setup k8s and vouch credential k8s must match the --oidc-client-id flag on the kube-apiserver. The default for both is kubernetes.
  • If you used a custom audience during setup, verify with: kubectl config view --raw -o jsonpath='{.users[?(@.name=="vouch-k8s-my-cluster")].user.exec.args}'.

Diagnosing configuration issues

  • Run vouch doctor to check your Vouch configuration.
  • Check API server logs for OIDC validation errors — common issues include the API server being unable to fetch the JWKS endpoint or a clock skew causing token validation failures.