Skip to main content
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

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.
entity organization {

    // roles
    relation admin   @user
    relation member  @user
    relation manager @user
    relation agent   @user

}
3

Define permissions using boolean operators

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.

Full Working Schema

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 runtime
entity role {
    relation assignee @user
}

// Global organizational roles
entity organization {
    relation admin   @user
    relation member  @user
    relation manager @user
    relation agent   @user
}

// Resource-specific permissions inherit organization roles
entity 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 pattern
entity dashboard {
    relation view @role#assignee
    relation edit @role#assignee
}

entity task {
    relation view @role#assignee
    relation edit @role#assignee
}

Build docs developers (and LLMs) love