- User Authentication: Authenticate specific users through the AI Gateway using the Authorization Code flow with refresh tokens
- Machine-to-Machine Authentication: Enable programmatic access without user interaction using the Client Credentials grant flow
Prerequisites
Before you begin, ensure you have:- An Okta account with admin access
- A TrueFoundry account with a workspace
- Basic understanding of OAuth2 flows
- Python 3.13 installed for local testing
1. Setup on Okta (User Authentication)
This section covers the setup for user authentication through the AI Gateway. The authorization server created here will also be used for machine-to-machine authentication (see Section 4).Create an OAuth Application
1
Create an OAuth2 Application
Create the OAuth2 application that will authenticate users.
- Navigate to Applications > Applications in the Okta dashboard
- Click Create App Integration
- Select OIDC - OpenID Connect
- Select Web Application as the application type
- Configure the application:
- App integration name:
MCP Server Client - Grant type: Check:
- Authorization Code (required for user authentication via Gateway)
- Refresh Token (required to enable automatic token refresh)
- Sign-in redirect URIs: Add
https://<your-tfy-control-plane-url>/api/svc/v1/llm-gateway/mcp-servers/oauth2/callback
- App integration name:
Authorization Code and Refresh Token are required for the Gateway OAuth integration to enable automatic token refresh. For machine-to-machine authentication, see Section 4.
- Click Save
- Note the Client ID and Client Secret from the application page
Create an Authorization Server
1
Create an Authorization Server
An authorization server issues tokens that your MCP server will validate. This authorization server will be used for both user authentication (via the Gateway) and machine-to-machine authentication.
The authorization server is common for both user authentication and machine-to-machine authentication. You only need to create it once.
- Navigate to Security > API in the Okta dashboard
- Click Add Authorization Server
- Configure with the following:
- Name:
MCP Server Auth(or your preferred name) - Audience:
https://your-mcp-server.example.com(this will be your MCP server’s identifier) - Description: Authorization server for MCP servers
- Name:
- Click Save
- Note the Issuer URI from the Settings tab (e.g.,
https://dev-12345678.okta.com/oauth2/aus123abc)
The audience value is an identifier for your API/resource. It doesn’t have to be an actual URL, but using a URL format is a common convention.
2
Configure Scopes
Define what permissions your application can request.
- In your Authorization Server, go to the Scopes tab
- Add custom scopes if needed (e.g.,
read:data,write:data)
3
Create Access Policy and Rule
Control who can get tokens from your authorization server.
- In your Authorization Server, go to the Access Policies tab
- Click Add New Access Policy
- Configure:
- Name:
MCP Access Policy - Description: Policy for MCP server access
- Assign to: Select your OAuth application
- Name:
- Click Create Policy
- Click Add Rule to create a default rule:
- Rule Name:
Default Rule - Grant type is: Check Authorization Code and Refresh Token
- User is: Any user assigned the app
- Scopes requested: Any scopes
- Access token lifetime: 1 hour (or as per your requirements)
- Rule Name:
- Click Create Rule
If you plan to use machine-to-machine authentication, you’ll need to add Client Credentials grant type to this rule or create a separate access policy. See Section 4 for machine-to-machine setup instructions.
Refresh Token must be enabled in the access policy rule to allow the Gateway to refresh expired access tokens automatically.
Collect Necessary Information
1
Collect Configuration Values
Once you have the OAUTH_ISSUER from your authorization server Settings tab (e.g.,
https://dev-12345678.okta.com/oauth2/aus123abc), you can access the well-known URL:OAUTH_WELL_KNOWN_URL: {OAUTH_ISSUER}/.well-known/oauth-authorization-serverThe well-known endpoint provides the JWKS URI for token verification.You’ll also need:- OAUTH_AUDIENCE: The audience value you configured in the authorization server (e.g.,
https://your-mcp-server.example.com) - CLIENT_ID and CLIENT_SECRET: From your user-facing OAuth application (for Gateway integration)
2. Deploy to TrueFoundry
Now let’s deploy the OAuth-authenticated MCP server as a TrueFoundry service.1
Navigate to Service Deployment
- Go to your TrueFoundry dashboard
- Navigate to Deployments > New Deployment
- Select your workspace
- Choose Service as the deployment type
2
Configure Source Repository
Use the GitHub repository as the source:
- Select GitHub as the source
- Repository URL:
https://github.com/truefoundry/mcp-servers - Branch:
main - Build Context Path:
./sample-oauth-mcp/
If you’re deploying from your own fork, make sure the repository is accessible to TrueFoundry via GitHub integration.
3
Configure Build Settings
Specify how to build and run the service:
- Build Type: Python
- Python Version: 3.13
- Command:
python server.py - Requirements Path:
requirements.txt - Port:
8000
4
Add Environment Variables
Configure the OAuth settings using the values from Step 1:Add these environment variables:
| Variable | Value | Description |
|---|---|---|
OAUTH_WELL_KNOWN_URL | https://dev-12345678.okta.com/oauth2/aus123abc/.well-known/oauth-authorization-server | OAuth authorization server well-known endpoint for auto-discovery |
OAUTH_JWKS_URI | https://dev-12345678.okta.com/oauth2/aus123abc/v1/keys | JSON Web Key Set URI for token verification |
OAUTH_ISSUER | https://dev-12345678.okta.com/oauth2/aus123abc | Authorization server issuer URI |
OAUTH_AUDIENCE | https://your-mcp-server.example.com | Audience identifier for your API |
The MCP server only needs these four environment variables to validate OAuth tokens. It doesn’t need the Client ID or Client Secret since it’s only validating tokens, not generating them.The
OAUTH_WELL_KNOWN_URL enables the MCP server to expose the /.well-known/oauth-authorization-server endpoint, which allows the AI Gateway to auto-discover OAuth configuration details. This endpoint redirects to your Okta authorization server’s well-known endpoint.5
Configure Networking
Set up the service endpoint:
- Port:
8000 - Expose: Enable this to make the service accessible
https://oauth-mcp-server.apps.yourcluster.truefoundry.cloud).6
Deploy the Service
- Review all configurations
- Click Submit to start the deployment
- Monitor the deployment status in the dashboard
- Wait for the status to show Active (green)
Alternative: Deploy Using Python SDK
Alternative: Deploy Using Python SDK
You can also deploy programmatically using the TrueFoundry Python SDK:More details in the Deploy Service Programmatically guide.
3. Integrate with AI Gateway
Now that your OAuth MCP server is deployed, let’s add it to the TrueFoundry AI Gateway.1
Create an MCP Server Group
If you don’t have an MCP Server Group yet:
- Navigate to MCP Servers in the AI Gateway
- Click Add New MCP Group
- Configure:
- Name:
oauth-protected-servers(or your preferred name) - Managers: Select teams/users who can manage servers in this group
- Name:
- Click Create
2
Add Your MCP Server
- In your MCP Server Group, click Add MCP Server
- Select Remote MCP
- Configure the server:
- Name:
oauth-mcp-server - Description: OAuth-authenticated MCP server with Okta
- URL: Your deployed service endpoint (e.g.,
https://oauth-mcp-server.apps.yourcluster.truefoundry.cloud/mcp) - Transport:
streamable-http - Authentication Type: Select OAuth2
- Name:
3
Configure OAuth2 Settings
In the OAuth2 configuration section, provide the Okta credentials:
- OAuth2 Client ID: Your Okta application client ID
- OAuth2 Client Secret: Your Okta application client secret
The AI Gateway will automatically discover the OAuth2 Authorization URL, Token URL, and other configuration details from your MCP server’s
/.well-known/oauth-authorization-server endpoint once you provide the MCP server URL. This endpoint is enabled by the OAUTH_WELL_KNOWN_URL environment variable configured during deployment (see Section 2).You can optionally configure:- OAuth2 Scopes: The scopes are prefilled, but you can change them if needed to use your custom scopes.
4
Set Access Control
Define who can use this MCP server:
- Access Control: Select teams or users who should have access to this server
Managers of the MCP Server Group automatically have access to all servers in the group.
5
Save and Test
- Click Save to add the MCP server
- The server will appear in your MCP Server Group
- Users can now connect and use the server through the AI Gateway
Using the OAuth MCP Server in Playground
To test your OAuth-protected MCP server:1
Open the Playground
Navigate to the Playground in the AI Gateway.
2
Add MCP Server
- Click Add Tool/MCP Servers
- Find your
oauth-mcp-serverin the list - Click Connect Now to initiate OAuth authorization
3
Authorize Access
You’ll be redirected to Okta to authorize access:
- Sign in with your Okta credentials
- Review the requested permissions (scopes)
- Click Allow to grant access
- You’ll be redirected back to the Gateway
4
Select Tools and Test
- Once connected, you’ll see the
get_metool from your MCP server - Select the tool and click Done
- Try sending a prompt like “Get my user details” or “What information do you have about me?”
- The tool will return details from your JWT token, such as your email, name, and other claims from Okta
4. Machine-to-Machine Authentication
This section is optional and only needed if you want to access your MCP server programmatically without user interaction (machine-to-machine communication). For normal user-facing workflows through the AI Gateway, the standard OAuth flow handled by the Gateway (covered in Section 3) is sufficient.
When to Use Machine-to-Machine Authentication
Use machine-to-machine authentication when:- Your application needs to access the MCP server programmatically
- No user interaction is required
Setup
1
Create an API Service Integration
Create a separate API Service Integration app for machine-to-machine access. API Service integrations provide more granular control over policies and are specifically designed for service-to-service communication.The following diagram illustrates how multiple services can access the same MCP server, each with their own Okta app and different scopes for fine-grained access control:Create Custom Scopes (required for API Service Integrations):
Key Points:
- One App Per Service: Each service accessing the MCP server has its own API Service Integration app, providing isolation and granular access control
- Shared MCP Server: Multiple services can access the same MCP server, but each uses different Okta apps with different scopes
- Custom Authorization Server: All apps use the same custom authorization server (not the Org Authorization Server, which is only for Okta APIs)
- Go to your Authorization Server (created in Section 1)
- Navigate to the Scopes tab
- Click Add Scope
- Configure each custom scope:
- Name: Enter a scope name (e.g.,
read,write,read:data,write:data) - Description: Enter a description of what this scope allows (e.g., “Read access to MCP server resources”)
- Name: Enter a scope name (e.g.,
- Click Create to add the scope
- Repeat steps 3-5 for each custom scope you need
- Navigate to Applications > Applications in the Okta dashboard
- Click Create App Integration
- Select API Services
- Configure the integration:
- Integration name:
MCP Server Machine-to-Machine - Description: API service integration for MCP server machine-to-machine authentication
- Integration name:
- Click Save
- Note the Client ID and Client Secret from the integration page
- Go to the General tab and disable DPoP (Demonstrate Proof of Possession) if it’s enabled
DPoP (Demonstrate Proof of Possession): DPoP is not covered in these docs. Make sure to disable DPoP for your API Service Integration app if it’s enabled by default.
2
Add Machine-to-Machine App to Access Policy
To use your machine-to-machine application with your custom authorization server:
- Go to your Authorization Server’s Access Policies tab
- Edit your existing MCP Access Policy (or create a new one)
- In the Assign to field, select:
- Your user-facing OAuth application (for user authentication)
- Your machine-to-machine application (OIDC app with Client Credentials or API Service Integration)
- Edit the access policy rule (or create a new rule):
- Grant type is: Check Client Credentials
- Scopes requested: Select your custom scopes
- Access token lifetime: Set as per your requirements
- Click Save
You can create separate access policies for user authentication and machine-to-machine authentication if you need different rules or token lifetimes for each use case.
Collect Machine-to-Machine Credentials
After setting up your machine-to-machine application, collect these values:- M2M_CLIENT_ID: The Client ID from your machine-to-machine application (OIDC app or API Service Integration)
- M2M_CLIENT_SECRET: The Client Secret from your machine-to-machine application
All other values (OAUTH_ISSUER, OAUTH_AUDIENCE) are already collected in Section 1. You only need the Client ID and Secret for machine-to-machine authentication.
Getting an Access Token
When using a custom authorization server with your API Service Integration, use the token endpoint and custom scopes. The token endpoint can be obtained from the well-known configuration at{OAUTH_ISSUER}/.well-known/oauth-authorization-server. The response includes the token_endpoint:
token_endpoint value from this response in your token requests.
- Using cURL
- Using Python
- Using Python with requests-oauthlib
When using a custom authorization server, you can use custom scopes defined in your authorization server. Make sure to include the
audience parameter matching the audience configured in your authorization server.Token Management Best Practices
Since Client Credentials doesn’t support refresh tokens, you’ll need to request a new access token when the current one expires. Implement automatic token renewal logic to handle token expiration gracefully.
-
Cache tokens: Access tokens are valid for the duration specified in
expires_in. Cache them and reuse until expiry. - Handle expiration: Implement automatic token renewal logic (request a new token when needed). See the TokenManager implementation in the MCP server README for a complete example.
- Secure storage: Never hardcode credentials. Use environment variables or secret management systems.
- Monitor usage: Track token requests to detect unusual patterns that might indicate compromised credentials.