-
Notifications
You must be signed in to change notification settings - Fork 56
Adds MCP FGA quickstart #500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
cfe3993
Adds MCP FGA quickstart
jtemporal 18e353e
Fix Vale errors
jtemporal 00b9af7
Fix outdated links in quickstart and snippets
jtemporal 7303977
Update title and sidebar name
jtemporal 01024c3
feat: add roles management section and update tenant settings in quic…
jtemporal b6ad2c7
refactor: restructure authorization model explanation and enhance cla…
jtemporal f25c2e8
fix: clarify instructions for reloading tools after permission changes
jtemporal 78d0ec4
fix: update permissions descriptions for client creation in FGA setup…
jtemporal f796ee4
Fix typo in number of authz scenarios
jtemporal 97cd268
updates changelog
jtemporal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
283 changes: 283 additions & 0 deletions
283
auth4genai/mcp/get-started/secure-mcp-server-with-auth0-fga.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,283 @@ | ||
| --- | ||
| title: Control Access to MCP Tools with FGA | ||
| description: Learn how to implement fine-grained authorization for your MCP server tools using Auth0 FGA with roles, groups, and temporal access. | ||
| sidebarTitle: Control Access to MCP Tools | ||
| og:title: "Control Access to MCP Tools with FGA - Auth for MCP Quickstart" | ||
| og:description: "Learn how to implement fine-grained authorization for your MCP server tools using Auth0 FGA." | ||
| og:url: "https://auth0.com/ai/docs" | ||
| twitter:title: "Control Access to MCP Tools with FGA - Auth for MCP Quickstart" | ||
| twitter:description: "Learn how to implement fine-grained authorization for your MCP server tools using Auth0 FGA." | ||
| permalink: "/mcp/get-started/secure-mcp-server-with-auth0-fga" | ||
| --- | ||
|
|
||
| import MCPGetStartedPrerequisites from "/snippets/mcp/get-started/pre-reqs/prerequisites.mdx"; | ||
| import MCPGetStartedConfigTenantSettings from "/snippets/mcp/get-started/config-tenant/config-tenant-settings.mdx"; | ||
| import CreateMCPAPI from "/snippets/mcp/get-started/create-mcp-api.mdx"; | ||
| import FGACLIInstallation from "/snippets/mcp/get-started/fga/fga-cli-installation.mdx"; | ||
| import FGAStoreSetupOverview from "/snippets/mcp/get-started/fga/fga-store-setup-overview.mdx"; | ||
| import SetupFGAStoreCLI from "/snippets/mcp/get-started/fga/setup-fga-store-cli.mdx"; | ||
| import FGAModelExplanation from "/snippets/mcp/get-started/fga/fga-model-explanation.mdx"; | ||
| import CreateEnvFileFGA from "/snippets/mcp/get-started/fga/create-env-file-fga.mdx"; | ||
| import ManagingPermissions from "/snippets/mcp/get-started/fga/managing-permissions.mdx"; | ||
| import MCPGetStartedTestingInstructions from "/snippets/mcp/get-started/testing-instructions.mdx"; | ||
| import { DownloadQuickstartButton } from "/snippets/download-quickstart/DownloadQuickstartButton.jsx"; | ||
|
|
||
| Fine-grained authorization goes beyond simple scope-based access control by enabling sophisticated permission models based on relationships between users, roles, groups, and resources. This quickstart demonstrates how to use [Auth0 FGA](https://auth0.com/fine-grained-authorization) to implement [Relationship-Based Access Control (ReBAC)](https://docs.fga.dev/authorization-concepts#what-is-relationship-based-access-control) for your MCP server tools. | ||
|
|
||
| The sample application showcases five authorization patterns: | ||
|
|
||
| 1. **Public Tools** - Accessible to all authenticated users without additional permissions | ||
| 2. **Role-Based Access** - Tools assigned to specific roles (`admin`, `content_editor`) | ||
| 3. **Group Membership** - Users inherit permissions through group membership (managers, marketing) | ||
| 4. **Temporal Access** - Time-limited tool access with automatic expiration | ||
| 5. **Resource-Specific Permissions** - Fine-grained control over tool features (e.g., viewing private documents) | ||
|
|
||
| By the end of this quickstart, you will have an MCP server that: | ||
| * Authenticates users with Auth0 OAuth 2.0 | ||
| * Uses Auth0 FGA to determine which tools each user can access | ||
| * Dynamically filters tool lists based on user permissions | ||
| * Supports time-limited access grants that automatically expire | ||
| * Provides different data based on user roles (public vs private documents) | ||
|
|
||
| <MCPGetStartedPrerequisites /> | ||
|
|
||
| Now install and setup the dependencies for FGA: | ||
|
|
||
| <AccordionGroup> | ||
| <Accordion title="1. Install the FGA CLI"> | ||
| <FGACLIInstallation /> | ||
| </Accordion> | ||
|
|
||
| <Accordion title="2. Set up Auth0 FGA or OpenFGA"> | ||
| <FGAStoreSetupOverview /> | ||
| </Accordion> | ||
| </AccordionGroup> | ||
|
|
||
| ## Configure tenant settings | ||
|
|
||
| <MCPGetStartedConfigTenantSettings /> | ||
|
|
||
| ## Create an API to represent your MCP server | ||
|
|
||
| <CreateMCPAPI /> | ||
|
|
||
| <Info> | ||
| This quickstart uses two OAuth scopes for demonstration: `tool:greet` and `tool:whoami`. The `get_datetime` tool is public and doesn't require scopes, while `get_documents` uses FGA for authorization. | ||
| </Info> | ||
|
|
||
| ## Set up your FGA store | ||
|
|
||
| <SetupFGAStoreCLI /> | ||
|
|
||
| ## Sample app | ||
|
|
||
| Start by downloading or cloning the sample app for this quickstart. The sample includes a FastMCP MCP server with Auth0 OAuth and Auth0 FGA integration in JavaScript/TypeScript. | ||
|
|
||
| <Tabs> | ||
| <Tab title="Use sample app (recommended)"> | ||
| <DownloadQuickstartButton | ||
| category="auth-for-mcp" | ||
| framework="fastmcp-mcp-fga-js" | ||
| /> | ||
|
|
||
| Once downloaded, extract the files and open the project in your preferred IDE. | ||
| </Tab> | ||
|
|
||
| <Tab title="Clone GitHub repository"> | ||
| Clone the repository and navigate to the sample app folder: | ||
|
|
||
| ```shell wrap lines | ||
| git clone https://github.com/auth0-samples/auth0-ai-samples.git | ||
| cd auth0-ai-samples/auth-for-mcp/fastmcp-mcp-fga-js | ||
| ``` | ||
|
|
||
| Once cloned, open the project in your preferred IDE. | ||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| ## Install packages | ||
|
|
||
| Install the required dependencies: | ||
|
|
||
| ```shell | ||
| npm install | ||
| ``` | ||
|
|
||
| ## Create your environment file | ||
|
|
||
| <CreateEnvFileFGA /> | ||
|
|
||
| ## Understanding the authorization model | ||
|
|
||
| <FGAModelExplanation /> | ||
|
|
||
| ## Import the authorization model and tuples | ||
|
|
||
| The sample includes a complete authorization model and initial permission tuples that define: | ||
| - Public access to `get_datetime` for all users | ||
| - Role assignments (`admin`, `content_editor`) | ||
| - Group-to-role mappings (`managers` → `admin`, `marketing` → `content_editor`) | ||
| - Tool access permissions for each role | ||
|
|
||
| <Steps> | ||
| <Step title="Review the authorization model"> | ||
| The authorization model is defined in `fga/model.fga`. It includes types for users, groups, roles, and tools, plus a temporal access condition. | ||
|
|
||
| The initial tuples are defined in `fga/tuples.yaml` and establish the baseline permissions. | ||
| </Step> | ||
|
|
||
| <Step title="Import the model and tuples"> | ||
| From the root of your sample app directory, run: | ||
|
|
||
| ```shell wrap lines | ||
| fga store import --file fga/store.fga.yaml | ||
| ``` | ||
|
|
||
| This command will: | ||
| 1. Create a new FGA store (if using OpenFGA locally) | ||
| 2. Upload the authorization model from `fga/model.fga` | ||
| 3. Import the initial tuples from `fga/tuples.yaml` | ||
| 4. Run tests defined in `fga/store.fga.yaml` to verify the setup | ||
|
|
||
| <Note> | ||
| If using OpenFGA, the command output will include a store ID. Copy this ID and add it to your `.env` file as `FGA_STORE_ID`. If using Auth0 FGA with existing store, the command will update your store with the new model and tuples. | ||
| </Note> | ||
| </Step> | ||
|
|
||
| <Step title="Verify the import"> | ||
| If the import is successful, you should see output similar to: | ||
|
|
||
| ```json | ||
| { | ||
| "store": { | ||
| "id": "01KB0NZZFAV9AX7SAPWY23KJAF", | ||
| "name": "fastmcp-fga-example", | ||
| "created_at": "2025-01-22T10:30:00Z", | ||
| "updated_at": "2025-01-22T10:30:00Z" | ||
| }, | ||
| "model": { | ||
| "authorization_model_id": "01KED54TEMBDE753YBK7NT3DRZ" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The tests at the end should show all checks passing, confirming that the authorization model is working correctly. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| <Info> | ||
| You can view and manage your authorization model in the [Auth0 FGA Dashboard](https://dashboard.fga.dev) if you're using Auth0 FGA. The dashboard provides a visual Model Explorer and allows you to view, add, and delete tuples in real-time. | ||
| </Info> | ||
|
|
||
| ## Run the MCP server | ||
|
|
||
| Start the MCP server: | ||
|
|
||
| ```shell | ||
| npm run start | ||
| ``` | ||
|
|
||
| The server will start on port 3001 (or the port specified in your `.env` file). You should see console output indicating: | ||
| - The server has started successfully | ||
| - FGA client has been initialized | ||
| - The server is listening for connections at `http://localhost:3001/mcp` | ||
|
|
||
| ``` | ||
| FastMCP Auth0 Example Server started | ||
| FGA client initialized for store: 01KB0NZZFAV9AX7SAPWY23KJAF | ||
| Server listening on http://localhost:3001/mcp | ||
| ``` | ||
|
|
||
| Leave the server running for testing in the next sections. | ||
|
|
||
| ## Manage user permissions | ||
|
|
||
| <ManagingPermissions /> | ||
|
|
||
| <MCPGetStartedTestingInstructions /> | ||
|
|
||
| ### Test authorization scenarios | ||
|
|
||
| Now test different authorization scenarios to see how FGA controls tool access. You'll need to use an MCP client like [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to connect to your server. | ||
|
|
||
| <Steps> | ||
| <Step title="Test baseline access"> | ||
| Connect to your MCP server using your user credentials. Initially, you should only see the public tool. | ||
|
|
||
| **Expected tools**: `get_datetime` | ||
|
|
||
| This demonstrates that without any role or group assignments, authenticated users only have access to public tools. | ||
| </Step> | ||
|
|
||
| <Step title="Grant admin access via managers group"> | ||
| Add your user to the managers group to grant admin role permissions: | ||
|
|
||
| ```shell wrap lines | ||
| ./fga/add-user-to-group.sh YOUR_EMAIL managers | ||
| ``` | ||
|
|
||
| Replace `YOUR_EMAIL` with the email address you use to authenticate. | ||
|
|
||
| Reconnect in your MCP client and verify you now see all tools. | ||
|
|
||
| **Expected tools**: `get_datetime`, `greet`, `whoami`, `get_documents` | ||
|
|
||
| Call the `get_documents` tool and verify that you see both public and private documents in the response. This demonstrates resource-specific permissions based on the admin role. | ||
|
|
||
| <Tip> | ||
| In MCP Inspector, you'll need to disconnect and reconnect (or refresh the connection) after changing permissions. The server queries FGA on each new connection to determine available tools. | ||
| </Tip> | ||
| </Step> | ||
|
|
||
| <Step title="Test content editor role"> | ||
| Switch from admin to content editor by changing group membership: | ||
|
|
||
| ```shell wrap lines | ||
| ./fga/remove-user-from-group.sh YOUR_EMAIL managers | ||
| ./fga/add-user-to-group.sh YOUR_EMAIL marketing | ||
| ``` | ||
|
|
||
| Reconnect in your MCP client. | ||
|
|
||
| **Expected tools**: `get_datetime`, `greet`, `whoami`, `get_documents` | ||
|
|
||
| Call the `get_documents` tool and verify that you now see only public documents (no private documents). This demonstrates how the same tool can provide different data based on user roles. | ||
|
|
||
| **Key difference**: Content editors have access to the same tools as admins but don't have the `can_view_private_documents` permission. | ||
| </Step> | ||
|
|
||
| <Step title="Test temporal access"> | ||
| Remove all group memberships and grant time-limited access to a specific tool: | ||
|
|
||
| ```shell wrap lines | ||
| ./fga/remove-user-from-group.sh YOUR_EMAIL marketing | ||
| ./fga/add-temporal-access.sh YOUR_EMAIL greet 20s | ||
| ``` | ||
|
|
||
| This grants 20 seconds of access to the `greet` tool. | ||
|
|
||
| **Immediately reconnect** in your MCP client. | ||
|
|
||
| **Expected tools**: `get_datetime`, `greet` | ||
|
|
||
| Call the `greet` tool to verify it works. | ||
|
|
||
| **Wait 25 seconds** and reconnect again. | ||
|
|
||
| **Expected tools**: `get_datetime` (only) | ||
|
|
||
| The `greet` tool should no longer appear. This demonstrates automatic expiration of temporal access without any cleanup required. | ||
|
|
||
| <Warning> | ||
| Temporal access is evaluated in real-time on each request. Once the duration expires, FGA automatically denies access even if the tuple still exists in the database. | ||
| </Warning> | ||
| </Step> | ||
| </Steps> | ||
|
|
||
|
|
||
| ## Next steps | ||
|
|
||
| * Learn about the simpler scope-based approach in [Authorization for Your MCP Server](./authorization-for-your-mcp-server) | ||
| * Explore [Auth0 FGA documentation](https://auth0.com/fine-grained-authorization) to learn more about designing authorization models | ||
| * Read about [OpenFGA](https://openfga.dev/docs) for advanced modeling patterns and best practices | ||
| * Learn how to [test your MCP server with MCP Inspector](/mcp/guides/test-your-mcp-server-with-mcp-inspector) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.