The Check API is the part that answers the core question:
“Is this user allowed to do this thing?” Your app sends a question, and
OpenFGA replies allowed: true or allowed: false.
This is the piece your app calls the most. It uses the authorization model (the rules) and the relationship tuples (the data) together to reach an answer.
Your app should not hold permission logic in its own code. Instead, before any sensitive action, it asks OpenFGA. This keeps all rules in one place and gives a fast, consistent yes/no everywhere.
A Check question has the same three parts as a tuple, plus the store and model it runs against.
| Part | Meaning | Example |
|---|---|---|
| user | who is asking | user:anne |
| relation | the action or link to test | viewer |
| object | the thing being accessed | document:budget |
In words: “Can Anne view the budget document?”
Check: user:anne viewer document:budget
A simple boolean.
{ "allowed": true }
The model plus the tuples form a graph. A Check walks that graph.
true. If not, false.
Example: Anne is not a direct viewer, but she is an editor, and the model says
viewer includes editor. The walk connects, so the answer is true.
A Check can include contextual tuples: extra facts passed in for this one question only. They are never stored. Use them for data you know at request time, such as the user's current department.
If the model uses conditions, the Check can pass context values (like time or amount). OpenFGA evaluates the condition as part of the walk. The grant only counts if the condition is true.
OpenFGA caches data for speed. A Check can ask for different consistency levels:
<note tip> Right after you write a tuple, use a higher-consistency Check if the new grant must take effect immediately. </note>
The Check API answers one yes/no question. OpenFGA has sibling queries for other needs:
Input → Process → Output:
(user, relation, object) with the store and model.allowed: true or allowed: false; your app allows or blocks the action.