Use this file to discover all available pages before exploring further.
Role-Based Access Control (RBAC) grants permissions to users based on the roles they hold. Permify Schema lets you model RBAC at different levels of granularity — from simple global roles attached to an organization all the way to fully custom, assignable role objects.
Global roles live on the highest-level entity (typically organization) and are shared across every resource that entity owns. This is the simplest starting point for RBAC.
1
Define the user entity
Every Permify schema requires a user entity. It is intentionally empty — other entities reference it as a relation type.
entity user {}
2
Add roles to the organization
Roles are modeled as relations on the entity where they live. Here we define four roles: admin, member, manager, and agent.
Permissions combine roles with or, and, and not operators.
entity organization { // roles relation admin @user relation member @user relation manager @user relation agent @user // organization file permissions permission view_files = admin or manager or (member not agent) permission delete_file = admin // vendor file permissions permission view_vendor_files = admin or manager or agent permission delete_vendor_file = agent}
view_files — admins, managers, or members who are not agents.
delete_file — admins only.
view_vendor_files — admins, managers, or agents.
delete_vendor_file — agents only.
Global role permissions defined on organization apply uniformly to everything owned by that organization. Move to Resource-Specific Roles when different resources need different permission sets.
Resource-specific roles extend global roles by attaching permissions directly to resource entities (file, vendor, etc.) and referencing the organization’s roles through relation traversal (org.admin, org.manager, …).
1
Keep roles on the organization
Organization roles remain the source of truth. Resource entities reference them rather than redefining them.
entity user {}entity organization { relation admin @user relation member @user relation manager @user relation agent @user}
2
Define the file entity with resource-specific permissions
The file entity has its own owner relation and inherits organizational roles via org.*.
entity file { // resource-specific relations relation owner @user relation org @organization relation vendor @vendor // resource-specific permissions permission view = org.admin or org.manager or (org.member not org.agent) or owner permission edit = org.admin or org.manager or owner permission delete = org.admin or owner}
3
Define the vendor entity with its own permission set
entity vendor { // vendor-specific relations relation primary_contact @user relation org @organization // vendor-specific permissions permission manage = org.admin or org.agent permission view = org.admin or org.manager or org.agent or primary_contact}
Custom roles let you create named role objects at runtime (e.g. role:admin, role:member) and assign specific permissions to them without hardcoding role names in the schema. This pattern is useful when roles must be configurable by end-users.
1
Model the role entity
The role entity has a single assignee relation pointing to users. Each role instance (e.g. role:admin) is a first-class object.
entity user {}entity role { relation assignee @user}
2
Attach role assignees to resource permissions
Instead of referencing @user directly, resource entities reference @role#assignee. This means “users who are assignees of some role”.
view on dashboard:145 → Allow — user:1 is an assignee of role:member, which has the view permission.
edit on dashboard:145 → Deny — user:1 is not an assignee of role:admin.
The custom roles pattern separates role definitions from schema changes. You can create new roles, modify their permissions, or delete them entirely by writing or deleting relationship tuples — no schema redeploy needed.
The schema below combines all three RBAC patterns into a single coherent model: global roles on organization, resource-specific permissions on file and vendor, and a custom role entity for fine-grained runtime control.
entity user {}// Custom role entity — role instances are created at runtimeentity role { relation assignee @user}// Global organizational rolesentity organization { relation admin @user relation member @user relation manager @user relation agent @user}// Resource-specific permissions inherit organization rolesentity file { relation owner @user relation org @organization relation vendor @vendor permission view = org.admin or org.manager or (org.member not org.agent) or owner permission edit = org.admin or org.manager or owner permission delete = org.admin or owner}entity vendor { relation primary_contact @user relation org @organization permission manage = org.admin or org.agent permission view = org.admin or org.manager or org.agent or primary_contact}// Dashboard and task use the custom-role patternentity dashboard { relation view @role#assignee relation edit @role#assignee}entity task { relation view @role#assignee relation edit @role#assignee}