Authorization model
The model defines four types: users, groups, roles, and tools. Users belong to groups, groups are assigned to roles, and roles grant access to tools. Tools can also be made public or granted directly to a user. Thecan_call relation on tool accepts several types of assignments:
user:*— any authenticated user can call the tool (public tools).user— a specific user can call the tool.role#assignee— anyone assigned to the role can call the tool, either directly or through group membership.user with temporal_grantorrole#assignee with temporal_grant— access is granted for a limited duration.
Setting up groups and roles
Link users to groups, and groups to roles:Granting tool access
With groups and roles in place, grant tool access through role assignments and public access:- anne (managers → admin) can call
greet,whoami,get_documents, andget_datetime. - beth (marketing → content_editor) can call
greet,whoami,get_documents, andget_datetime. - carl (no group) can only call
get_datetime.
Filtering the tool list
When a user connects to the MCP server, useListObjects to retrieve all tools they are authorized to call. The MCP server then exposes only those tools.
For example, listing all tools user:carl can call:
The MCP server only exposes get_datetime to carl. The other tools are hidden from the tool list entirely.
For user:anne (managers → admin), the result includes all tools:
Temporal access
You can grant time-limited access to a tool using thetemporal_grant condition. This is useful when a user needs temporary access to a tool for a specific task.
true only if the current time is within the grant window:
After the grant expires, the same check returns false:
Resource-level permissions within tools
Some tools return different results depending on user permissions. For example, aget_documents tool might return public documents to all users but restrict private documents to specific roles. You can model this by adding a separate relation to the tool:
Grant the can_view_private_documents relation to the admin role:
can_view_private_documents relation and adjust the response accordingly:
Since anne is an admin, she sees all documents. Beth, as a content editor, sees only public documents.
If you have many tools with resource-level permissions, consider creating separate types for each tool’s resources instead of adding relations to the
tool type. See Domain-specific models for an example.Integration pattern
The authorization flow for an MCP server follows this pattern:- Authentication: The user authenticates with an identity provider (e.g., via OAuth 2.0). The MCP server verifies the token and extracts the user ID.
- Tool filtering: On each request, call
ListObjectsto retrieve all tools the user is authorized to call. Only expose those tools. - Tool execution: When a tool is invoked, verify the user still has access. For tools with resource-level permissions, perform additional checks to determine what data to return.
- Dynamic grants: Use temporal access or direct user grants to provide just-in-time access to tools as needed.
Sample implementation
For a complete working example of an MCP server with OpenFGA authorization, see the FastMCP + OpenFGA sample. The sample includes:- A fully configured authorization model and tuples
- OAuth 2.0 authentication with token verification
ListObjectsfor tool filtering at connection timeCheckfor resource-level permissions at execution time- Shell scripts for managing group membership and temporal access
Related Sections
Take a look at the following sections for more information.Task-Based Authorization
Grant agents scoped permissions to perform specific actions without permanent access
Conditions
Learn how to add time-based expiration or other conditions to access grants
Search With Permissions
Integrate authorization into search and retrieval workflows