WorkOS Docs Homepage
FGA
API referenceDashboardSign In
OverviewOverviewQuick StartQuick StartCore ConceptsResource TypesResource TypesResourcesResourcesRoles and PermissionsRoles and PermissionsAssignmentsAssignmentsAccess ControlAccess ChecksAccess ChecksResource DiscoveryResource DiscoveryIntegrationsAuthKit IntegrationAuthKit IntegrationStandalone IntegrationStandalone IntegrationIdP Role AssignmentIdP Role Assignment
API Reference
API Reference
Events
Events
Integrations
Integrations
Migrate to WorkOS
Migrate to WorkOS
SDKs
SDKs

Roles and Permissions

Define what users can do within specific resource types.

On this page

  • Introduction
  • Understanding permissions
  • Understanding roles
  • Permission inheritance
  • Seeing inheritance in action
  • How access is evaluated
  • Managing roles in the Dashboard

Introduction

Once you’ve defined your resource types, the next step is deciding what users can actually do. Roles and permissions in FGA are always scoped to a specific resource type – a workspace role applies only to workspaces, a project role applies only to projects.

This scoping makes permissions predictable. When you see workspace-admin, you know it grants workspace access. When a role includes permissions for child types, those permissions flow down automatically – a workspace admin can access all projects in that workspace without separate assignments.

Understanding permissions

A permission represents a specific action a user can perform on a resource type. Each permission has a name (like “Edit Workspace”), a slug used in code (workspace:edit), and the resource type it applies to.

We recommend following a {resource_type}:{action} pattern for permission slugs. This makes permissions self-documenting – project:delete clearly means the ability to delete a project.

Common patterns include:

  • {type}:view for read access
  • {type}:edit for modifying a resource
  • {type}:create for creating child resources
  • {type}:delete for removing a resource
  • {type}:manage for full administrative control
  • {type}:invite for adding collaborators

Keep permissions granular. Instead of a broad project:access permission, create specific ones like project:view, project:edit, and project:delete. This gives you flexibility as your product’s access requirements evolve.

Understanding roles

Roles are collections of permissions that describe what someone can do. Like permissions, each role is scoped to a resource type – you create a role for workspaces, another for projects, and so on.

We recommend naming roles to indicate both the scope and the capability level. Following a {resource-type}-{capability} pattern makes roles self-explanatory:

  • workspace-admin – full control of a workspace
  • workspace-member – basic workspace access
  • project-editor – can modify a project
  • project-viewer – read-only project access

When you assign workspace-admin to a user on a specific workspace, they get all the permissions bundled in that role for that workspace.

Permission inheritance

The key feature of FGA roles is that they can include permissions for child resource types. This is where the power of hierarchical authorization comes in.

A workspace-admin role might include:

  • workspace:view and workspace:edit (same type)
  • project:view and project:edit (child type)
  • app:view and app:deploy (grandchild type)

When you assign this role to someone on a workspace, they can view and edit that workspace, plus view, edit, and deploy all projects and apps within it. One assignment grants access across the entire sub-tree.

This reduces “role explosion” – instead of creating separate roles for every resource combination, you define roles at appropriate levels and let inheritance handle the rest. A workspace admin naturally has access to everything in the workspace, which matches how people think about access.

Seeing inheritance in action

To understand how permission inheritance works in practice, consider a hierarchy where an organization contains projects, and projects contain apps:

Org
└─ Project
└─ App

Different users can have roles at different levels, and the access they receive depends on where their role is assigned and what permissions that role includes.

Example resource hierarchy with roles
  • User John has Project read-only on Project:1 and can view only that project, not its apps

  • User Jane is Org member of Org:1 with org:read, project:read, and app:read permissions. They can view the organization, all of its projects, and all apps under those projects.

  • Jane is also Project editor for Project:2 and can read and edit Project:2 and all of its apps.

  • Jane has App editor for App:Finance and can view and edit only that app instance.

This pattern is powerful because it lets you express nuanced access with minimal assignments. A single organization-level membership provides baseline visibility, while targeted assignments grant elevated access where needed. The hierarchy does the work of propagating permissions, so you don’t have to create individual assignments for every resource.

How access is evaluated

When your application checks whether a user can perform an action on a resource, FGA looks at all possible sources of access:

  1. Direct assignments on the resource itself
  2. Inherited assignments from parent resources
  3. Organization-level roles that include the permission

If any of these grant the permission, the user is authorized.

For example, if Alice wants to deploy App:Frontend, FGA checks whether she has app:deploy directly on that app, or on its parent project, or on its parent workspace, or through an organization role. Her workspace-admin role on Workspace: Engineering includes app:deploy, so she’s authorized – even without any direct assignment on the app.

Permissions are additive. If a user has multiple roles, they get the union of all permissions from all their roles. There’s no way for one role to remove permissions granted by another.

Managing roles in the Dashboard

Configure roles and permissions in the WorkOS Dashboard under Authorization. You’ll need to have resource types defined before you can create scoped roles and permissions.

To create a new role, select the resource type it applies to and give it a descriptive name and slug.

FGA create role set details

Then choose which permissions to include from the same type and child types.

FGA create role assign permissions

When you modify a role’s permissions, changes apply immediately to everyone with that role. No re-assignment is needed – existing users automatically get the updated permissions.

For organizations using multiple roles, users receive all permissions from all their assigned roles. Priority order only matters for IdP role assignment when running in single-role mode.

Role AssignmentsGrant users access to specific resources through role assignments
Up next
© WorkOS, Inc.
FeaturesAuthKitSingle Sign-OnDirectory SyncAdmin PortalFine-Grained Authorization
DevelopersDocumentationChangelogAPI Status
ResourcesBlogPodcastPricingSecuritySupport
CompanyAboutCustomersCareersLegalPrivacy
© WorkOS, Inc.