Table of Contents
OpenFGA Relationship Tuples
A relationship tuple is one small fact about who is connected to what. It is the data in OpenFGA. The authorization model defines the shape of the rules; tuples fill in the real facts.
- Model = the rules (the shape).
- Tuples = the data (the facts).
- Together = the graph the Check API walks.
Why they exist
The model alone answers nothing. It only says a document can have an owner. A tuple says who the owner actually is. You need thousands or millions of these facts to describe your real users, groups, and objects.
What a tuple looks like
Every tuple has three parts, plus an optional condition.
| Part | Meaning | Example |
|---|---|---|
| user | who or what the fact is about | user:anne |
| relation | the named link (must exist in the model) | owner |
| object | the thing being accessed (type:id) | document:budget |
Written together:
user:anne owner document:budget
Read it as: “Anne is the owner of the budget document.”
The three fields in detail
user
The user field is flexible. It can be:
- An object:
user:anne— one specific subject. - A userset:
group:eng#member— every member of the eng group.
This is how you grant access to a whole group at once. - A wildcard:
user:*— every user of that type (public access).
relation
The name of the link, like owner, editor, or viewer. It must be a
relation that exists in the model for that object's type. You cannot invent one.
object
The target, always in type:id form, like document:budget or
organization:acme. The type must exist in the model.
Examples
user:anne owner document:budget user:bob viewer document:budget group:eng#member viewer document:roadmap folder:finance parent document:budget user:* viewer document:public-notice
Notice the fourth line: the user is itself an object (folder:finance). This
links a document to its parent folder, so access can flow along that link.
Conditional tuples (ABAC)
A tuple can carry a condition and some context. The grant only counts if the condition is true. For example, a tuple might say “Anne is a viewer only if the current time is during work hours”. This mixes attribute checks into the data.
Writing and deleting tuples
You change tuples through the Write API.
- Write: add a new fact (Anne becomes an owner).
- Delete: remove a fact (Anne is no longer an owner).
Tuples are usually kept in sync with your main database. A common pattern is CDC (Change Data Capture): when a row changes in your database, a matching tuple is written or deleted in OpenFGA automatically.
Contextual tuples
Some facts are not stored. You can pass contextual tuples inside a single Check call. They exist only for that one question and are never saved.
<note tip> Use contextual tuples for facts you know at request time but do not want to store, such as the user's current department passed in from a request header. </note>
How they fit
Input → Process → Output:
- Input: your app (or CDC) writes tuples as facts change.
- Process: on a Check, OpenFGA walks these tuples using the model rules.
- Output: an
allowed: trueorallowed: falseanswer.
