ABAC vs. ReBAC
Attribute-Based Access Control (ABAC) decides based on attributes of the principal, resource, and request — "role = engineer AND region = EU". Relationship-Based Access Control (ReBAC) decides based on relationships in a stored graph — "user is editor of doc, which is in folder shared with team".
| ABAC | ReBAC | |
|---|---|---|
| Source of truth | Attributes on the request and resource | Stored relationship tuples |
| Ergonomics for hierarchy | Needs explicit attribute lookups | Native |
| Ergonomics for attribute checks | Native | Needs conditions/contextual data |
| Reverse queries | Hard — must enumerate resources | First-class |
| Common engines | OPA (Rego), Cedar, AWS IAM | OpenFGA, SpiceDB, Ory Keto |
When ABAC fits
- The decision is stateless from the engine's perspective — everything needed is on the request: claims, headers, resource metadata.
- Rules involve comparisons (
amount < limit,region = EU,time within business_hours). - You want policies versioned in Git as code or YAML, not stored as data.
When ReBAC fits
- The decision depends on relationships that change at write time — membership, sharing, hierarchy.
- You need reverse queries for UI rendering or filtered listings.
- Permissions need to traverse multi-hop graphs (team → project → folder → document).
OpenFGA does both
OpenFGA is a ReBAC engine, but it covers ABAC needs through conditions (CEL expressions evaluated at check time) and contextual tuples (request-time data passed into the check). For most applications that's enough — you don't need a second engine.
When you might want both
If you also need policy outside the application — Kubernetes admission, Terraform validation, service-mesh request rules — pair OpenFGA with a policy engine like OPA. OpenFGA inside the app, OPA at the infrastructure layer.