>

SpiceDB Community Day - March 19

[Register Now]

What are the key components of ReBAC?

Learn the core building blocks of ReBAC: object types, relations, permission computation, graph traversal, and consistency guarantees, with implementation examples from SpiceDB and OpenFGA.

Relationship-based access control (ReBAC) determines permissions through the connections between users and resources. Unlike role-based systems that assign predefined roles or attribute-based systems that evaluate object properties, ReBAC models authorization as a graph problem where access derives from relationship paths.

The foundational concepts of ReBAC are universal across implementations, though specific systems like Google Zanzibar, SpiceDB, OpenFGA, and others each realize these principles with different architectural choices and feature sets. This article explores both the core components that define ReBAC as an authorization paradigm and how leading implementations approach these concepts.

Object types and namespaces

At the conceptual level, ReBAC systems need a way to categorize the entities in your authorization model. These categories represent the types of subjects (like users or services) and resources (like documents or folders) that participate in relationships.

In a document management system, you might have categories like user, document, folder, and organization. Users are subjects that request access, while documents and folders are resources requiring protection. Organizations represent groups that contain users and own resources.

Systems like SpiceDB use a schema language to define object types and their relationships. OpenFGA uses a similar modeling DSL, while Oso Cloud employs its Polar language for defining entities and their relationships. The core concept remains the same: explicitly declaring what types of entities exist and what relationships they can have.

Relations and relationship tuples

The fundamental building block of any ReBAC system is the relationship itself. A relationship represents a connection between two entities in your system.

These relationships are typically represented as tuples with three components: a resource, a relation name, and a subject. For example, "Alice is an editor of Document 1" or "The Engineering team has viewing access to the Sales folder." The resource is what's being protected, the relation describes the nature of the connection, and the subject is who or what has that connection.

Implementation approaches: Most Zanzibar-inspired systems store relationships using a similar tuple format. SpiceDB uses the syntax document:doc1#editor@user:alice. OpenFGA uses a comparable structure in its API. Systems differ in how they store and index these tuples for performance. Zanzibar-based implementations like SpiceDB and OpenFGA store relationships in dedicated databases, while Oso Cloud can work with data in your application database.

Permission computation and schema

ReBAC systems need a mechanism to derive permissions from relationships. This is where the authorization logic lives: the rules that determine which relationships grant which permissions.

A permission might be directly granted through a relationship, or it might be computed from a chain of relationships. For instance, "can edit" might be granted directly, or it might be derived from being an "owner" (where owners can do everything editors can do), or from being a member of a team that has editing rights.

SpiceDB's schema language uses definitions and operators (union, intersection, exclusion) to express permission logic. OpenFGA's modeling language provides similar capabilities with its own syntax. Oso's Polar language takes a more general-purpose approach, letting you express authorization as logical rules. Cerbos uses YAML-based policies for policy definitions, which can incorporate relationship checks but focuses more on attribute-based logic.

Here's how permission computation might be expressed in SpiceDB's schema language:

zed
definition document {
  relation viewer: user | team#member
  relation editor: user | team#member
  relation owner: user

  permission view = viewer + editor + owner
  permission edit = editor + owner
  permission delete = owner
}

This defines that viewing permission is granted to anyone who has the viewer, editor, or owner relation.

Contextual and attribute-based evaluation

While ReBAC excels at modeling static relationships, real-world authorization often needs to consider dynamic context—things like time of day, IP address, or resource attributes that can't be pre-stored as relationships.

This represents a key distinction in the ReBAC ecosystem. Pure relationship-based systems like Zanzibar store all authorization data ahead of time, which enables extreme performance and consistency guarantees. Attribute-based access control (ABAC) systems evaluate policies at runtime against application data, offering more flexibility but typically with different performance characteristics.

SpiceDB introduced Caveats to allow relationships to be conditional on runtime context while maintaining Zanzibar's performance model. OpenFGA provides Conditions for similar purposes. Oso Cloud takes a hybrid approach, combining relationship-based checks with attribute evaluation in its policy language. Policy engines like Cerbos and OPA primarily focus on ABAC but can be used alongside ReBAC systems for cases that don't map naturally to pre-stored relationships.

Permission checking and graph traversal

At runtime, ReBAC systems answer authorization questions by searching for paths through the relationship graph. Given a subject, resource, and permission, the system checks whether a valid chain of relationships exists that grants that permission.

This graph traversal is what makes ReBAC powerful for modeling complex, hierarchical permissions. When you check if Alice can view Document 1, the system might discover she can through multiple paths: she's a direct viewer, or she's a member of the Engineering team which has viewing rights, or she's an admin of the organization that owns the document.

Zanzibar-inspired systems like SpiceDB and OpenFGA perform distributed graph walks with aggressive caching to achieve sub-10ms check latencies at scale. Oso Cloud optimizes for different performance characteristics by working with data in your application database. The core concept remains: translating authorization questions into graph reachability problems.

In SpiceDB, a check operation works as follows:

  1. You ask "Does user:alice have permission view on document:doc1?"
  2. SpiceDB looks up the permission definition in the schema
  3. It expands the permission expression, finding all relations that could grant it
  4. For each relation, it searches for stored relationships connecting the resource to the subject
  5. Any referenced permissions or relations trigger recursive graph walks
  6. Conditional relationships get evaluated with the provided context
  7. The result indicates if a valid path exists

Consistency and versioning

ReBAC systems must handle temporal consistency—ensuring that permission checks reflect the correct state of relationships even as they change. This is particularly important for the "new enemy problem," where revoking someone's access should immediately prevent them from seeing newly created resources, even in distributed systems with caching.

SpiceDB uses ZedTokens (inspired by Zanzibar's "Zookies") to track versions and provide configurable consistency levels. OpenFGA provides similar consistency tokens. These systems let you specify minimum freshness requirements while still benefiting from caching. Different implementations make different trade-offs between consistency strength and performance—understanding these trade-offs is crucial for production deployments.

Common ReBAC patterns across systems

Regardless of implementation, several authorization patterns appear consistently in ReBAC systems:

Direct relationships connect users directly to resources. User Alice is an editor of Document 1.

Hierarchical permissions propagate through organizational structures. Admins of Organization A can edit all documents in folders owned by that organization.

Group membership uses relations on group objects. Users who are members of the engineering team inherit permissions granted to that team.

Resource hierarchies allow permissions to flow from parent resources to children. Read access to a folder grants read access to its documents.

Role emulation within ReBAC systems. While ReBAC is more expressive than traditional RBAC, you can model role-based access by creating role objects and connecting users to roles, then roles to permissions. This is a common pattern when migrating from RBAC to ReBAC or when you need both relationship-based and role-based authorization in the same system.

FAQ

What's the difference between a relation and a permission?

A relation is a stored connection between objects that you write to the system. A permission is a computed authorization decision based on relations and other permissions. Relations are your data; permissions are your authorization logic. This distinction exists across all ReBAC implementations, though the terminology may vary slightly.

How does ReBAC relate to traditional RBAC?

ReBAC can fully model RBAC by creating role objects and establishing relationships between users, roles, and resources. However, the inverse isn't true—RBAC systems can't naturally express the relationship-based patterns that ReBAC excels at. As noted in AuthZed's documentation, systems like Zanzibar incorporate RBAC principles, but RBAC systems aren't necessarily Zanzibar-like. ReBAC is more expressive and can handle complex organizational hierarchies and sharing scenarios that require many specialized roles in pure RBAC systems.

How do you handle dynamic, request-time authorization logic?

This is where ReBAC implementations diverge significantly. Zanzibar-inspired systems like SpiceDB and OpenFGA use conditional relationships (Caveats/Conditions) for authorization decisions that depend on runtime context like IP addresses or time ranges. Policy-based systems like Oso Cloud and Cerbos evaluate rules at request time with access to your application data. The choice depends on your performance requirements and how much of your authorization logic can be pre-computed versus evaluated dynamically.

How do you keep relationships synchronized with your application database?

Synchronization strategies vary by system. Zanzibar-based systems like SpiceDB and OpenFGA store relationships in dedicated databases, requiring you to replicate authorization-relevant data. You can use two-phase commits for strong consistency or asynchronous replication for weaker consistency. Oso Cloud's approach allows it to query your application database directly, reducing synchronization complexity but with different architectural trade-offs. The right approach depends on your consistency requirements and operational preferences.

What are the main differences between ReBAC implementations?

The main dimensions of difference are:

  1. Data architecture — whether relationships are stored in a dedicated database or work with your application data directly
  2. Performance model — computing permission decisions at query time versus runtime policy evaluation. Each model requires unique caching and performance tuning to run at scale.
  3. Consistency guarantees — strong consistency with selectable levels (like SpiceDB's Consistency message format) versus eventual consistency
  4. Expression language — domain-specific languages like SpiceDB's schema language versus general-purpose policy languages like Polar
  5. Attribute handling — how systems incorporate dynamic context and attributes alongside relationships

Your choice should be guided by your scale requirements, consistency needs, and how naturally your authorization model maps to pure relationships versus needing runtime attribute evaluation.

Zanzibar for your applications?

See how AuthZed can add fine-grained permissions to your applications.