Build a Google Docs-like authorization model in which users have varying levels of access to documents they can collaborate on with each other.
Explore the example from this guide in the FGA Playground, where you can interact with the schema, warrants, and access checks in real-time!
Implement an authorization model similar to Google Docs document sharing. Allow users to grant read and/or write access to other users on individual documents and folders containing other nested documents and/or folders.
Consider this authorization model for:
version 0.3 type user type document // Note: folders are modeled as documents. // They can be parents of other documents. relation parent [document] relation role_owner [user] relation role_editor [user] relation role_viewer [user] relation can_write_users [] relation can_read_users [] relation can_write_content [] relation can_read_content [] inherit role_owner if relation role_owner on parent [document] inherit role_editor if any_of relation role_owner relation role_editor on parent [document] inherit role_viewer if any_of relation role_editor relation role_viewer on parent [document] inherit can_write_users if relation role_owner inherit can_read_users if any_of relation role_viewer relation can_write_users inherit can_write_content if relation role_editor inherit can_read_content if any_of relation role_viewer relation can_write_content
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
Create warrants that associate users and documents. The example schema defines the following relationships:
owner
, editor
, or viewer
)Let’s create a few warrants between documents doc-1
, doc-2
, doc-3
, folder-1
, folder-f2
, and user user_2oDscjroNWtzxzYEnEzT9P7VYEe
:
curl "https://api.workos.com/fga/v1/warrants" \ -X POST \ -H "Authorization: Bearer sk_example_123456789" \ --data-raw \ '[ { "op": "create", "resource_type": "document", "resource_id": "doc-1", "relation": "parent", "subject": { "resource_type": "document", "resource_id": "folder-1" } }, { "op": "create", "resource_type": "document", "resource_id": "doc-2", "relation": "parent", "subject": { "resource_type": "document", "resource_id": "folder-1" } }, { "op": "create", "resource_type": "document", "resource_id": "doc-3", "relation": "parent", "subject": { "resource_type": "document", "resource_id": "folder-2" } }, { "op": "create", "resource_type": "document", "resource_id": "folder-1", "relation": "parent", "subject": { "resource_type": "document", "resource_id": "folder-2" } }, { "op": "create", "resource_type": "document", "resource_id": "folder-1", "relation": "role_owner", "subject": { "resource_type": "user", "resource_id": "user_2oDscjroNWtzxzYEnEzT9P7VYEe" } }, { "op": "create", "resource_type": "document", "resource_id": "folder-2", "relation": "role_viewer", "subject": { "resource_type": "user", "resource_id": "user_2oDscjroNWtzxzYEnEzT9P7VYEe" } }, ]'
With our environment setup, we can check whether the user can read a document’s contents.
curl "https://api.workos.com/fga/v1/check" \ -X POST \ -H "Authorization: Bearer sk_example_123456789" \ --data-raw \ '{ "checks": [ { "resource_type": "document", "resource_id": "doc-1", "relation": "can_read_content", "subject": { "resource_type": "user", "resource_id": "user_2oDscjroNWtzxzYEnEzT9P7VYEe" } } ] }'