WorkOS Docs Homepage
FGA
API referenceDashboardSign In
Getting StartedOverviewOverviewQuick StartQuick StartPlaygroundPlaygroundKey ConceptsSchemaSchemaWarrantsWarrantsResourcesResourcesPoliciesPoliciesQuery LanguageQuery LanguageWarrant TokensWarrant TokensOperations & UsageOperations & UsageManagementSchema ManagementSchema ManagementLocal DevelopmentLocal DevelopmentIdentity Provider SessionsIdentity Provider SessionsModelingOrg Roles & PermissionsOrg Roles & PermissionsCustom RolesCustom RolesGoogle DocsGoogle DocsEntitlementsEntitlementsUser GroupsUser GroupsManaged Service ProviderManaged Service ProviderAttribute-Based Access ControlAttribute-Based Access ControlConditional RolesConditional RolesPolicy ContextPolicy ContextPublic AccessPublic AccessSuperusersSuperusersBlocklistsBlocklists
API Reference
API Reference
Events
Events
Integrations
Integrations
Migrate to WorkOS
Migrate to WorkOS
SDKs
SDKs

Conditional Roles

Combine relationship-based access control (ReBAC) with attribute-based access control (ABAC) to create conditional roles.

On this page

  • When to Use It
  • Example Applications
  • Schema
  • Example
    • 1. Apply the schema
    • 2. Create warrants
    • 3. Check access

Explore the example from this guide in the FGA Playground, where you can interact with the schema, warrants, and access checks in real-time!

Use FGA to combine Relationship-Based Access Control (ReBAC) and Attribute-Based Access Control (ABAC). Define roles that are bound to specific resources and change based on specific conditions. This allows for more granular control over who can do what, when, and under which circumstances.

When to Use It

Use conditional roles when you cannot determine access by relationships alone. For example, a team member may be allowed to approve some expenses, but only if they are below a certain amount or belong to specific cost centers. As systems grow in complexity, pure ReBAC or ABAC models may become limiting. Conditional roles help bridge that gap with clear, composable rules.

Example Applications

  • Expense Management: Finance managers can approve expense reports only if the amount is below a defined threshold and aligned with their assigned cost centers.
  • Procurement: Department heads may approve purchase orders only after completing mandatory compliance or budget authorization training.
  • Healthcare Systems: Authorized clinicians can access sensitive health records only if the individual is assigned to their care team and the access occurs during regulated working hours.

Schema

version 0.3
type user
type team
relation finance_admin [user]
relation finance_manager [user]
inherit finance_manager if
relation finance_admin
type expense
relation approval_team [team]
relation submitter [user]
relation approve []
inherit approve if
any_of
all_of
relation finance_manager on approval_team [team]
policy can_approve_amount
all_of
relation finance_admin on approval_team [team]
policy is_high_value_expense
policy can_approve_amount(expense_attributes map, user_attributes map) {
let can_approve_cost_center = expense_attributes.cost_center in user_attributes.approved_cost_centers;
let can_approve_amount = expense_attributes.amount <= 1000;
can_approve_cost_center && can_approve_amount
}
policy is_high_value_expense(expense_attributes map) {
expense_attributes.amount > 1000
}

Example

1. Apply the schema

Create a file called schema.txt containing the schema definition from above. Then use the CLI to apply this schema to your WorkOS FGA environment.

Note: make sure to select the correct environment with the CLI

workos fga schema apply schema.txt

2. Create warrants

Create warrants that associate users, teams, and expenses. The example schema defines the following relationships:

  • users with teams (using the finance_admin or finance_manager roles)
  • teams with expenses (using the approval_team relation)

Let’s create a few warrants between team finance-1, expense expense-1, and user user_2oDscjroNWtzxzYEnEzT9P7VYEe:

Create warrants
curl "https://api.workos.com/fga/v1/warrants" \
-X POST \
-H "Authorization: Bearer sk_example_123456789" \
--data-raw \
'[
{
"op": "create",
"resource_type": "expense",
"resource_id": "expense-1",
"relation": "approval_team",
"subject": {
"resource_type": "team",
"resource_id": "team-1"
}
},
{
"op": "create",
"resource_type": "team",
"resource_id": "team-1",
"relation": "finance_manager",
"subject": {
"resource_type": "user",
"resource_id": "user_2oDscjroNWtzxzYEnEzT9P7VYEe"
}
}
]'

3. Check access

With our environment setup, we can check the user’s permission to approve expenses.

Check if a user can approve an expense
curl "https://api.workos.com/fga/v1/check" \
-X POST \
-H "Authorization: Bearer sk_example_123456789" \
--data-raw \
'{
"checks": [
{
"resource_type": "expense",
"resource_id": "expense-1",
"relation": "approve",
"subject": {
"resource_type": "user",
"resource_id": "user_2oDscjroNWtzxzYEnEzT9P7VYEe"
},
"context": {
"user_attributes": {
"user_id": "user_2oDscjroNWtzxzYEnEzT9P7VYEe",
"approved_cost_centers": [
"cost-center-1",
"cost-center-2"
]
},
"expense_attributes": {
"cost_center": "cost-center-1",
"amount": 150,
"description": "New keyboard",
"date": "2023-10-01"
}
}
}
],
}'
© WorkOS, Inc.
FeaturesAuthKitSingle Sign-OnDirectory SyncAdmin PortalFine-Grained Authorization
DevelopersDocumentationChangelogAPI Status
ResourcesBlogPodcastPricingSecuritySupport
CompanyAboutCustomersCareersLegalPrivacy
© WorkOS, Inc.