====== OpenFGA Authorization Model ======
An **authorization model** is the set of rules. It defines what //types// of
things exist and what //relations// can hold between them. It is the schema for
your permissions.
It holds only the **shape** of the rules. It does //not// hold real users or
real data — that is what relationship tuples are for.
===== Why it exists =====
Your app needs an agreed set of rules before it can answer any question. The
model is that agreement. It says things like "a document has an owner" and "an
editor can also view". Once the model is set, tuples fill in the real facts, and
the Check API uses both together.
* Model = the rules (the shape).
* Tuples = the data (the facts).
* Together = the graph OpenFGA walks to answer a Check.
===== What it contains =====
Two building blocks.
^ Block ^ What it is ^
| **Type** | A kind of object: ''user'', ''document'', ''folder'', ''organization''. |
| **Relation** | A named link on a type: ''owner'', ''editor'', ''viewer'', ''member''. |
Each type lists the relations that can point to it.
===== Two kinds of relation =====
A relation can be **direct** or **computed**.
* **Direct**: filled in by a tuple. Written with square brackets showing which types are allowed. \\ ''define owner: [user]'' means "a user can be assigned as owner".
* **Computed**: worked out from other relations, no tuple needed. \\ ''define editor: [user] or owner'' means "an editor, //or// anyone who is already an owner".
===== Relation operators =====
Computed relations use four operators.
^ Operator ^ Meaning ^ Example ^
| ''or'' (union) | this **or** that | ''editor: [user] or owner'' |
| ''and'' (intersection) | this **and** that | ''can_edit: editor and member'' |
| ''but not'' (exclusion) | this **but not** that | ''viewer: editor but not banned'' |
| ''from'' (tuple-to-userset) | inherit through another relation | ''viewer: viewer from parent'' |
The ''from'' operator is the key to ReBAC. ''viewer from parent'' means "you are a
viewer of this document if you are a viewer of its parent folder". Access flows
along the link.
===== Type restrictions =====
Direct relations say //which types// are allowed. This can also include:
* A single type: ''[user]''
* A **userset**: ''[group#member]'' — every member of a group.
* A **wildcard**: ''[user:*]'' — every user (public access).
Type restrictions keep the model safe. You cannot assign a type that the
relation does not allow.
===== Conditions (ABAC) =====
A relation can carry a **condition**: a small rule that must also be true. This
mixes attribute checks into the model. Example: a grant that only applies "if
the amount is under 500" or "only during work hours".
===== Two syntaxes =====
* **DSL**: the human-friendly form you write and read. Shown in all examples here.
* **JSON**: the form the API stores. The DSL compiles down to JSON.
They describe the same model.
===== Versioning =====
Each time you write a model, OpenFGA saves it as a **new, immutable version** with
its own model ID. Old versions stay. This means:
- You can change rules without breaking old tuples.
- A Check can be pinned to a specific model version.
- You get a full history of your rules.
===== Example =====
A classic document / folder model in DSL:
model
schema 1.1
type user
type folder
relations
define viewer: [user]
type document
relations
define parent: [folder]
define owner: [user]
define editor: [user] or owner
define viewer: [user] or editor or viewer from parent
Read the last line as: you can view a document if you are directly a viewer, //or//
an editor, //or// a viewer of its parent folder.
===== How it fits =====
Input → Process → Output:
* **Input**: you write the model once in DSL.
* **Process**: OpenFGA compiles it, versions it, and uses it to guide every Check.
* **Output**: a stable set of rules that tuples plug into.
===== See also =====
* [[https://openfga.dev/docs/configuration-language|Configuration language (DSL)]]
* [[https://openfga.dev/docs/modeling/getting-started|Modeling guide]]
* [[https://wiki.quizz.vn/doku.php?id=security:authorization:openfga:authorization-model:keyword-vs-name|OpenFGA DSL Syntax: Keywords vs Names]]