Overview
Policy as Code (PaC) is the practice of managing access control policies using software development principles. Instead of clicking checkboxes in a GUI or writing static PDF documents, policies are defined in code (e.g., OPA Rego, Cedar), version-controlled in Git, tested via CI/CD, and deployed automatically.
This shift moves authorization from a "runtime configuration" to a "build-time artifact." It allows organizations to mathematically prove that a policy allows or denies specific access before it ever hits production. It is the gold standard for modern, cloud-native IGA.
Architecture
Reference Pattern: GitOps for Policy
The policy lifecycle mirrors the software lifecycle: Code -> Test -> Merge -> Deploy.
Diagram
Key Decisions
| Decision | Options | Recommendation | Notes / Gotchas |
|---|---|---|---|
| Language | OPA (Rego), AWS Cedar, XACML, Custom | OPA (Rego) or Cedar | Rego is the industry standard (CNCF). Cedar is newer, more readable, and performant. Avoid XACML (XML hell). |
| Enforcement Point | In-App (Library), Sidecar (Mesh), Central Service | Sidecar / Local Service | Centralized authorization services introduce latency and single points of failure. Keep policy close to the app. |
| Data Fetching | Push (Data in Policy), Pull (Lookups) | Push (Context-aware) | "Push" data (e.g., user roles) into the policy engine via bundles. "Pulling" at runtime kills performance. |
| Testing Strategy | Manual, Unit Tests, Integration | Unit Tests + Replay | You must unit test policy logic. "Replay" involves running old traffic against new policy to check for breaks. |
| Hardening | Fail-open, Fail-closed | Fail-closed | If the policy engine is unreachable, deny access. Availability mechanisms must be robust. |
Implementation
Phase 1: Policy Centralization
- Move hardcoded logic ("if user.role == 'admin'") out of application code.
- Adopt a policy engine (e.g., OPA).
- Store policy files in a version control system.
- Goal: Decouple policy from application logic.
Phase 2: CI/CD Integration
- Create a pipeline for policy changes.
- Implement linting and basic unit tests.
- Automate the distribution of policy bundles to agents.
- Goal: Treat policy changes with the same rigor as code changes.
Phase 3: Advanced Governance
- Implement "Policy Sentinel" (Policy controlling Policy).
- Generate compliance evidence directly from the Git history.
- Real-time impact analysis (Simulation) before merging PRs.
- Goal: Automated compliance and safe velocity.
Risks
- Complexity Barrier: Rego/Cedar learning curve is steep. Developers may struggle to write correct policies.
- Performance Latency: Every request now involves an external call (even if local). Optimization is key.
- Data Consistency: The policy engine thinks the user is in "Dept A", but the DB says "Dept B" due to sync lag.
- "Big Ball of Mud" Policies: Creating massive, monolithic policy files that are impossible to debug. Modularize!
KPIs
- Policy Coverage: Percentage of applications using externalized policy vs. hardcoded logic.
- Deployment Frequency: How often policy updates are pushed (should be high).
- Change Failure Rate: Percentage of policy deployments that caused an outage or rollback.
- Audit Time: Time required to prove "Who had access to X on date Y" (via Git history).
