Using kubelogin for kubectl Authentication
kubelogin is a kubectl plugin that handles OIDC authentication automatically. Instead of manually managing tokens, kubelogin opens your browser to authenticate and caches the token locally.
What is kubelogin?
kubelogin (also known as kubectl oidc-login) is a credential plugin for kubectl that:
- Implements the Kubernetes exec credential plugin API
- Handles the OIDC authentication flow (Authorization Code + PKCE)
- Caches tokens locally to avoid repeated logins
- Automatically refreshes expired tokens
When you run kubectl get pods, kubelogin:
- Checks for a cached, valid token
- If the token is missing or expired, opens a browser for authentication
- Handles the OAuth2/OIDC flow with Easy OIDC
- Returns the ID token to kubectl
- kubectl includes the token in API requests
Installation
macOS
brew install int128/kubelogin/kubeloginLinux
Download the latest release from GitHub:
# Example for Linux amd64
curl -LO https://github.com/int128/kubelogin/releases/latest/download/kubelogin_linux_amd64.zip
unzip kubelogin_linux_amd64.zip
sudo mv kubelogin /usr/local/bin/Windows
# Using Chocolatey
choco install kubelogin
# Or download from GitHub releasesVerify Installation
kubelogin --versionConfigure kubeconfig
Add a user to your kubeconfig that uses kubelogin:
apiVersion: v1
kind: Config
users:
- name: oidc-user
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubelogin
args:
- get-token
- --oidc-issuer-url=https://auth.example.com
- --oidc-client-id=kubelogin-prod
- --oidc-use-pkce
interactiveMode: IfAvailable
provideClusterInfo: falseThen create a context that uses this user:
contexts:
- context:
cluster: my-cluster
user: oidc-user
name: my-cluster-oidc
current-context: my-cluster-oidcTest Authentication
Run the setup wizard to test authentication:
kubectl oidc-login setup \
--oidc-issuer-url=https://auth.example.com \
--oidc-client-id=kubelogin-prod \
--oidc-use-pkceThis will:
- Open your browser
- Redirect to Google or GitHub (depending on your Easy OIDC configuration)
- After successful login, display your ID token and claims
Expected output:
Opening in existing browser session.
authentication in progress...
## 2. Verify authentication
You got a token with the following claims:
{
"iss": "https://auth.example.com",
"sub": "[email protected]",
"aud": "kubelogin-prod",
"email": "[email protected]",
"email_verified": true,
"groups": ["prod-admins", "devs"],
"exp": 1234567890,
"iat": 1234564290
}
## 3. Bind a cluster role
kubectl create clusterrolebinding oidc-cluster-admin \
--clusterrole=cluster-admin \
--user='https://auth.example.com#[email protected]'Using kubectl with OIDC
Once configured, use kubectl normally:
kubectl get pods
kubectl get nodes
kubectl apply -f deployment.yamlOn first use, kubelogin will open a browser for authentication. Subsequent commands use the cached token until it expires (default 1 hour).
Token Caching
Tokens are cached in ~/.kube/cache/oidc-login/ directory. Each issuer and client_id combination gets its own cache file.
Cache location:
~/.kube/cache/oidc-login/
└── <hash-of-issuer-and-client-id>
└── token.jsonPermissions: Ensure ~/.kube/cache has restrictive permissions (0700) to protect tokens.
Automatic Token Refresh
kubelogin automatically handles token expiry:
- Before each kubectl command, kubelogin checks if the token is still valid
- If expired, it triggers a new authentication flow (opens browser)
- If valid, it returns the cached token immediately
No manual intervention required.
Multiple Clusters
You can configure multiple clusters with different Easy OIDC client IDs:
users:
- name: oidc-prod
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubelogin
args:
- get-token
- --oidc-issuer-url=https://auth.example.com
- --oidc-client-id=kubelogin-prod
- --oidc-use-pkce
- name: oidc-staging
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubelogin
args:
- get-token
- --oidc-issuer-url=https://auth.example.com
- --oidc-client-id=kubelogin-staging
- --oidc-use-pkce
contexts:
- context:
cluster: prod-cluster
user: oidc-prod
name: prod
- context:
cluster: staging-cluster
user: oidc-staging
name: stagingSwitch contexts:
kubectl config use-context prod
kubectl get pods # Uses kubelogin-prod client
kubectl config use-context staging
kubectl get pods # Uses kubelogin-staging clientNon-Interactive Environments (CI/CD)
kubelogin requires a browser for interactive authentication. For CI/CD pipelines, use Kubernetes ServiceAccounts instead:
apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-deploy
namespace: defaultThen bind the ServiceAccount to a Role or ClusterRole, and use its token in the pipeline.
Troubleshooting
“browser did not open”:
- Ensure you’re on a machine with a browser installed
- For remote servers (SSH), kubelogin won’t work—use ServiceAccounts instead
- Check that port
8000is available (kubelogin’s default callback listener)
“failed to get token”:
- Verify Easy OIDC is accessible:
curl https://auth.example.com/.well-known/openid-configuration - Check that the
--oidc-client-idmatches a client configured in Easy OIDC - Ensure the redirect URI
http://localhost:8000is in the client’sdefault_redirect_uris
“token expired” on every command:
- Check system clock is synchronized (use NTP)
- Verify token cache directory exists and is writable:
~/.kube/cache/oidc-login/
“certificate signed by unknown authority”:
- Easy OIDC uses Let’s Encrypt, which should be trusted by default
- If using a custom CA, add
--certificate-authority=<path>to kubelogin args
See Troubleshooting for more issues.
Advanced Options
Change callback port (if 8000 is in use):
args:
- get-token
- --oidc-issuer-url=https://auth.example.com
- --oidc-client-id=kubelogin-prod
- --oidc-use-pkce
- --listen-address=127.0.0.1:18000Don’t forget to update default_redirect_uris in Easy OIDC to ["http://localhost:18000"].
Skip browser opening (display URL instead):
args:
- get-token
- --oidc-issuer-url=https://auth.example.com
- --oidc-client-id=kubelogin-prod
- --oidc-use-pkce
- --skip-open-browserUseful for SSH sessions where you want to copy/paste the URL to your local browser.