Set up resource types and warrants that model your authorization requirements. Then install the SDK to make access checks from your application.
To get the most out of this guide, you should have:
In this guide, we’ll implement fine-grained authorization for a simple B2B SaaS application that offers customers the ability to build and share reports generated using company data.
We will:
Don't see an SDK you need? Contact us to request an SDK!
Our application has three types of resources: reports, teams, and users. Our authorization model should meet the following requirements:
We can create the following resource types to fulfill these requirements:
[ { "type": "report", "relations": { "parent": {}, "owner": {}, "editor": { "inherit_if": "owner" }, "viewer": { "inherit_if": "any_of", "rules": [ { "inherit_if": "member", "of_type": "team", "with_relation": "parent" }, { "inherit_if": "editor" } ] } } }, { "type": "team", "relations": { "member": {} } }, { "type": "user", "relations": {} } ]
You can create resource types from the FGA dashboard using the JSON editor on the New Resource Type page.
Using your WorkOS API key, make a request to the Resource Types API to create your resource types.
curl "https:/api.workos.com/fga/v1/resource-types" \ -X PUT \ -H "Authorization: Bearer YOUR_KEY" \ --data-raw \ '[ { "type": "report", "relations": { "parent": {}, "owner": {}, "editor": { "inherit_if": "owner" }, "viewer": { "inherit_if": "any_of", "rules": [ { "inherit_if": "member", "of_type": "team", "with_relation": "parent" }, { "inherit_if": "editor" } ] } } }, { "type": "team", "relations": { "member": {} } }, { "type": "user", "relations": {} } ]'
Warrants are rules that specify relationships between the resources in an application. These relationships are then used to figure out if a user should have access to a resource or not.
As an example, let’s create two warrants:
[user:d6ed6474-784e-407e-a1ea-42a91d4c52b9] is a [member] of [team:stark]
[team:stark] is [parent] of [report:7]
curl "https://api.workos.com/fga/v1/warrants" \ -X POST \ -H "Authorization: Bearer sk_example_123456789" \ --data-raw \ '[ { "op": "create", "resource_type": "team", "resource_id": "stark", "relation": "member", "subject": { "resource_type": "user", "resource_id": "d6ed6474-784e-407e-a1ea-42a91d4c52b9" } }, { "op": "create", "resource_type": "report", "resource_id": "7", "relation": "parent", "subject": { "resource_type": "team", "resource_id": "stark" } } ]'
Now that we have our resource types and some warrants set up, we can start making access checks from our application.
Since we assigned [team:stark]
as the parent
team of [report:7]
and [user:d6ed6474-784e-407e-a1ea-42a91d4c52b9]
as a member
of [team:stark]
, they should automatically be a viewer
of [report:7]
. Let’s do a check to make sure.
curl "https://api.workos.com/fga/v1/check" \ -X POST \ -H "Authorization: Bearer sk_example_123456789" \ --data-raw \ '{ "checks": [ { "resource_type": "report", "resource_id": "7", "relation": "viewer", "subject": { "resource_type": "user", "resource_id": "d6ed6474-784e-407e-a1ea-42a91d4c52b9" } } ] }'
That’s it! We’ve now setup a powerful authorization system for our application that features a hierarchy of privileges and inheritance of privileges based on team membership.