Aller au contenu

OAuth2 Proxy Cheat Sheet

Overview

OAuth2 Proxy is a reverse proxy and static file server that provides authentication using OAuth 2.0 identity providers (Google, GitHub, Azure, Keycloak, etc.) to validate accounts by email, domain, or group. It sits in front of your application and handles the authentication flow, passing verified user information to the upstream service via headers.

OAuth2 Proxy is ideal for adding authentication to applications that lack built-in auth, protecting internal tools, and standardizing authentication across multiple services. It supports cookie-based sessions, JWT tokens, Redis session storage, and can be configured with Nginx, Traefik, or any reverse proxy that supports auth subrequests.

Installation

# Binary download
curl -L https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.6.0/oauth2-proxy-v7.6.0.linux-amd64.tar.gz | tar xz
sudo mv oauth2-proxy-v7.6.0.linux-amd64/oauth2-proxy /usr/local/bin/

# Docker
docker pull quay.io/oauth2-proxy/oauth2-proxy

# Homebrew
brew install oauth2-proxy

# Go install
go install github.com/oauth2-proxy/oauth2-proxy/v7@latest

# Verify
oauth2-proxy --version

Basic Usage

# Start with Google provider
oauth2-proxy \
  --provider=google \
  --client-id=YOUR_CLIENT_ID \
  --client-secret=YOUR_CLIENT_SECRET \
  --cookie-secret=$(python3 -c "import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())") \
  --email-domain=example.com \
  --upstream=http://localhost:8080 \
  --http-address=0.0.0.0:4180

# Start with GitHub provider
oauth2-proxy \
  --provider=github \
  --client-id=YOUR_CLIENT_ID \
  --client-secret=YOUR_CLIENT_SECRET \
  --cookie-secret=RANDOM_SECRET \
  --github-org=my-org \
  --upstream=http://localhost:8080 \
  --http-address=0.0.0.0:4180

Provider Configuration

Google

oauth2-proxy \
  --provider=google \
  --client-id=$GOOGLE_CLIENT_ID \
  --client-secret=$GOOGLE_CLIENT_SECRET \
  --email-domain=example.com \
  --cookie-secret=$COOKIE_SECRET

GitHub

oauth2-proxy \
  --provider=github \
  --client-id=$GITHUB_CLIENT_ID \
  --client-secret=$GITHUB_CLIENT_SECRET \
  --github-org=my-organization \
  --github-team=developers,devops \
  --cookie-secret=$COOKIE_SECRET

Azure AD / Entra ID

oauth2-proxy \
  --provider=azure \
  --client-id=$AZURE_CLIENT_ID \
  --client-secret=$AZURE_CLIENT_SECRET \
  --oidc-issuer-url=https://login.microsoftonline.com/TENANT_ID/v2.0 \
  --email-domain=example.com \
  --cookie-secret=$COOKIE_SECRET

Keycloak / Generic OIDC

oauth2-proxy \
  --provider=oidc \
  --client-id=$KEYCLOAK_CLIENT_ID \
  --client-secret=$KEYCLOAK_CLIENT_SECRET \
  --oidc-issuer-url=https://keycloak.example.com/realms/myrealm \
  --email-domain=* \
  --cookie-secret=$COOKIE_SECRET \
  --scope="openid email profile groups"

Configuration File

# oauth2-proxy.cfg
provider = "oidc"
client_id = "my-client-id"
client_secret = "my-client-secret"
oidc_issuer_url = "https://auth.example.com"

cookie_secret = "base64-encoded-32-byte-secret"
cookie_secure = true
cookie_domains = [".example.com"]
cookie_samesite = "lax"

email_domains = ["example.com"]

upstreams = ["http://localhost:8080"]
http_address = "0.0.0.0:4180"

redirect_url = "https://app.example.com/oauth2/callback"

pass_access_token = true
pass_authorization_header = true
set_authorization_header = true
set_xauthrequest = true

skip_provider_button = true

# Session storage
session_store_type = "redis"
redis_connection_url = "redis://redis:6379"

Common Flags

FlagDescription
--providerOAuth provider (google, github, azure, oidc, etc.)
--client-idOAuth client ID
--client-secretOAuth client secret
--cookie-secretSecret for cookie encryption (32 bytes, base64)
--email-domainRestrict to email domain (* for any)
--upstreamUpstream application URL
--http-addressListen address
--redirect-urlOAuth callback URL
--pass-access-tokenPass OAuth access token to upstream
--set-xauthrequestSet X-Auth-Request headers
--set-authorization-headerSet Authorization Bearer header
--skip-provider-buttonSkip the login button page
--whitelist-domainAllowed redirect domains
--authenticated-emails-fileFile with allowed emails
--cookie-expireCookie expiration time
--cookie-refreshCookie refresh interval
--skip-auth-regexPaths to skip authentication

Nginx Integration

server {
    listen 443 ssl;
    server_name app.example.com;

    location /oauth2/ {
        proxy_pass http://oauth2-proxy:4180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Auth-Request-Redirect $request_uri;
    }

    location = /oauth2/auth {
        proxy_pass http://oauth2-proxy:4180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Content-Length "";
        proxy_pass_request_body off;
    }

    location / {
        auth_request /oauth2/auth;
        error_page 401 = /oauth2/sign_in;

        auth_request_set $user $upstream_http_x_auth_request_user;
        auth_request_set $email $upstream_http_x_auth_request_email;
        auth_request_set $auth $upstream_http_authorization;

        proxy_set_header X-User $user;
        proxy_set_header X-Email $email;
        proxy_set_header Authorization $auth;

        proxy_pass http://backend:8080;
    }
}

Traefik Integration

# docker-compose.yml
services:
  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy
    command:
      - --provider=oidc
      - --oidc-issuer-url=https://auth.example.com
      - --client-id=${CLIENT_ID}
      - --client-secret=${CLIENT_SECRET}
      - --cookie-secret=${COOKIE_SECRET}
      - --email-domain=*
      - --upstream=static://202
      - --reverse-proxy=true
      - --set-xauthrequest=true
      - --http-address=0.0.0.0:4180
    labels:
      - "traefik.http.middlewares.oauth.forwardAuth.address=http://oauth2-proxy:4180/oauth2/auth"
      - "traefik.http.middlewares.oauth.forwardAuth.trustForwardHeader=true"
      - "traefik.http.middlewares.oauth.forwardAuth.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email,Authorization"

  my-app:
    image: my-app:latest
    labels:
      - "traefik.http.routers.myapp.middlewares=oauth@docker"

Advanced Usage

Skip Auth for Specific Paths

oauth2-proxy \
  --skip-auth-regex="^/health$" \
  --skip-auth-regex="^/api/public/.*" \
  --skip-auth-regex="^/static/.*"

Allowed Email List

# Create file with allowed emails
cat > /etc/oauth2-proxy/emails.txt <<EOF
admin@example.com
developer@example.com
EOF

oauth2-proxy \
  --authenticated-emails-file=/etc/oauth2-proxy/emails.txt

Redis Session Storage

oauth2-proxy \
  --session-store-type=redis \
  --redis-connection-url="redis://redis:6379" \
  --redis-password="redis-password" \
  --cookie-refresh=1h

Multiple Upstreams

oauth2-proxy \
  --upstream="http://app1:8080/app1/" \
  --upstream="http://app2:8080/app2/" \
  --upstream="file:///var/www/static/#/static/"

Configuration

# Generate cookie secret
python3 -c "import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())"

# Or with openssl
openssl rand -base64 32

# Environment variables (prefix with OAUTH2_PROXY_)
export OAUTH2_PROXY_PROVIDER=oidc
export OAUTH2_PROXY_CLIENT_ID=my-client-id
export OAUTH2_PROXY_CLIENT_SECRET=my-client-secret
export OAUTH2_PROXY_COOKIE_SECRET=base64-secret
export OAUTH2_PROXY_OIDC_ISSUER_URL=https://auth.example.com
export OAUTH2_PROXY_EMAIL_DOMAINS=example.com

Troubleshooting

IssueSolution
Redirect loopCheck redirect-url matches callback URL; verify cookie domain
403 after loginCheck email-domain, github-org, or allowed emails config
Cookie too largeSwitch to Redis session storage; cookies have 4KB browser limit
CORS issuesSet --whitelist-domain and configure upstream CORS headers
Provider discovery failsVerify --oidc-issuer-url is accessible and returns OIDC config
Session expiring too fastIncrease --cookie-expire; enable --cookie-refresh
Headers not passed to upstreamEnable --set-xauthrequest and --pass-access-token
Multiple domain SSO failsSet --cookie-domains=.example.com for parent domain