Policy System Overview
The CWMS Access Management system uses Open Policy Agent (OPA) to evaluate authorization decisions. This document describes the policy architecture, evaluation flow, and how policies interact with the authorization proxy.
Policy Architecture
The policy system consists of three main components:
Main Orchestrator (
cwms_authz.rego) - Entry point that evaluates all persona policiesPersona Policies - Role-specific authorization rules in the
personas/directoryHelper Modules - Reusable functions for office hierarchy and time-based rules
graph TD
A[Authorization Request] --> B[cwms_authz.rego]
B --> C{Evaluate Personas}
C --> D[public]
C --> E[dam_operator]
C --> F[water_manager]
C --> G[data_manager]
C --> H[automated_collector]
C --> I[automated_processor]
C --> J[external_cooperator]
C --> K[viewer_users]
D --> L{Any Allow?}
E --> L
F --> L
G --> L
H --> L
I --> L
J --> L
K --> L
L -->|Yes| M[allow: true]
L -->|No| N[allow: false]
Policy Evaluation
Input Structure
OPA policies receive a standardized input structure from the authorization proxy:
{
"user": {
"id": "m5hectest",
"roles": ["dam_operator", "cwms_user"],
"offices": ["SWT"],
"persona": "dam_operator",
"timezone": "America/Chicago",
"ts_privileges": [
{"ts_group_id": "PRECIP", "embargo_hours": 72}
]
},
"action": "read",
"resource": "timeseries",
"context": {
"office_id": "SWT",
"classification": "public",
"data_source": "AUTOMATED",
"ts_group_id": "PRECIP",
"timestamp_ns": 1705708800000000000
}
}
Evaluation Order
The main orchestrator (cwms_authz.rego) evaluates persona policies in sequence. Authorization succeeds if any persona policy returns allow = true:
default allow := false
allow if { public.allow }
allow if { dam_operator.allow }
allow if { water_manager.allow }
allow if { data_manager.allow }
allow if { automated_collector.allow }
allow if { automated_processor.allow }
allow if { external_cooperator.allow }
allow if { viewer_users.allow }
Privileged Roles
Two roles bypass persona-based evaluation entirely:
Role |
Description |
|---|---|
|
Full system access, bypasses all persona checks |
|
HEC staff access, bypasses all persona checks |
allow if { "system_admin" in input.user.roles }
allow if { "hec_employee" in input.user.roles }
Policy Decision Response
OPA returns a decision that the authorization proxy uses to construct the x-cwms-auth-context header:
{
"allow": true,
"decision_id": "opa-12345",
"constraints": {
"allowed_offices": ["SWT"],
"embargo_rules": {"SWT": 72, "default": 168},
"embargo_exempt": false
}
}
Helper Module Integration
Persona policies import helper modules to evaluate complex conditions:
import data.cwms.helpers.offices
import data.cwms.helpers.time_rules
Helpers provide:
Office Validation - Checks if user can access a specific office based on assignments, region, or role
Time Rules - Evaluates embargo periods, shift hours, and modification windows
See helpers.md for detailed documentation.
Policy File Organization
policies/
cwms_authz.rego # Main orchestrator
personas/
public.rego # Unauthenticated/public access
dam_operator.rego # Dam operators
water_manager.rego # Water managers
data_manager.rego # Data managers
automated_collector.rego # Automated data collection
automated_processor.rego # Automated data processing
external_cooperator.rego # External partners
viewer_users.rego # Read-only users
helpers/
offices.rego # Office hierarchy and access
time_rules.rego # Embargo and time window rules