-
Notifications
You must be signed in to change notification settings - Fork 36
Add Entra OAuth proxy (via FastMCP AzureAuthProvider) and automated Entra app registration #18
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
Changes from 2 commits
7d6aa3b
22b03c1
e0c8f28
5967e09
eb4c563
15fdc98
9edfc59
c33c031
8652a4f
cb31c05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,4 +30,4 @@ | |
| }, | ||
| }, | ||
| "inputs": [] | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Instructions for coding agents | ||
|
|
||
| ## Adding a new azd environment variable | ||
|
|
||
| An azd environment variable is stored by the azd CLI for each environment. It is passed to the "azd up" command and can configure both provisioning options and application settings. | ||
|
|
||
| When adding new azd environment variables, update these files: | ||
|
|
||
| 1. **infra/main.parameters.json**: Add the new parameter mapping from azd env variable to Bicep parameter | ||
| - Use format `${ENV_VAR_NAME}` for required values | ||
| - Use format `${ENV_VAR_NAME=default}` for optional values with defaults | ||
| - Example: `"useEntraProxy": { "value": "${USE_ENTRA_PROXY=false}" }` | ||
|
|
||
| 2. **infra/main.bicep**: Add the Bicep parameter declaration at the top with `@description` | ||
| - Use `@secure()` decorator for sensitive values like passwords/secrets | ||
| - Example: `@description('Flag to enable feature X') param useFeatureX bool = false` | ||
|
|
||
| 3. **infra/server.bicep** (or other module): If the variable needs to be passed to a container app: | ||
| - Add a parameter to receive the value from main.bicep | ||
| - Add the environment variable to the appropriate `env` array (e.g., `baseEnv`, or a conditional array) | ||
| - For secrets, add to a secrets array and reference via `secretRef` | ||
|
|
||
| 4. **infra/main.bicep**: Pass the parameter value to the module | ||
| - Example: `featureXEnabled: useFeatureX ? someValue : ''` | ||
|
|
||
| 5. **infra/write_env.sh** and **infra/write_env.ps1**: If the variable should be written to `.env` for local development: | ||
| - Add a line to echo/write the value from `azd env get-value` | ||
| - For conditional values, wrap in an if block to only write when populated | ||
|
|
||
| 6. **infra/main.bicep outputs**: If the value needs to be stored back in azd env after provisioning: | ||
| - Add an output (note: `@secure()` parameters cannot be outputs) | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,7 @@ A demonstration project showcasing Model Context Protocol (MCP) implementations | |||||
| - [Deploy to Azure](#deploy-to-azure) | ||||||
| - [Deploy to Azure with private networking](#deploy-to-azure-with-private-networking) | ||||||
| - [Deploy to Azure with Keycloak authentication](#deploy-to-azure-with-keycloak-authentication) | ||||||
| - [Deploy to Azure with Entra OAuth Proxy](#deploy-to-azure-with-entra-oauth-proxy) | ||||||
|
|
||||||
| ## Getting started | ||||||
|
|
||||||
|
|
@@ -360,3 +361,83 @@ This project supports deploying with OAuth 2.0 authentication using Keycloak as | |||||
| | DCR | Open (anonymous) | Require initial access token | Any client can register without auth | | ||||||
|
|
||||||
| > **Note:** Keycloak must be publicly accessible because its URL is dynamically generated by Azure. Token issuer validation requires a known URL, but the mcproutes URL isn't available until after deployment. Using a custom domain would fix this. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Deploy to Azure with Entra OAuth Proxy | ||||||
|
|
||||||
| This project supports deploying with Microsoft Entra ID (Azure AD) authentication using FastMCP's built-in Azure OAuth proxy. This is an alternative to Keycloak that uses Microsoft Entra with your Azure tenant for identity management. | ||||||
|
|
||||||
| ### What gets deployed with Entra OAuth | ||||||
|
|
||||||
| | Component | Description | | ||||||
| |-----------|-------------| | ||||||
| | **Microsoft Entra App Registration** | Created automatically during provisioning with redirect URIs for local development, VS Code, and production | | ||||||
| | **OAuth-protected MCP Server** | FastMCP with AzureProvider for OAuth authentication | | ||||||
| | **CosmosDB OAuth Client Storage** | Persists OAuth client registrations across server restarts | | ||||||
|
|
||||||
| ### Deployment steps for Entra OAuth | ||||||
|
|
||||||
| 1. Enable Entra OAuth proxy: | ||||||
|
|
||||||
| ```bash | ||||||
| azd env set USE_FASTMCP_AUTH true | ||||||
| ``` | ||||||
|
|
||||||
| 2. Deploy to Azure: | ||||||
|
|
||||||
| ```bash | ||||||
| azd up | ||||||
| ``` | ||||||
|
|
||||||
| During deployment: | ||||||
| - **Preprovision hook**: Creates a Microsoft Entra App Registration with a client secret, and stores the credentials in azd environment variables | ||||||
| - **Postprovision hook**: Updates the App Registration with the deployed server URL as an additional redirect URI | ||||||
|
|
||||||
| 3. Verify deployment by checking the outputs: | ||||||
|
|
||||||
| ```bash | ||||||
| azd env get-value MCP_SERVER_URL | ||||||
| azd env get-value FASTMCP_AUTH_AZURE_CLIENT_ID | ||||||
| ``` | ||||||
|
|
||||||
| ### Environment variables | ||||||
|
|
||||||
| The following environment variables are automatically set by the deployment hooks: | ||||||
|
|
||||||
| | Variable | Description | | ||||||
| |----------|-------------| | ||||||
| | `FASTMCP_AUTH_AZURE_CLIENT_ID` | The App Registration's client ID | | ||||||
| | `FASTMCP_AUTH_AZURE_CLIENT_SECRET` | The App Registration's client secret | | ||||||
| | `FASTMCP_AUTH_AZURE_TENANT_ID` | Your Azure tenant ID | | ||||||
|
||||||
| | `FASTMCP_AUTH_AZURE_TENANT_ID` | Your Azure tenant ID | | |
| | `AZURE_TENANT_ID` | Your Azure tenant ID | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
pamelafox marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
pamelafox marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Pre-provision hook to set up Azure/Entra ID app registration for FastMCP OAuth Proxy | ||
|
|
||
| # Check if USE_FASTMCP_AUTH is enabled | ||
| $USE_FASTMCP_AUTH = azd env get-value USE_FASTMCP_AUTH 2>$null | ||
| if ($USE_FASTMCP_AUTH -ne "true") { | ||
| Write-Host "Skipping auth init (USE_FASTMCP_AUTH is not enabled)" | ||
| exit 0 | ||
| } | ||
|
|
||
| Write-Host "Setting up Azure/Entra ID app registration for FastMCP OAuth Proxy..." | ||
| python ./infra/fastmcp_auth_init.py |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #!/bin/bash | ||
| # Pre-provision hook to set up Azure/Entra ID app registration for FastMCP OAuth Proxy | ||
|
|
||
| # Check if USE_FASTMCP_AUTH is enabled | ||
| USE_FASTMCP_AUTH=$(azd env get-value USE_FASTMCP_AUTH 2>/dev/null || echo "false") | ||
| if [ "$USE_FASTMCP_AUTH" != "true" ]; then | ||
| echo "Skipping auth init (USE_FASTMCP_AUTH is not enabled)" | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Setting up Azure/Entra ID app registration for FastMCP OAuth Proxy..." | ||
|
||
| python ./infra/fastmcp_auth_init.py | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # Post-provision hook to update Azure app registration redirect URIs with deployed server URL | ||
|
|
||
| # Check if USE_FASTMCP_AUTH is enabled | ||
| $USE_FASTMCP_AUTH = azd env get-value USE_FASTMCP_AUTH 2>$null | ||
| if ($USE_FASTMCP_AUTH -ne "true") { | ||
| Write-Host "Skipping auth update (USE_FASTMCP_AUTH is not enabled)" | ||
| exit 0 | ||
| } | ||
|
|
||
| Write-Host "Updating FastMCP auth redirect URIs with deployed server URL..." | ||
| python ./infra/fastmcp_auth_update.py |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #!/bin/bash | ||
| # Post-provision hook to update Azure app registration redirect URIs with deployed server URL | ||
|
|
||
| # Check if USE_FASTMCP_AUTH is enabled | ||
| USE_FASTMCP_AUTH=$(azd env get-value USE_FASTMCP_AUTH 2>/dev/null || echo "false") | ||
| if [ "$USE_FASTMCP_AUTH" != "true" ]; then | ||
| echo "Skipping auth update (USE_FASTMCP_AUTH is not enabled)" | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Updating FastMCP auth redirect URIs with deployed server URL..." | ||
| python ./infra/fastmcp_auth_update.py |
Uh oh!
There was an error while loading. Please reload this page.