Relationships
Relationships are the core of Permify’s data model. They build up a collection of Access Control Lists (ACLs) called relational tuples. Each relational tuple represents a fact: user U has relation R to object O. The simplest form is:| Tuple | Meaning |
|---|---|
organization:1#admin@user:3 | User 3 is an admin of organization 1 |
document:1#owner@user:1 | User 1 owns document 1 |
document:1#maintainer@organization:2#member | All members of organization 2 are maintainers of document 1 |
The
relation field in the subject object controls what the subject refers to:- Empty (
"") — the subject is a direct individual user (e.g.user:123). "..."— the subject is the entity itself without a sub-relation. Used when the subject type is not theuserentity.- A named relation (e.g.
"member") — the subject is a userset: everyone who holds that relation on the subject entity.
Attributes
For scenarios where relationships alone are not enough — such as geo-based restrictions, time-based access, or boolean flags — Permify supports attributes. Attributes attach typed values to entities:| Attribute | Meaning |
|---|---|
account:1$balance|double:4000 | Account 1’s balance is 4000 |
post:546$is_restricted|boolean:true | Post 546 is marked as restricted |
user:122$regions|string[]:US,MEX | User 122 is associated with the US and Mexico regions |
Writing authorization data
Relationships and attributes are created via the Write Data API at runtime — typically when a user action in your application changes the authorization state (e.g. a user creates a document, joins an organization, or is granted a role). All data must conform to your authorization schema.Write Data API
POST/v1/tenants/{tenant_id}/data/write
Consider this schema for the examples below:
Example: document owner
When user:1 creates document:2, write the ownership tupledocument:2#owner@user:1:
- cURL
- Go
- Node
Example: organization admin
Relational tuple:organization:1#admin@user:3 — User 3 is an admin of organization 1.
- cURL
- Go
- Node
Example: parent organization
Relational tuple:document:1#parent@organization:1#... — Organization 1 is the parent of document 1.
- cURL
- Go
- Node
Example: group-based maintainer
Relational tuple:document:1#maintainer@organization:2#member — All members of organization 2 are maintainers of document 1.
- cURL
- Go
- Node
Snap tokens
Every Write Data response includes asnap_token:
Audit logs and history
Permify uses MVCC (Multi-Version Concurrency Control) to maintain a complete history of all permission data changes. This provides a built-in audit trail — you can review what changed, who changed it, and when.- Historical review — query past versions of your permission state.
- Current state review — inspect the latest version of any permission setting.
- Garbage collection — a built-in GC process cleans up old versions to keep storage optimized. Configure it via the
database.garbage_collectionsettings in your config file.