Skip to content

ianlintner/authproxy

Repository files navigation

OAuth2 Sidecar Proxy

License: MIT Kubernetes Istio Helm Documentation GitHub

Simple, secure OAuth2 authentication for Kubernetes applications using the sidecar pattern.

Each application gets its own oauth2-proxy container that handles authentication transparentlyβ€”no complex configuration needed.

✨ Key Features

  • πŸ”’ Secure by Default - OAuth2/OIDC authentication with industry best practices
  • 🎯 Sidecar Pattern - Isolated authentication per application
  • πŸš€ Zero Application Changes - Drop-in authentication for any HTTP service
  • 🌐 Single Sign-On - Share sessions across all *.example.com apps
  • 🎨 Customizable UI - Branded sign-in pages with Tailwind CSS
  • πŸ“Š Observable - Prometheus metrics, health checks, audit logs
  • πŸ”„ Multi-Provider - GitHub, Google, Azure AD, Generic OIDC
  • πŸ›‘οΈ Security Hardened - Non-root containers, read-only filesystems, minimal privileges

πŸ“š Documentation

πŸ“– Full documentation: https://ianlintner.github.io/authproxy/

Topic Description
Quick Start Get running in 5 minutes
Architecture How it works with diagrams
Installation Detailed setup guide
Adding Apps Protect your applications
OAuth Providers GitHub, Google, Azure AD
Configuration All config options
Troubleshooting Common issues & solutions

πŸš€ Quick Start

Prerequisites

  • Kubernetes 1.20+ with kubectl access
  • Istio 1.14+ service mesh installed
  • Helm 3 installed
  • Domain with DNS/TLS configured
  • OAuth app registered (e.g., GitHub OAuth App)

Install in 3 Steps

1. Create OAuth Application

GitHub
  1. Go to GitHub Settings β†’ Developer settings β†’ OAuth Apps
  2. Click New OAuth App
  3. Set Homepage URL: https://example.com
  4. Set Authorization callback URL: https://auth.example.com/oauth2/callback
  5. Save Client ID and generate a Client Secret
Google
  1. Go to Google Cloud Console
  2. Create project β†’ APIs & Services β†’ Credentials
  3. Create OAuth 2.0 Client ID (Web application)
  4. Add Authorized redirect URI: https://auth.example.com/oauth2/callback
  5. Save Client ID and Client Secret

2. Install with Helm

# Clone the repository
git clone https://github.com/ianlintner/authproxy.git
cd authproxy

# Install the helm chart
helm install oauth2-sidecar ./helm/oauth2-sidecar \
  --set domain=example.com \
  --set cookieDomain=.example.com \
  --set oauth.provider=github \
  --set oauth.clientID=Ov23li1234567890abcd \
  --set oauth.clientSecret=1234567890abcdef1234567890abcdef12345678 \
  --set istio.gateway.existingGateway=your-gateway \
  --namespace default
Or create a values file
# values.yaml
domain: example.com
cookieDomain: .example.com

oauth:
  provider: github
  clientID: Ov23li1234567890abcd
  clientSecret: 1234567890abcdef1234567890abcdef12345678
  
istio:
  gateway:
    existingGateway: your-gateway
helm install oauth2-sidecar ./helm/oauth2-sidecar \
  -f values.yaml \
  --namespace default

3. Deploy Example Application

# Deploy the example app
kubectl apply -k k8s/apps/example-app/

# Check deployment
kubectl get pods -l app=example-app

4. Test It Out

# Visit your app (will redirect to GitHub/Google login)
open https://example-app.example.com

You should see:

  1. Sign-in page with your OAuth provider button
  2. OAuth consent screen (first time only)
  3. Your application - authenticated! πŸŽ‰

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Browser   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚ HTTPS
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Istio Gateway  β”‚
β”‚   (TLS Term)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Kubernetes Service         β”‚
β”‚        (port 4180)             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           Pod                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  OAuth2 Proxy Sidecar    β”‚ β”‚
β”‚  β”‚  :4180                   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚            β”‚ localhost         β”‚
β”‚            β–Ό                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Your Application        β”‚ β”‚
β”‚  β”‚  :8080                   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

How It Works

  1. Traffic arrives at Istio Gateway with TLS termination
  2. VirtualService routes to Service port 4180
  3. OAuth2 Proxy sidecar receives request:
    • ❌ No cookie? β†’ Redirect to OAuth provider sign-in
    • βœ… Valid cookie? β†’ Proxy to app on localhost:8080
  4. Application receives request with injected headers:
    • X-Auth-Request-User: john.doe
    • X-Auth-Request-Email: john.doe@example.com
    • X-Auth-Request-Access-Token: gho_xxxx...

Why Sidecar Pattern?

Benefit Description
Simple No complex Istio ext_authz or EnvoyFilter configuration
Isolated Each app has its own OAuth configuration
Debuggable Logs and metrics co-located with your app
Flexible Different OAuth providers per application
Portable Easy to migrate apps between clusters

See Architecture Documentation for detailed diagrams.

πŸ”§ Configuration

OAuth Providers

Configure your OAuth provider in the Helm values:

=== "GitHub" yaml oauth: provider: github clientID: Ov23li1234567890 clientSecret: your-secret github: org: "my-company" # Optional: restrict to org team: "engineering" # Optional: restrict to team

=== "Google" yaml oauth: provider: google clientID: 1234567890-abc123.apps.googleusercontent.com clientSecret: your-secret google: hostedDomain: "example.com" # Optional: restrict to domain

=== "Azure AD" yaml oauth: provider: azure clientID: your-app-id clientSecret: your-secret azure: tenant: your-tenant-id

See OAuth Provider Documentation for detailed setup guides.

Custom Sign-in Pages

Customize the sign-in page with your branding:

customTemplates:
  enabled: true
  brandName: "My Company SSO"
  logo: "<base64-encoded-logo>"

See Custom Templates Guide.

Advanced Configuration

# Session settings
session:
  cookieExpire: 168h  # 7 days
  cookieRefresh: 1h   # Refresh interval

# Email restrictions
email:
  domains:
    - "example.com"
    - "partner.com"

# Extra arguments to oauth2-proxy
extraArgs:
  - --skip-auth-regex=^/health
  - --ssl-upstream-insecure-skip-verify

Full configuration reference: Configuration Options

πŸš€ Adding Your Applications

Option 1: Use the Helper Script

./scripts/add-app.sh <app-name> <namespace> <app-port> <domain>

# Example:
./scripts/add-app.sh my-api default 8080 api.example.com

Option 2: Manual Configuration

Add the oauth2-proxy sidecar to your deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
      # OAuth2 Proxy sidecar
      - name: oauth2-proxy
        image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
        args:
          - --config=/etc/oauth2-proxy/oauth2_proxy.cfg
        env:
          - name: OAUTH2_PROXY_UPSTREAMS
            value: "http://127.0.0.1:8080"
        ports:
          - containerPort: 4180
        volumeMounts:
          - name: oauth2-proxy-config
            mountPath: /etc/oauth2-proxy
          - name: oauth2-proxy-templates
            mountPath: /templates
      
      # Your application
      - name: app
        image: my-app:latest
        ports:
          - containerPort: 8080
      
      volumes:
        - name: oauth2-proxy-config
          configMap:
            name: oauth2-proxy-sidecar-config
        - name: oauth2-proxy-templates
          configMap:
            name: oauth2-proxy-templates

Complete guide: Adding Applications

πŸ” Accessing User Information

Your application automatically receives user information via HTTP headers:

Available Headers

Header Description Example
X-Auth-Request-User Username john.doe
X-Auth-Request-Email Email address john.doe@example.com
X-Auth-Request-Preferred-Username Preferred username johndoe
X-Auth-Request-Access-Token OAuth access token gho_xxxx...
X-Forwarded-User User identifier john.doe
X-Forwarded-Email Email address john.doe@example.com
Authorization Bearer token Bearer gho_xxxx...

Code Examples

=== "Python / Flask" ```python from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def index():
    user = request.headers.get('X-Auth-Request-User')
    email = request.headers.get('X-Auth-Request-Email')
    return f'Hello {user} ({email})!'

@app.route('/admin')
def admin():
    email = request.headers.get('X-Auth-Request-Email')
    if not email.endswith('@example.com'):
        return 'Forbidden', 403
    return 'Admin Panel'
```

=== "Node.js / Express" ```javascript const express = require('express'); const app = express();

app.get('/', (req, res) => {
  const user = req.headers['x-auth-request-user'];
  const email = req.headers['x-auth-request-email'];
  res.send(`Hello ${user} (${email})!`);
});

app.get('/admin', (req, res) => {
  const email = req.headers['x-auth-request-email'];
  if (!email.endsWith('@example.com')) {
    return res.status(403).send('Forbidden');
  }
  res.send('Admin Panel');
});

app.listen(8080);
```

=== "Go" ```go package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    user := r.Header.Get("X-Auth-Request-User")
    email := r.Header.Get("X-Auth-Request-Email")
    fmt.Fprintf(w, "Hello %s (%s)!", user, email)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}
```

πŸ“Š Monitoring & Observability

Health Checks

OAuth2-proxy exposes health endpoints:

  • GET /ping - Liveness check
  • GET /ready - Readiness check

Prometheus Metrics

Metrics available at /metrics:

oauth2_proxy_requests_total
oauth2_proxy_authentication_attempts_total
oauth2_proxy_authentication_failures_total
oauth2_proxy_cookies_expired_total

Logs

View sidecar logs:

# View oauth2-proxy logs
kubectl logs -n default <pod-name> -c oauth2-proxy

# View application logs
kubectl logs -n default <pod-name> -c app

# Follow both
kubectl logs -n default <pod-name> --all-containers -f

πŸ› Troubleshooting

Common Issues

Redirect loop / Endless redirects

Cause: Callback URL mismatch

Solution: Ensure callback URL in OAuth provider matches:

https://auth.example.com/oauth2/callback

Check deployment env var:

kubectl get deployment -o yaml | grep REDIRECT_URL
Cookie not persisting / Sign in every time

Cause: Cookie domain mismatch

Solution: Verify cookie domain is .example.com:

kubectl get configmap oauth2-proxy-sidecar-config -o yaml | grep cookie_domains
404 Not Found on protected paths

Cause: VirtualService routing to wrong port

Solution: Verify VirtualService routes to port 4180:

kubectl get virtualservice <app-name> -o yaml

Should have:

destination:
  host: <app-name>
  port:
    number: 4180  # oauth2-proxy port
Connection refused to localhost:8080

Cause: Application not listening on localhost

Solution: Ensure app container listens on 0.0.0.0:8080 or 127.0.0.1:8080

See Troubleshooting Guide for more solutions.

πŸ“ Repository Structure

authproxy/
β”œβ”€β”€ docs/                      # MkDocs documentation
β”‚   β”œβ”€β”€ getting-started/      # Installation & quick start
β”‚   β”œβ”€β”€ architecture/         # Architecture with diagrams
β”‚   β”œβ”€β”€ guide/                # User guides
β”‚   β”œβ”€β”€ providers/            # OAuth provider setup
β”‚   └── reference/            # API & config reference
β”œβ”€β”€ helm/
β”‚   └── oauth2-sidecar/       # Helm chart
β”‚       β”œβ”€β”€ templates/        # Kubernetes templates
β”‚       β”œβ”€β”€ values.yaml       # Default values
β”‚       └── Chart.yaml        # Chart metadata
β”œβ”€β”€ k8s/
β”‚   β”œβ”€β”€ base/                 # Base resources
β”‚   β”‚   β”œβ”€β”€ istio/           # Gateway, VirtualService
β”‚   β”‚   └── oauth2-proxy/    # ConfigMaps, templates
β”‚   └── apps/
β”‚       └── example-app/      # Complete working example
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ add-app.sh           # Add auth to existing apps
β”‚   β”œβ”€β”€ setup.sh             # Initial cluster setup
β”‚   └── validate.sh          # Validation checks
β”œβ”€β”€ examples/                 # Example configurations
β”‚   └── simple-app/          # Minimal example
β”œβ”€β”€ mkdocs.yml               # Documentation config
└── README.md                # This file

🀝 Contributing

Contributions are welcome! Please see Contributing Guide.

Development Setup

# Clone repository
git clone https://github.com/ianlintner/authproxy.git
cd authproxy

# Install documentation dependencies
pip install -r docs/requirements.txt

# Serve docs locally
mkdocs serve

# Run validation
./scripts/validate.sh

About

OAuth2 Proxy Sidecar for Kubernetes Helmcharts and Configs

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •