Modern systems operate across clusters, APIs, and shared data layers. Each of these layers requires precise access control that can reason about users, actions, and context in real time. As OWASP continues to rank Broken Access Control as a top application security risk (OWASP Top 10 2021), the need for consistent and scalable authorization has become urgent.
A single policy engine is rarely enough. Instead, organizations are learning to match the policy model to the problem shape.
Three open models dominate current design:
- Open Policy Agent (OPA) — now a CNCF graduated project
- Cedar — an open authorization language
- Zanzibar — Google’s globally consistent authorization model
Three open models dominate current design: Open Policy Agent (OPA), Cedar, and Zanzibar. All three can manage infrastructure, APIs, and application data. The right choice depends on how you think about access: as code, as typed policy, or as a graph of relationships.
The Lenses for Decision Making
Choosing a policy engine is not about following trends. It is about matching the engine’s architecture to your data’s gravity. Use these seven lenses to evaluate your needs:
1. Data shape
- If you model deep ownership trees or sharing groups, a relationship graph is a natural fit.
- If you work with typed entities and attributes, a schema-based model adds clarity.
- If you use unstructured JSON and custom logic, a rule language is more flexible.
2. Explainability and analysis
- Typed languages produce predictable, auditable policies.
- Rule languages give freedom but need clear naming and testing conventions.
- Relationship graphs are intuitive to visualize but harder to explain in policy form.
3. Decision type
- Define what the decision must return.
- Boolean results work for most authorization cases, but some pipelines need lists, reasons, or filtered data sets.
4. Scale and latency
- Relationship models handle very high read volumes.
- Rule and schema models often embed close to services for low-latency checks.
5. Deployment and operations
- Some engines embed directly in the service layer, while others run as APIs or distributed graph stores.
- Plan for how you will observe, cache, and synchronize each engine.
6. Data freshness and sync
- Policies depend on current attributes and relationships.
- Graph and typed systems often require dedicated sync pipelines to stay accurate.
7. Team skills and lifecycle
- Readable and testable policies succeed when teams understand them.
- Pick a model that matches your engineering and security culture.
Code vs Graph: Two Mental Models of Authorization
This lens highlights how each system represents and resolves access.
Code-based policies
In rule and schema systems, authorization is code that runs against data. OPA and Cedar follow this model. Each decision evaluates conditions written in a language such as Rego or Cedar. They are best when policies depend on attributes, context, or computed logic.
Example (rule style):
package app.authz
default allow = false
allow {
input.user.department == input.resource.department
input.resource.consent == true
} Or
permit(principal, action in [ViewRecord], resource)
when {
principal in resource.department.members
&& resource.consent == true
}; Both evaluate conditions programmatically using the latest data provided at runtime.
Graph-based policies
In graph-based models, such as Zanzibar, access is resolved by walking relationships. No code runs at decision time. The engine checks tuples that describe how users, groups, and resources connect.
Example (graph style):
definition record {
relation dept_member: user
permission view = dept_member
}
record:rec1#dept_member@user:bob A check for record:rec1#view@user:bob returns allowed because the relationship already exists.
Trade-off
- Graph-based engines provide scale, consistency, and simplicity for membership and sharing.
- Most enterprises use both: graphs for relationships, and code for contextual evaluation.
- Code-based engines provide flexibility and context awareness.
In simple terms:
Code-based engines answer “Should this request be allowed given the current context?”
Graph-based engines answer “Does this relationship exist?
Comparing OPA, Cedar, and Zanzibar Models
All three models can operate on infrastructure, APIs, and application data. The key differences appear in how they express logic, govern data, and scale.
OPA (Rego)
Model: Logic rules evaluated over structured JSON input
Best fit: Infrastructure, APIs, and DevOps automation
Advantages
- Enforces structure between entities, attributes, and actions.
- Policies are human-readable and auditable.
- Supports static analysis and safety checks before deployment.
- Clear permit and forbid outcomes for predictable behavior.
Disadvantages
- No schema validation or typing.
- Large policy sets can become inconsistent without governance.
- Data synchronization must be handled externally.
Trade-off
OPA provides freedom and expressiveness. It fits diverse environments but needs strong testing and modular design to stay maintainable.
Cedar
Model: Typed, schema-driven, declarative
Best fit: Fine-grained application authorization
Advantages
- Enforces structure between entities, attributes, and actions.
- Policies are human-readable and auditable.
- Supports static analysis and safety checks before deployment.
- Clear permit and forbid outcomes for predictable behavior.
Disadvantages
- Requires schema definition in advance.
- Limited flexibility for arbitrary computed data.
- Less suited for large-scale relationship traversal.
Trade-off
Cedar prioritizes safety and readability. It is ideal when policies need to align with business logic and compliance standards.
Zanzibar
Model: Relationship graph (ReBAC)
Best fit: Collaboration, ownership, and group-based access
Advantages
- Efficient for nested relationships and transitive permissions.
- Scales to high read volumes and large datasets.
- Data-driven model; relationships can change independently of policy code.
Disadvantages
- Context evaluation is limited.
- Requires specialized tuple storage and caching.
- More abstract to author or visualize for non-graph users.
Trade-off
- Zanzibar emphasizes scale and simplicity for relationship reasoning.
- It pairs best with code-based engines for context-aware checks.
Summary: Strengths and Trade-Offs
Example Requirement Across Three Policy Engine Models
Imagine a common requirement: “A user can view a patient record if they belong to the same department, and consent is true.”
Infrastructure check with OPA
package admission
default allow = false
allow {
input.user.department == input.resource.department
input.resource.consent == true
} Fast and local; suited for Kubernetes admission or API gateways.
Application rule with Cedar
Schema Example
{
"AccessControl": {
"entityTypes": {
"User": {
"shape": {
"type": "Record",
"attributes": {
"userId": { "type": "String" }
}
}
},
"Department": {
"shape": {
"type": "Record",
"attributes": {
"members": {
"type": "Set",
"element": { "type": "Entity", "name": "User" }
}
}
}
},
"Resource": {
"shape": {
"type": "Record",
"attributes": {
"department": {
"type": "Entity",
"name": "Department"
},
"consent": { "type": "Boolean" }
}
}
}
},
"actions": {
"View": {
"appliesTo": {
"principalTypes": ["User"],
"resourceTypes": ["Resource"]
}
}
}
}
} Policy Example
permit(principal, action in [View], resource)
when {
principal in resource.department.members
&& resource.consent == true
}; Typed, auditable, and readable; ideal for business logic and compliance.
Relationship model with Zanzibar syntax
definition record {
relation dept_member: user
permission view = dept_member
}
record:rec1#dept_member@user:bob Lightweight and scalable for millions of relationships. The check walks the graph, not the code.
Decision Workflow
- Define the authorization question in plain language.
- Identify whether data is graph-heavy, typed, or free-form JSON.
- Select the minimal decision type: boolean or structured output.
- Estimate scale and latency expectations.
- Choose deployment and caching patterns.
- Plan data synchronization and audit trails.
- Keep one unified logging and versioning pipeline.
Blending the Models
In practice, organizations use a blend:
- Graph layer for relationships and group membership.
- Typed policy layer for application-specific context.
- Rule layer for platform and deployment guardrails.
Each layer reinforces the other, forming a consistent policy fabric that spans every system.
Conclusion
Infrastructure, APIs, and application data can all be protected by any of the three engines. The difference lies not in where they are applied, but in how each engine approaches authorization.
Code-based models such as OPA and Cedar focus on evaluating logic, while Graph-based models like Zanzibar focus on resolving relationships.
Understanding this distinction and aligning it with your data, compliance, and scalability needs forms the foundation of an effective multi-policy strategy.
When combined under shared governance, these engines provide flexible, explainable, and scalable access control for modern enterprises.
Request a Reva demo to see how multi-policy authorization works at runtime across infrastructure, APIs, and application data.



