Skip to main content
Model Context Protocol (MCP) servers expose tools that AI agents can call. Without authorization, any authenticated user can invoke any tool. OpenFGA lets you control which tools each user can access, based on their role, group membership, or time-limited grants. This guide shows how to model tool-level authorization for an MCP server using OpenFGA, covering public tools, role-based access, group membership, temporal access, and resource-level permissions within tools. It explains how to control an agent’s interactions with an MCP server based on the user’s permissions.

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. The can_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_grant or role#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:
With this setup:
  • anne (managers → admin) can call greet, whoami, get_documents, and get_datetime.
  • beth (marketing → content_editor) can call greet, whoami, get_documents, and get_datetime.
  • carl (no group) can only call get_datetime.

Filtering the tool list

When a user connects to the MCP server, use ListObjects 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 the temporal_grant condition. This is useful when a user needs temporary access to a tool for a specific task.
When checking access, pass the current time in the request context. The check returns 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, a get_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:
When the tool executes, check whether the user has the 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:
  1. 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.
  2. Tool filtering: On each request, call ListObjects to retrieve all tools the user is authorized to call. Only expose those tools.
  3. 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.
  4. 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
  • ListObjects for tool filtering at connection time
  • Check for resource-level permissions at execution time
  • Shell scripts for managing group membership and temporal access
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
Last modified on September 28, 2026