Skip to content

kubectl plugin for Keycloak authentication via OAuth 2.0 Device Authorization Grant flow

Notifications You must be signed in to change notification settings

ohauer/kubectl-oidc-login

Repository files navigation

kubectl-oidc-login

A kubectl plugin for authenticating to Kubernetes clusters using Keycloak via OAuth 2.0 Device Authorization Grant flow.

Features

  • Device Flow Authentication - Authenticate on headless systems by entering a code in a browser on another device
  • Dual Authentication Modes - Support both OIDC and direct token injection
  • Automatic Token Refresh - Seamlessly refresh expired tokens
  • Keycloak Setup Automation - Tools and scripts to configure Keycloak programmatically
  • Secure Token Storage - Tokens stored with 0600 permissions
  • Debug Support - Comprehensive debug logging for troubleshooting

Table of Contents

Installation

Download Binary

# Download the latest release
curl -LO https://github.com/ohauer/kubectl-oidc-login/releases/latest/kubectl-oidc-login

# Make it executable
chmod +x kubectl-oidc-login

# Move to PATH
sudo mv kubectl-oidc-login /usr/local/bin/

Verify Installation

kubectl-oidc-login --version

Quick Start

1. Configure Keycloak

Use the automated setup tool:

# Create admin password file
echo "your-admin-password" > ~/keycloak-admin-pass.txt
chmod 600 ~/keycloak-admin-pass.txt

# Initialize Keycloak realm and client
setup-keycloak init \
  -u https://keycloak.example.com \
  -P ~/keycloak-admin-pass.txt

# Create test user
echo "test-user-password" > ~/user-pass.txt
chmod 600 ~/user-pass.txt

setup-keycloak user \
  -u https://keycloak.example.com \
  -P ~/keycloak-admin-pass.txt \
  -n testuser \
  -p ~/user-pass.txt

# Clean up password files
rm -f ~/keycloak-admin-pass.txt ~/user-pass.txt

Or follow the manual setup guide.

2. Configure kubectl-oidc-login

Create ~/.kube/oidc-login-config.yaml:

keycloak:
  issuer_url: https://keycloak.example.com/realms/kubernetes
  client_id: kubectl-oidc

auth:
  mode: oidc  # or "direct" for clusters without OIDC
  auto_refresh: true
  cache_path: ~/.kube/keycloak-tokens

3. Authenticate

kubectl-oidc-login login

Follow the instructions to complete authentication in your browser.

4. Use kubectl

kubectl get pods

Configuration

Configuration File

Location: ~/.kube/oidc-login-config.yaml

keycloak:
  # Keycloak issuer URL (realm URL)
  issuer_url: https://keycloak.example.com/realms/kubernetes
  
  # OAuth2 client ID
  client_id: kubectl-oidc

auth:
  # Authentication mode: "oidc" or "direct"
  # - oidc: Uses OIDC auth provider (requires cluster OIDC configuration)
  # - direct: Injects bearer token directly (works without cluster OIDC)
  mode: oidc
  
  # Enable automatic token refresh
  auto_refresh: true
  
  # Token cache file path
  cache_path: ~/.kube/keycloak-tokens

Command-Line Flags

kubectl-oidc-login [command] [flags]

Global Flags:
  --config string       Config file path (default: ~/.kube/oidc-login-config.yaml)
  --kubeconfig string   Kubeconfig file path (default: ~/.kube/config)
  --user string         Username in kubeconfig (default: keycloak-user)
  --debug               Enable debug output

Authentication Modes

OIDC Mode (Recommended)

Requires Kubernetes API server configured with OIDC flags:

kube-apiserver \
  --oidc-issuer-url=https://keycloak.example.com/realms/kubernetes \
  --oidc-client-id=kubectl-oidc \
  --oidc-username-claim=preferred_username \
  --oidc-groups-claim=groups

Advantages:

  • Tokens validated by Kubernetes API server
  • More secure
  • Standard approach

Direct Token Mode

Works without cluster OIDC configuration.

Advantages:

  • No cluster configuration needed
  • Easier for testing
  • Works with any cluster

Disadvantages:

  • Plugin must handle token refresh
  • Less secure than OIDC mode

Usage

Login

Authenticate via device flow:

kubectl-oidc-login login

Output:

Requesting device code...

Authentication Required
=======================

Please visit the following URL in your browser:

    https://keycloak.example.com/realms/kubernetes/device

And enter this code:

    ABCD-EFGH

Waiting for authentication... (expires in 10 minutes)

Polling for token...
✓ Authentication successful!
Tokens saved to: ~/.kube/keycloak-tokens
✓ Kubeconfig updated (OIDC mode)

You can now use kubectl with user: keycloak-user

Check Status

View authentication status and token expiry:

kubectl-oidc-login status

Output:

Authentication Status
====================
User:         keycloak-user
Mode:         oidc
Issuer:       https://keycloak.example.com/realms/kubernetes
Client ID:    kubectl-oidc
Token Type:   Bearer
Expires At:   2026-01-30T01:00:00+01:00
Valid:        true
Time Left:    45m30s

Refresh Tokens

Manually refresh tokens:

kubectl-oidc-login refresh

Logout

Clear cached tokens and remove user from kubeconfig:

kubectl-oidc-login logout

Debug Mode

Enable debug output for troubleshooting:

kubectl-oidc-login login --debug

Keycloak Setup

Automated Setup

Using Go CLI Tool

# Initialize
setup-keycloak init \
  -u https://keycloak.example.com \
  -r kubernetes \
  -P /path/to/admin-password.txt \
  -c kubectl-oidc

# Create user
setup-keycloak user \
  -u https://keycloak.example.com \
  -r kubernetes \
  -P /path/to/admin-password.txt \
  --username testuser \
  --password-file /path/to/user-password.txt

# Validate
setup-keycloak validate \
  -u https://keycloak.example.com \
  -r kubernetes

Using Shell Script

# Initialize
./scripts/setup-keycloak.sh init \
  -u https://keycloak.example.com \
  -P /path/to/admin-password.txt

# Create user
./scripts/setup-keycloak.sh user \
  -u https://keycloak.example.com \
  -P /path/to/admin-password.txt \
  -n testuser \
  -p /path/to/user-password.txt

# Validate
./scripts/setup-keycloak.sh validate \
  -u https://keycloak.example.com

Manual Setup

See Keycloak Setup Guide for detailed manual configuration instructions.

Troubleshooting

Authentication Fails

Problem: failed to request device code or authentication failed

Solutions:

  • Verify Keycloak URL is correct and accessible
  • Check that realm and client ID match configuration
  • Ensure device flow is enabled on the client
  • Use --debug flag to see detailed error messages
kubectl-oidc-login login --debug

Token Expired

Problem: token expired and auto-refresh disabled

Solutions:

  • Enable auto-refresh in config: auto_refresh: true
  • Manually refresh: kubectl-oidc-login refresh
  • Re-authenticate: kubectl-oidc-login login

kubectl Commands Fail

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

Solutions:

  • Check token status: kubectl-oidc-login status
  • Verify kubeconfig user is set correctly
  • For OIDC mode, ensure cluster is configured with OIDC flags
  • Try direct token mode if OIDC is not configured

Config File Not Found

Problem: failed to load config: failed to read config file

Solutions:

  • Create config file: ~/.kube/oidc-login-config.yaml
  • Use example: cp oidc-login-config.yaml.example ~/.kube/oidc-login-config.yaml
  • Specify custom path: --config /path/to/config.yaml

Device Code Expired

Problem: error: expired_token

Solutions:

  • Device codes expire after 10 minutes
  • Request a new code: kubectl-oidc-login login
  • Complete authentication faster

TLS Certificate Errors

Problem: x509: certificate signed by unknown authority

Solutions:

  • Ensure Keycloak uses valid TLS certificate
  • For private domains with valid certs, add to /etc/hosts
  • Verify certificate chain is complete

Permission Denied

Problem: failed to save token cache: permission denied

Solutions:

  • Check directory permissions: ls -la ~/.kube/
  • Create directory: mkdir -p ~/.kube && chmod 700 ~/.kube
  • Verify file permissions: chmod 600 ~/.kube/keycloak-tokens

Debug Logging

Enable debug mode to see detailed diagnostic information:

# For kubectl-oidc-login
kubectl-oidc-login login --debug

# For setup-keycloak
setup-keycloak init -u https://keycloak.example.com -P pass.txt --debug

# For shell script
./scripts/setup-keycloak.sh init -u https://keycloak.example.com -P pass.txt -d

Documentation

Building from Source

Prerequisites

  • Go 1.25.6 or higher
  • make
  • git

Build

# Clone the repository
git clone https://github.com/ohauer/kubectl-oidc-login.git
cd kubectl-oidc-login

# Build binaries
make build

# Run tests
make test

# Run linter
make lint

# Install locally
make install

Build Targets

make build    # Build both binaries
make test     # Run all tests with coverage
make lint     # Run golangci-lint
make clean    # Remove build artifacts
make install  # Install to /usr/local/bin

Version Information

# Release build
make build
./bin/kubectl-oidc-login --version
# Output: kubectl-oidc-login version 0.1-alpha0

# Development build
VERSION=dev make build
./bin/kubectl-oidc-login --version
# Output: kubectl-oidc-login version dev (built: 2026-01-30_00:30:00, commit: abc1234)

Requirements

  • Go 1.25.6 or higher (for building)
  • Keycloak 26.x
  • Kubernetes cluster (for OIDC mode, cluster must be configured with OIDC flags)
  • Valid HTTPS connection to Keycloak

Security Considerations

  • Tokens stored with 0600 file permissions
  • File-based credential input prevents exposure in process lists
  • All communication over HTTPS
  • TLS certificate validation enabled by default
  • No credentials in logs or command history

License

Apache License 2.0

Contributing

Contributions are welcome! Please ensure:

  • Code follows Go best practices
  • All tests pass: make test
  • Linter passes: make lint
  • Documentation is updated

Support

For issues, questions, or contributions:

About

kubectl plugin for Keycloak authentication via OAuth 2.0 Device Authorization Grant flow

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published