FGA Backend Overview
Summary
The FGA Backend is the relationship storage and evaluation layer that powers Keymate's fine-grained authorization capabilities. It stores relationship tuples, executes graph-based queries, and returns authorization decisions for ReBAC policies. Keymate currently uses OpenFGA as its backend implementation.
Why It Exists
Fine-grained authorization requires storing and querying relationships between entities at scale. These relationships form a directed graph that must support:
- Fast authorization checks ("Does user X have relation Y to resource Z?")
- List operations ("Which resources can user X access?")
- Relationship writes ("Grant user X editor access to resource Z")
The FGA Engine communicates with the backend through a defined API contract, allowing Keymate to leverage specialized graph authorization engines optimized for these operations.
Where It Fits in Keymate
The FGA Backend operates behind the FGA Engine component. When the Policy Engine evaluates a ReBAC policy, it delegates to the FGA Engine, which queries the backend for relationship data.
Boundaries
What it covers:
- Relationship tuple storage (user-relation-object triples)
- Authorization model management
- Graph-based authorization queries
- Relationship write operations
What it does not cover:
- Policy authoring and management (handled by Policy Engine)
- Request routing and enforcement (handled by Access Gateway)
- Audit logging (handled by Audit & Observability)
How It Works
Backend Abstraction
Keymate communicates with the FGA backend through a standardized interface that supports:
| Operation | Description |
|---|---|
| Check | Verify if a relationship exists between two entities |
| Write | Create or delete relationship tuples |
| Read | Query existing relationships |
| List Objects | Find all objects a user can access with a given relation |
| List Users | Find all users with a given relation to an object |
Authorization Models
The backend stores authorization models that define:
- Entity types — Categories of objects (user, document, team, organization)
- Relations — Named connections between entities (owner, editor, member)
- Relationship inheritance — How relations imply other relations (owner implies editor)
Relationship Tuples
The backend stores authorization data as tuples in the format:
(user, relation, object)
Where:
- user — The entity requesting access (can be a user, group, or another object)
- relation — The type of relationship (owner, editor, viewer, member)
- object — The resource being accessed
Examples:
user:janeiseditorofdocument:quarterly-reportuser:johnismemberofteam:engineeringteam:engineeringisassignedtoproject:platform
The third example shows indirect relationships: team membership can grant access to team resources through the authorization model.
Query Execution
The FGA Engine delegates authorization queries to the backend. For details on how OpenFGA processes these queries, see Current OpenFGA Backend.
Example Scenario
Scenario
An application lists all documents a user can view. The FGA Engine queries the backend using the ListObjects operation.
Input
- Actor: Application building a user's document library view
- Resource: ListObjects request for
user:johnwith relationvieweron typedocument - Action: List accessible resources
- Context: User has direct
vieweraccess to some documents andmemberaccess to a team that owns others
Expected Outcome
- Backend finds direct tuples:
user:johnisviewerofdocument:meeting-notes - Backend traverses team membership:
user:johnismemberofteam:engineering, which isownerofdocument:roadmap - Since
ownerimpliesviewerin the model, both documents appear in the result - Returns list:
[document:meeting-notes, document:roadmap]
Common Misunderstandings
- Backend stores policies — The backend stores relationship data, not policy definitions. The Policy Engine manages policies.
- Every check requires a database query — Backends use caching and optimization to minimize latency for repeated queries.
The backend must maintain consistency between relationship writes and authorization checks. Eventual consistency can cause temporary authorization discrepancies.
Design Notes / Best Practices
- Design authorization models before writing relationships
- Use relationship inheritance to minimize tuple count
- Monitor backend query latency for performance optimization
- Plan capacity based on expected tuple count and query volume
Use the backend's list operations to build UI features like "show documents I can edit" without checking each document individually.
Related Use Cases
- Document-level access control with per-user relationships
- Team-based project access through membership relationships
- Organization hierarchy with inherited permissions