Authentication Architecture
This document describes the modular authentication architecture for the Greenfield Cluster template.
Overview
The authentication system provides drop-in authentication for any HTTP application with near-zero app code changes. It supports multiple identity providers (SAML, OIDC) and can be configured with different enforcement strategies.
Azure AD / Google / GitHub / Okta] end subgraph "Kubernetes Cluster" subgraph "Istio Service Mesh" Gateway[Istio Ingress Gateway
with ext_authz] OAuth2[oauth2-proxy
Session Management] Keycloak[Keycloak
Optional SAML Broker] end subgraph "Application Layer" App1[Application 1] App2[Application 2] App3[Application 3] end subgraph "Policy Enforcement" ReqAuth[RequestAuthentication
JWT Validation] AuthzPolicy[AuthorizationPolicy
RBAC / Claims] end end User -->|1. Request| Gateway Gateway -->|2. ext_authz| OAuth2 OAuth2 -.->|3. OIDC| IdP OAuth2 -.->|3. OIDC| Keycloak Keycloak -.->|SAML| IdP Gateway -->|4. With headers| ReqAuth ReqAuth --> AuthzPolicy AuthzPolicy --> App1 AuthzPolicy --> App2 AuthzPolicy --> App3 style Gateway fill:#e1f5ff style OAuth2 fill:#e1f5ff style Keycloak fill:#f3e5f5 style ReqAuth fill:#fff9c4 style AuthzPolicy fill:#fff9c4 style App1 fill:#e8f5e9 style App2 fill:#e8f5e9 style App3 fill:#e8f5e9
Architecture Principles
- Drop-in auth - Applications require minimal changes to add authentication
- Multiple identity options - Support SAML (Okta), OIDC (Azure AD, Google, GitHub), and Keycloak
- Policy + enforcement in cluster - Authentication and authorization managed via GitOps
- Same workflow every time - Consistent commands for installation and configuration
Core Components
oauth2-proxy
oauth2-proxy is the primary authentication proxy that: - Handles OAuth2/OIDC authentication flows - Manages user sessions with encrypted cookies - Forwards identity headers to applications - Integrates with Istio for ingress-level enforcement
Keycloak (Optional)
Keycloak can be used as: - SAML to OIDC broker - Normalizes SAML providers to OIDC - Primary IdP - Platform-owned identity management - Federation hub - Connects multiple external providers
Istio Service Mesh
Istio provides: - Ingress gateway - Entry point for external traffic - Envoy ext_authz filter - Calls oauth2-proxy for authentication - RequestAuthentication - JWT token validation - AuthorizationPolicy - Fine-grained access control
Deployment Modes
Mode A: OIDC-first (Recommended)
OIDC] OAuth2 --> IdP[Azure AD / Google / GitHub] Gateway --> App[Application
with identity headers] style OAuth2 fill:#e1f5ff style IdP fill:#fff4e1 style App fill:#e8f5e9
Use when: - Using cloud identity providers (Azure AD, Google Workspace, GitHub) - Want fast setup with minimal components - Don't need SAML support
Pros: - Simple architecture - Fast authentication flows - Native JWT support - Low resource usage
Cons: - Limited to OIDC providers - Less flexibility for custom auth flows
Mode B: SAML-first via Keycloak
OIDC] OAuth2 --> Keycloak[Keycloak
SAML Broker] Keycloak --> Okta[Okta
SAML] Gateway --> App[Application
with identity headers] style OAuth2 fill:#e1f5ff style Keycloak fill:#f3e5f5 style Okta fill:#fff4e1 style App fill:#e8f5e9
Use when: - Enterprise requires SAML (Okta, OneLogin, etc.) - Need to normalize SAML to OIDC/JWT - Want consistent token format across providers
Pros: - Supports SAML providers - Normalizes claims/attributes - Flexible attribute mapping - Standard OIDC tokens for apps
Cons: - Additional component (Keycloak) - More complex setup - Higher resource usage
Mode C: Keycloak as Primary IdP
OIDC] OAuth2 --> Keycloak[Keycloak
Primary IdP] Gateway --> App[Application
with identity headers] style OAuth2 fill:#e1f5ff style Keycloak fill:#f3e5f5 style App fill:#e8f5e9
Use when: - Platform-owned identity required - Need complex realm/client management - Managing service accounts - Multiple federated providers
Pros: - Full control over identity - Service account management - Complex authentication flows - User federation (LDAP, AD)
Cons: - Most complex architecture - Highest resource usage - Requires Keycloak expertise
Enforcement Strategy
Authentication is enforced at the Istio ingress gateway using Envoy's ext_authz filter.
Authentication Flow
(X-Auth-Request-User,
X-Auth-Request-Email,
X-Auth-Request-Access-Token) App->>User: 11. Response
Benefits
- No per-app sidecars - Authentication enforced at ingress
- Centralized logic - Single oauth2-proxy instance
- Uniform policies - Consistent across all apps
- Easy to add apps - Simple VirtualService configuration
Identity Claims Standardization
All providers are normalized to a standard set of claims:
{
"iss": "https://provider.example.com",
"sub": "user-unique-id",
"email": "user@example.com",
"email_verified": true,
"groups": ["developers", "admins"],
"name": "John Doe",
"aud": "client-id",
"exp": 1234567890,
"iat": 1234567890
}
Claim Mapping
Different providers use different claim names. Keycloak can normalize these:
| Provider | Email Claim | Groups Claim | Notes |
|---|---|---|---|
| Azure AD | email or preferred_username |
groups |
Requires API permissions for groups |
email |
N/A | Use domain restriction | |
| GitHub | email |
teams |
Format: org/team-slug |
| Okta SAML | Attribute mapping | Attribute mapping | Via Keycloak broker |
Authorization Patterns
JWT Valid?} ReqAuth -->|No JWT| Deny1[❌ Deny] ReqAuth -->|Valid JWT| AuthzPolicies{Authorization Policies} AuthzPolicies --> PathCheck{Path Exemption?
/health, /metrics} PathCheck -->|Yes| Allow1[✓ Allow] PathCheck -->|No| DomainCheck{Email Domain?} DomainCheck -->|Wrong Domain| Deny2[❌ Deny] DomainCheck -->|Correct Domain| GroupCheck{Group Membership?} GroupCheck -->|Not in Group| Deny3[❌ Deny] GroupCheck -->|In Group| RouteCheck{Admin Route?
/admin/*} RouteCheck -->|Admin Route| AdminCheck{Admin Group?} RouteCheck -->|Regular Route| Allow2[✓ Allow] AdminCheck -->|Not Admin| Deny4[❌ Deny] AdminCheck -->|Is Admin| Allow3[✓ Allow] Allow1 --> App[Application] Allow2 --> App Allow3 --> App style ReqAuth fill:#fff9c4 style AuthzPolicies fill:#fff9c4 style PathCheck fill:#e3f2fd style DomainCheck fill:#e3f2fd style GroupCheck fill:#e3f2fd style RouteCheck fill:#e3f2fd style AdminCheck fill:#e3f2fd style Allow1 fill:#c8e6c9 style Allow2 fill:#c8e6c9 style Allow3 fill:#c8e6c9 style Deny1 fill:#ffcdd2 style Deny2 fill:#ffcdd2 style Deny3 fill:#ffcdd2 style Deny4 fill:#ffcdd2 style App fill:#e8f5e9
Pattern 1: Email Domain Restriction
Allow all users from specific email domains:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
spec:
action: ALLOW
rules:
- when:
- key: request.auth.claims[email]
values:
- "*@example.com"
- "*@partner.com"
Pattern 2: Group-Based Access
Allow only specific groups:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
spec:
action: ALLOW
rules:
- when:
- key: request.auth.claims[groups]
values:
- "admins"
- "developers"
Pattern 3: Path-Based Exemptions
Allow unauthenticated access to health checks:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
spec:
action: ALLOW
rules:
- to:
- operation:
paths:
- "/health"
- "/metrics"
Pattern 4: Layered Policies
Combine multiple policies for defense in depth:
# Policy 1: Allow health checks
# Policy 2: Require valid JWT
# Policy 3: Restrict to specific groups
# Policy 4: Admin-only routes
Security Considerations
Cookie Security
- HTTPS only - Cookies marked as Secure
- HttpOnly - Prevents JavaScript access
- SameSite=Lax - CSRF protection
- Encryption - Cookie contents encrypted
- Rotation - Regular cookie secret rotation
Secret Management
- Never commit secrets - Use external-secrets or sealed-secrets
- Strong cookie secret - Minimum 32 bytes, randomly generated
- Client secret rotation - Regular rotation per provider policy
- Namespace isolation - Secrets scoped to namespace
Network Security
- TLS everywhere - HTTPS for all external traffic
- mTLS optional - Internal service-to-service encryption
- Gateway isolation - Separate external/internal gateways
- Rate limiting - Protect against brute force
Token Validation
- JWT verification - Signature validation with JWKS
- Audience check - Ensures tokens for this application
- Expiry check - Rejects expired tokens
- Issuer validation - Only trusted issuers
Performance Characteristics
oauth2-proxy
- Memory: ~50-100MB per replica
- CPU: ~50-100m per replica
- Latency: ~10-50ms per request (cached session)
- Throughput: ~1000 req/sec per replica
Keycloak
- Memory: ~1-2GB per replica
- CPU: ~500-1000m per replica
- Latency: ~100-200ms per authentication
- Throughput: ~100 auth/sec per replica
Scaling Recommendations
- oauth2-proxy: 2-3 replicas minimum for HA
- Keycloak: 3 replicas for HA, shared PostgreSQL
- Session cache: Redis for shared sessions (optional)
Troubleshooting Guide
See auth-troubleshooting.md for detailed troubleshooting steps.
Common issues: - Redirect loops - Cookie domain mismatches - JWT validation failures - Group claims not working - Clock skew problems
Migration and Upgrades
Adding Authentication to Existing Apps
- No app code changes required
- Add VirtualService routing through gateway
- Apply RequestAuthentication policy
- Apply AuthorizationPolicy rules
- Test authentication flow
Changing Providers
- Deploy new provider overlay
- Update oauth2-proxy configuration
- Test with pilot application
- Switch traffic gradually
- Remove old provider
Upgrading Components
- oauth2-proxy: Update image tag in deployment
- Keycloak: Follow Keycloak upgrade guide
- Istio: Update EnvoyFilter for API changes