Cloud Computing Kubernetes Security

Easy-OIDC: Simplify Kubernetes Authentication with a Minimal OIDC Server

Introduction

Managing user authentication in Kubernetes clusters can be complex and time-consuming. Traditional approaches require managing passwords, certificate authorities, or integrating with heavyweight identity providers. Easy-OIDC changes this paradigm by offering a minimal, single-binary OIDC (OpenID Connect) server designed specifically for Kubernetes environments.

Whether you’re a DevOps engineer managing production clusters or a developer setting up local Kubernetes, Easy-OIDC eliminates authentication complexity while maintaining security. It delegates authentication to providers you already use—GitHub, Google, or any OAuth2/OIDC provider—making it perfect for teams that want simple, secure access control without the operational overhead.

What is OIDC? (For Everyone)

OIDC (OpenID Connect) is an authentication layer built on top of OAuth 2.0. Think of it as a universal “login with” system that allows applications to verify your identity through trusted providers.

How It Works (Simple Analogy)

Imagine you’re entering a secured building (your Kubernetes cluster). Instead of the building maintaining its own ID cards and access lists, it trusts a verification service (like GitHub or Google). You show your ID to the verification service, they confirm who you are, and the building grants you access based on your verified identity.

Why Kubernetes Needs OIDC

Kubernetes doesn’t have built-in user management. It relies on external identity providers to:

  • Authenticate who you are
  • Authorize what you can do (via Role-Based Access Control)
  • Audit what actions were performed

Why Easy-OIDC? The Problem It Solves

Traditional OIDC implementations like Dex, Keycloak, or Auth0 are powerful but often overkill for many use cases. They require:

  • Complex configuration and maintenance
  • External databases (PostgreSQL, MySQL)
  • Multiple components and services
  • Significant compute resources

Easy-OIDC takes a different approach:

# Traditional Setup vs Easy-OIDC
Traditional OIDC Stack:
  - Identity Provider (Keycloak/Dex)
  - External Database (PostgreSQL)
  - Redis Cache
  - Load Balancer
  - Multiple VMs
  - Cost: $200-500/month

Easy-OIDC Stack:
  - Single binary (Go)
  - Embedded SQLite
  - Automatic TLS (Caddy)
  - One EC2 t3.micro
  - Cost: $8-15/month

Key Benefits

  1. Zero Password Management: Delegates to GitHub, Google, or any OAuth2+UserInfo/OIDC provider
  2. Static Group Overrides: Map users to Kubernetes groups via simple JSONC configuration
  3. PKCE-Only Security: Uses Proof Key for Code Exchange—no client secrets to leak
  4. Single Binary: No external dependencies, embedded SQLite database
  5. Ed25519 Signing: State-of-the-art cryptographic signing for JWTs

Architecture: How Easy-OIDC Works

Easy-OIDC follows a streamlined architecture designed for simplicity and security:

graph TB
    subgraph "User Workstation"
        A[kubectl + kubelogin]
    end
    
    subgraph "Cloud Infrastructure"
        B[Caddy Reverse Proxy<br/>:443 HTTPS]
        C[Easy-OIDC Server<br/>:8080 HTTP]
        D[(SQLite<br/>Embedded DB)]
        E[Secrets Manager<br/>AWS/GCP/Azure]
    end
    
    subgraph "Identity Providers"
        F[GitHub OAuth]
        G[Google OAuth]
        H[Generic OIDC/OAuth2]
    end
    
    A -->|1. Login Request| B
    B -->|2. Forward| C
    C -->|3. Store State| D
    C -->|4. Fetch Secrets| E
    C -->|5. Redirect to Provider| F
    C -->|5. Redirect to Provider| G
    C -->|5. Redirect to Provider| H
    F -->|6. User Authentication| C
    G -->|6. User Authentication| C
    H -->|6. User Authentication| C
    C -->|7. Issue JWT Token| A
    
    style A fill:#e1f5ff
    style C fill:#ffebee
    style B fill:#f3e5f5
    style D fill:#fff3e0
    style E fill:#e8f5e9
Identity Providers
Cloud Infrastructure
User Workstation
1. Login Request
2. Forward
3. Store State
4. Fetch Secrets
5. Redirect to Provider
5. Redirect to Provider
5. Redirect to Provider
6. User Authentication
6. User Authentication
6. User Authentication
7. Issue JWT Token
GitHub OAuth
Google OAuth
Generic OIDC/OAuth2
Caddy Reverse Proxy
:443 HTTPS
Easy-OIDC Server
:8080 HTTP
SQLite
Embedded DB
Secrets Manager
AWS/GCP/Azure
kubectl + kubelogin

Architecture Components

Caddy Reverse Proxy: Handles TLS termination with automatic Let’s Encrypt certificates, eliminating manual certificate management.

Easy-OIDC Server: A Go binary that implements the OIDC protocol, manages authentication flows, and issues JWT tokens. It stores OAuth state and authorization codes in an embedded SQLite database with replay protection.

Secrets Manager Integration: Retrieves sensitive configuration (client IDs, signing keys) from cloud-native secret stores like AWS Secrets Manager, ensuring credentials are never hardcoded.

Identity Provider Federation: Delegates actual authentication to GitHub, Google, or any OAuth2/OIDC-compatible provider, allowing users to log in with existing credentials.

Configuration: Setting Up Your OIDC Server

Easy-OIDC uses a simple JSONC (JSON with comments) configuration file. Here’s a complete example:

{
  // Basic server configuration
  "issuer": "https://oidc.example.com",
  "listen_address": ":8080",
  
  // Kubernetes cluster configuration
  "clusters": [
    {
      "name": "production-cluster",
      "api_server": "https://k8s-api.example.com"
    }
  ],
  
  // GitHub authentication provider
  "providers": {
    "github": {
      "client_id": "your-github-oauth-app-client-id",
      "client_secret_env": "GITHUB_CLIENT_SECRET",
      "allowed_organizations": ["your-org-name"]
    },
    
    // Optional: Google authentication
    "google": {
      "client_id": "your-google-client-id.apps.googleusercontent.com",
      "client_secret_env": "GOOGLE_CLIENT_SECRET",
      "allowed_domains": ["example.com"]
    }
  },
  
  // Static group mappings
  "groups": {
    "cluster-admins": [
      "alice@example.com",
      "bob@example.com"
    ],
    "developers": [
      "carol@example.com",
      "dave@example.com"
    ],
    "viewers": [
      "eve@example.com"
    ]
  },
  
  // JWT signing configuration
  "signing": {
    "algorithm": "EdDSA",
    "key_env": "OIDC_SIGNING_KEY"
  }
}

Environment Variables

Create a .env file for sensitive configuration:

# GitHub OAuth credentials
GITHUB_CLIENT_SECRET=ghp_your_github_client_secret_here

# Google OAuth credentials (optional)
GOOGLE_CLIENT_SECRET=GOCSPX-your_google_client_secret

# Ed25519 signing key (base64 encoded)
OIDC_SIGNING_KEY=your_base64_encoded_ed25519_private_key

Kubernetes RBAC Configuration

Map the OIDC groups to Kubernetes roles:

# ClusterRoleBinding for cluster-admins group
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: oidc-cluster-admins
subjects:
- kind: Group
  name: cluster-admins
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
# RoleBinding for developers group (namespace-scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: oidc-developers
  namespace: development
subjects:
- kind: Group
  name: developers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io

Authentication Flow: Behind the Scenes

Here’s what happens when a user authenticates with Easy-OIDC:

sequenceDiagram
    participant User
    participant kubectl
    participant EasyOIDC
    participant GitHub
    participant K8sAPI as Kubernetes API
    
    User->>kubectl: kubectl get pods
    kubectl->>EasyOIDC: 1. Initiate OIDC flow
    EasyOIDC->>EasyOIDC: 2. Generate PKCE code_verifier
    EasyOIDC->>User: 3. Redirect to browser
    User->>GitHub: 4. Login with GitHub
    GitHub->>User: 5. Authorize application
    User->>EasyOIDC: 6. Authorization code + state
    EasyOIDC->>GitHub: 7. Exchange code for token<br/>(with code_verifier)
    GitHub->>EasyOIDC: 8. Access token + user info
    EasyOIDC->>EasyOIDC: 9. Map user to groups<br/>Sign JWT with Ed25519
    EasyOIDC->>kubectl: 10. Return ID token (JWT)
    kubectl->>K8sAPI: 11. API request with JWT
    K8sAPI->>K8sAPI: 12. Verify JWT signature<br/>Check RBAC permissions
    K8sAPI->>kubectl: 13. Response (allowed/denied)
    kubectl->>User: 14. Display results
UserkubectlEasyOIDCGitHubKubernetes APIkubectl get pods1. Initiate OIDC flow2. Generate PKCE code_verifier3. Redirect to browser4. Login with GitHub5. Authorize application6. Authorization code + state7. Exchange code for token(with code_verifier)8. Access token + user info9. Map user to groupsSign JWT with Ed2551910. Return ID token (JWT)11. API request with JWT12. Verify JWT signatureCheck RBAC permissions13. Response (allowed/denied)14. Display resultsUserkubectlEasyOIDCGitHubKubernetes API

Flow Breakdown

Steps 1-3: When you run kubectl, it detects missing credentials and initiates the OIDC flow through kubelogin, opening your browser.

Steps 4-6: You authenticate with your identity provider (GitHub, Google, etc.) and authorize the application.

Steps 7-9: Easy-OIDC exchanges the authorization code for user information, maps you to configured groups, and signs a JWT token with Ed25519.

Steps 10-14: Your kubectl client receives the JWT, includes it in API requests, and Kubernetes validates it against RBAC policies.

Quick Setup: Deploy in Minutes

Prerequisites

# Install kubelogin (OIDC kubectl plugin)
kubectl krew install oidc-login

# Or via Homebrew (macOS)
brew install int128/kubelogin/kubelogin

# Or download binary directly
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/

Deploy with Docker

# Create configuration directory
mkdir -p ~/easy-oidc/config
cd ~/easy-oidc

# Create config.jsonc (use example from Configuration section)
nano config/config.jsonc

# Create .env file with secrets
nano .env

# Run Easy-OIDC with Docker
docker run -d \
  --name easy-oidc \
  -p 8080:8080 \
  -v $(pwd)/config:/config \
  --env-file .env \
  ghcr.io/easy-oidc/easy-oidc:latest \
  --config /config/config.jsonc

Deploy on AWS with Terraform

For production deployments, use the official Terraform module:

# main.tf
module "easy_oidc" {
  source  = "easy-oidc/easy-oidc/aws"
  version = "~> 1.0"

  domain_name          = "oidc.example.com"
  route53_zone_id      = "Z1234567890ABC"
  instance_type        = "t3.micro"
  
  github_client_id     = "your-github-client-id"
  github_organizations = ["your-org"]
  
  group_mappings = {
    cluster-admins = ["alice@example.com", "bob@example.com"]
    developers     = ["carol@example.com"]
  }
}

output "oidc_issuer_url" {
  value = module.easy_oidc.issuer_url
}
# Initialize and apply Terraform
terraform init
terraform plan
terraform apply

# Configure kubectl
kubectl config set-credentials oidc-user \
  --exec-api-version=client.authentication.k8s.io/v1beta1 \
  --exec-command=kubectl \
  --exec-arg=oidc-login \
  --exec-arg=get-token \
  --exec-arg=--oidc-issuer-url=https://oidc.example.com \
  --exec-arg=--oidc-client-id=kubernetes

# Test authentication
kubectl get pods --user=oidc-user

Use Cases and Real-World Applications

Startup Teams (5-20 Developers)

Use GitHub authentication for your entire team. Everyone logs in with their GitHub accounts, and you control access through static group mappings. Cost: ~$10/month instead of $200+/month for enterprise identity solutions.

Multi-Cluster Management

Deploy Easy-OIDC once and configure multiple Kubernetes clusters to use it as their identity provider. Centralized authentication across development, staging, and production environments.

Compliance and Audit

Every kubectl action is associated with a real user email (from GitHub/Google), making audit logs meaningful and traceable. No more shared service account credentials.

Hybrid Cloud Environments

Works seamlessly across AWS, GCP, Azure, or on-premises Kubernetes clusters. The lightweight footprint makes it ideal for edge deployments.

Conclusion

Easy-OIDC proves that Kubernetes authentication doesn’t have to be complicated or expensive. By leveraging existing OAuth providers and providing a minimal, secure implementation, it offers enterprise-grade authentication with startup-friendly simplicity.

Whether you’re managing a small development team or orchestrating multiple production clusters, Easy-OIDC delivers the authentication layer your Kubernetes environment needs—without the operational burden of traditional identity providers.

Get started today: Visit easy-oidc.dev or check out the GitHub repository to deploy your first minimal OIDC server in minutes.

Try out yourself and let us know your experience or issues or queries in the comments section

Leave a Reply

Your email address will not be published. Required fields are marked *