Authorization Flow
The request flow through the CWMS Access Management system spans from initial client authentication through data retrieval.
Complete Authorization Sequence
The following diagram shows the full request lifecycle including authentication, context retrieval, policy evaluation, and data filtering.
sequenceDiagram
participant c as Client
participant kc as Keycloak
participant proxy as Authorization Proxy
participant redis as Redis
participant opa as OPA
participant api as CWMS Data API
participant db as Oracle Database
c->>kc: Authenticate with credentials
kc-->>c: JWT Token
c->>proxy: Request + JWT
proxy->>proxy: Extract username from JWT
proxy->>redis: Check cache for user context
alt Cache Hit
redis-->>proxy: User context
else Cache Miss
proxy->>api: GET /user/profile + JWT
api->>kc: Validate JWT via JWKS
api->>db: Query principle_name mapping
api->>db: Query offices and roles
api-->>proxy: User profile
proxy->>redis: Cache user context (30 min TTL)
end
proxy->>opa: Evaluate policy with user context
opa-->>proxy: Decision and constraints
alt Request Allowed
proxy->>api: Forward request + x-cwms-auth-context header
api->>db: Execute query with WHERE constraints
db-->>api: Filtered data
api-->>proxy: Response
proxy-->>c: Response
else Request Denied
proxy-->>c: 403 Forbidden
end
Flow Phases
Phase 1: Authentication
The client authenticates with Keycloak using their credentials. Upon successful authentication, Keycloak issues a JWT token containing:
Issuer claim identifying the Keycloak realm
Subject claim with the user’s unique identifier
Expiration and other standard JWT claims
The client includes this token in subsequent requests to the authorization proxy.
Phase 2: User Context Resolution
When the proxy receives a request, it extracts the username from the JWT token and attempts to retrieve the user’s context.
Step |
Description |
|---|---|
Cache Check |
Proxy queries Redis for cached user context |
Profile Request |
On cache miss, proxy requests user profile from CWMS Data API |
JWT Validation |
API validates the JWT using Keycloak’s JWKS endpoint |
Identity Mapping |
API maps the JWT subject to a CWMS database user |
Context Assembly |
API queries user offices and roles from database |
Cache Storage |
Proxy caches the context in Redis for 30 minutes |
The user context includes:
User identifier and username
Assigned roles from the CWMS security groups
Office affiliations and primary office
Any additional profile attributes
Phase 3: Policy Evaluation
The proxy sends the user context along with request details to OPA for policy evaluation.
sequenceDiagram
participant proxy as Authorization Proxy
participant opa as OPA
proxy->>opa: Policy input
Note right of proxy: user context, HTTP method, path, parameters
opa->>opa: Evaluate Rego policies
opa-->>proxy: Policy decision
Note left of opa: allow, constraints, embargo rules
OPA evaluates the request against configured policies and returns:
Field |
Description |
|---|---|
|
Boolean indicating whether request is permitted |
|
Array of office IDs the user can access |
|
Time-based restrictions per office |
|
Whether user bypasses embargo restrictions |
|
Historical data access limitations |
|
Classification levels the user can access |
Phase 4: Request Forwarding
If the policy allows the request, the proxy constructs the x-cwms-auth-context header and forwards the request to the CWMS Data API.
The header contains the complete authorization context in JSON format, enabling the API to apply filtering without making additional authorization queries.
Phase 5: Server-Side Filtering
The CWMS Data API parses the authorization context header and applies constraints at the database query level.
sequenceDiagram
participant proxy as Authorization Proxy
participant api as CWMS Data API
participant db as Oracle Database
proxy->>api: Request + x-cwms-auth-context
Note over api: Parse header constraints
api->>db: SELECT * WHERE office_id IN ('SWT', 'SPK')
Note over db: Only matching records returned
db-->>api: Filtered results
api-->>proxy: Response with filtered data
The API uses the AuthorizationFilterHelper class to generate JOOQ conditions that are added to SQL WHERE clauses. This ensures filtering happens at the database level, preventing unauthorized data from ever leaving the database.
Whitelist Bypass Flow
For endpoints not on the OPA whitelist, the proxy bypasses policy evaluation and forwards requests directly.
sequenceDiagram
participant c as Client
participant proxy as Authorization Proxy
participant api as CWMS Data API
c->>proxy: Request to non-whitelisted endpoint
proxy->>proxy: Check whitelist
Note over proxy: Endpoint not whitelisted
proxy->>api: Forward request directly
api-->>proxy: Response
proxy-->>c: Response
This allows administrative or health check endpoints to function without authorization overhead while still benefiting from the proxy infrastructure.