OAuth Authentication Flow¶
This document describes the complete OAuth2 authentication flow when using the sidecar pattern.
Overview¶
The OAuth2 sidecar proxy handles authentication transparently, redirecting unauthenticated users through an OAuth flow and maintaining session cookies for authenticated users.
Authentication Flow Diagram¶
sequenceDiagram
participant User as User Browser
participant Istio as Istio Gateway
participant Sidecar as OAuth2 Proxy
(Sidecar)
participant App as Application
participant OAuth as OAuth Provider
(GitHub/Google/Azure)
User->>Istio: 1. Request https://app.example.com/
Istio->>Sidecar: 2. Forward to Pod
(port 4180)
Note over Sidecar: Check for valid
session cookie
alt No Valid Session
Sidecar->>User: 3. Show sign-in page
(custom template)
User->>Sidecar: 4. Click provider button
(e.g., GitHub)
Sidecar->>User: 5. Redirect to /oauth2/start
Sidecar->>User: 6. Redirect to OAuth provider
with callback URL
User->>OAuth: 7. Login & authorize
OAuth->>User: 8. Redirect to callback
with auth code
User->>Istio: 9. Request callback URL
https://auth.example.com/oauth2/callback
Istio->>Sidecar: 10. Forward callback
Sidecar->>OAuth: 11. Exchange code for token
OAuth->>Sidecar: 12. Return access token
Note over Sidecar: Create session,
set cookie
Sidecar->>User: 13. Redirect to original URL
with session cookie
User->>Istio: 14. Request original URL
with cookie
Istio->>Sidecar: 15. Forward request
end
Note over Sidecar: Valid session found
Sidecar->>App: 16. Proxy to app
on localhost:8080
+ inject headers
App->>Sidecar: 17. Response
Sidecar->>User: 18. Return response
Step-by-Step Flow¶
1. Initial Request (Unauthenticated)¶
When a user first visits https://app.example.com/, they don't have a valid session cookie:
2. Sign-in Page Display¶
The OAuth2 proxy sidecar checks for a session cookie. If none is found or it's expired, the proxy serves a custom sign-in page instead of auto-redirecting:
The sign-in page displays provider options (GitHub, Google, etc.) with branded buttons.
3. OAuth Provider Selection¶
When the user clicks a provider button (e.g., "Sign in with GitHub"), the browser navigates to:
4. Redirect to OAuth Provider¶
The sidecar generates an OAuth authorization URL and redirects:
HTTP/1.1 302 Found
Location: https://github.com/login/oauth/authorize?
client_id=YOUR_CLIENT_ID
&redirect_uri=https://auth.example.com/oauth2/callback
&response_type=code
&scope=user:email read:org
&state=ENCRYPTED_STATE_WITH_RETURN_URL
Key parameters:
redirect_uri: Centralized callback domain (e.g.,auth.example.com)state: Encrypted state containing the original return URLscope: Requested OAuth scopes
5. User Authorization¶
The user authenticates with the OAuth provider (GitHub, Google, Azure AD, etc.) and grants permissions.
6. Callback with Authorization Code¶
The OAuth provider redirects back to the callback URL with an authorization code:
https://auth.example.com/oauth2/callback?
code=AUTHORIZATION_CODE
&state=ENCRYPTED_STATE_WITH_RETURN_URL
7. Token Exchange¶
The sidecar exchanges the authorization code for an access token:
POST https://github.com/login/oauth/access_token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&code=AUTHORIZATION_CODE
&redirect_uri=https://auth.example.com/oauth2/callback
Response:
8. Session Creation¶
The sidecar creates a session and sets a secure cookie:
HTTP/1.1 302 Found
Location: https://app.example.com/
Set-Cookie: _oauth2_proxy=ENCRYPTED_SESSION_DATA;
Domain=.example.com;
Path=/;
Secure;
HttpOnly;
SameSite=Lax;
Max-Age=604800
Cookie characteristics:
- Domain:
.example.com(enables SSO across subdomains) - Secure: Only sent over HTTPS
- HttpOnly: Not accessible to JavaScript
- SameSite=Lax: Protects against CSRF
- Max-Age: 7 days (configurable)
9. Authenticated Request¶
Subsequent requests include the session cookie:
10. Request Proxying with Headers¶
The sidecar validates the session and proxies the request to the application container, injecting user information as headers:
GET /dashboard HTTP/1.1
Host: localhost:8080
X-Auth-Request-User: john.doe
X-Auth-Request-Email: john.doe@example.com
X-Auth-Request-Preferred-Username: johndoe
X-Auth-Request-Access-Token: gho_xxxxxxxxxxxxx
Authorization: Bearer gho_xxxxxxxxxxxxx
Centralized vs. Per-App Callbacks¶
Centralized Callback Domain¶
The sidecar architecture uses a centralized callback domain for all applications:
Benefits:
- Single OAuth app configuration per provider
- Shared SSO cookie across all apps
- Simplified DNS and certificate management
- Consistent user experience
Configuration¶
# Deployment environment variable
- name: OAUTH2_PROXY_REDIRECT_URL
value: "https://auth.example.com/oauth2/callback"
# ConfigMap
cookie_domains = [".example.com"]
whitelist_domains = [".example.com"]
Session Management¶
Cookie Structure¶
The session cookie contains encrypted data:
Components:
- Version: Cookie format version
- Encrypted Data: User email, access token, expiry
- Signature: HMAC signature for integrity
Cookie Refresh¶
Cookies are automatically refreshed:
When a cookie is older than 1 hour but younger than 7 days, the sidecar refreshes it by validating the access token and issuing a new cookie.
Sign Out Flow¶
sequenceDiagram
participant User
participant Sidecar as OAuth2 Proxy
participant App
User->>App: Click "Sign Out"
App->>Sidecar: Redirect to /oauth2/sign_out?rd=/
Note over Sidecar: Clear session cookie
Sidecar->>User: Redirect with cleared cookie
User->>Sidecar: Next request (no cookie)
Sidecar->>User: Show sign-in page
Sign-out URL format:
The rd parameter specifies where to redirect after sign-out.
Security Considerations¶
State Parameter¶
The state parameter prevents CSRF attacks:
The sidecar validates the state parameter on callback to ensure the request originated from the same session.
Cookie Security¶
Cookies are encrypted using AES-256 with a secret key:
Token Storage¶
Access tokens are stored encrypted in the session cookie, not in server-side storage. This enables stateless operation across multiple sidecar instances.
Error Handling¶
Common Error Scenarios¶
- Invalid/Expired Session
-
Clear cookie and redirect to sign-in page
-
OAuth Provider Error
- Display custom error page with details
-
Allow user to retry
-
Invalid State Parameter
- Clear session and redirect to sign-in
-
Log security event
-
Token Refresh Failure
- Clear session and require re-authentication
Custom Error Pages¶
Configure custom error templates:
Network Flow Architecture¶
graph TB
subgraph "Kubernetes Pod"
Sidecar[OAuth2 Proxy
:4180]
App[Application
:8080]
Sidecar -->|localhost| App
end
subgraph "Istio"
Gateway[Gateway]
VirtualService[VirtualService]
end
User[User Browser] -->|HTTPS| Gateway
Gateway --> VirtualService
VirtualService -->|:4180| Sidecar
Sidecar -.->|OAuth flow| OAuth[OAuth Provider]
style Sidecar fill:#4f46e5,color:#fff
style App fill:#10b981,color:#fff
Configuration Reference¶
Deployment Configuration¶
env:
- name: OAUTH2_PROXY_REDIRECT_URL
value: "https://auth.example.com/oauth2/callback"
- name: OAUTH2_PROXY_UPSTREAMS
value: "http://127.0.0.1:8080"
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: client-id
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: client-secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: cookie-secret
ConfigMap Settings¶
provider = "github"
http_address = "0.0.0.0:4180"
cookie_domains = [".example.com"]
cookie_secure = true
cookie_httponly = true
cookie_samesite = "lax"
cookie_expire = "168h"
cookie_refresh = "1h"
email_domains = ["*"]
skip_provider_button = false
custom_templates_dir = "/templates"
reverse_proxy = true