- Go 92.3%
- Just 7.7%
| internal | ||
| .gitignore | ||
| go.mod | ||
| justfile | ||
| main.go | ||
| README.md | ||
kubectl-oidc-device
A kubectl exec plugin that authenticates against an OIDC provider using the
RFC 8628 device authorization grant. It exists for machines that have no
local browser — SSH sessions, provisioned VMs, containers — where the usual
kubelogin authorization-code flow (which redirects to http://localhost:PORT)
can't work.
The plugin prints a URL and a short code to stderr; you open the URL on any
device with a browser, log in, approve, and the plugin's polling receives the
token set and emits a kubectl ExecCredential on stdout.
kubectl oidc-device get-token --oidc-issuer-url=... --oidc-client-id=...
Install
go install git.navicore.tech/navicore/kubectl-oidc-device@latest
Ensure $GOPATH/bin (or $GOBIN) is on your $PATH. kubectl auto-discovers
any binary named kubectl-* as a plugin, so kubectl-oidc-device becomes
kubectl oidc-device.
kubeconfig
Use it exactly like kubelogin, but swap the exec.command and drop the
redirect_uri (device-flow clients have no redirect target):
apiVersion: v1
kind: Config
clusters:
- cluster:
server: https://k8s-api.example.com
insecure-skip-tls-verify: true # or a CA bundle
name: homelab
contexts:
- context:
cluster: homelab
user: oidc-device
name: homelab
current-context: homelab
users:
- name: oidc-device
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl-oidc-device
args:
- get-token
- --oidc-issuer-url=https://auth.example.com/realms/homelab
- --oidc-client-id=kubectl-oidc-device
- --oidc-extra-scope=groups
interactiveMode: IfAvailable
Token cache
id_token + refresh_token are cached at
~/.kube/cache/oidc-device/<sha256(issuer|client)> (mode 0600, dir 0700). On
each invocation the plugin:
- returns the cached id_token if it has >30s of life left
- else tries the
refresh_tokengrant silently (no browser) - else runs the interactive device flow
This mirrors kubelogin's caching behavior, so refresh + re-login cadence
feels the same on both flows.
Server requirements
The OIDC provider must advertise a device_authorization_endpoint and support
the urn:ietf:params:oauth:grant-type:device_code grant (RFC 8628), with PKCE
S256. The client must be registered for device flow. This plugin contains
nothing anz-specific; any compliant provider works.
The k8s API server must list the device-flow client_id in its
--oidc-client-id (or accept it via --oidc-required-claim/audiences) so
tokens minted by this plugin validate the same way kubelogin tokens do.
Flags
| Flag | Required | Description |
|---|---|---|
--oidc-issuer-url |
yes | OIDC issuer URL (e.g. https://auth.example.com/realms/homelab) |
--oidc-client-id |
yes | OAuth client_id registered for device flow |
--oidc-extra-scope |
no | extra scope to request (repeatable; openid is always included) |
--oidc-client-secret |
no | client_secret for confidential clients (public clients omit) |
Build from source
just build # → ./bin/kubectl-oidc-device
just test # unit tests
just ci # fmt-check + vet + test + build
just install # go install into $GOPATH/bin