first commit
This commit is contained in:
483
docs/mcp/oauth.mdx
Normal file
483
docs/mcp/oauth.mdx
Normal file
@@ -0,0 +1,483 @@
|
||||
---
|
||||
title: "OAuth 2.0 Authentication"
|
||||
sidebarTitle: "OAuth Authentication"
|
||||
description: "Configure OAuth 2.0 authentication for MCP HTTP and SSE connections. Support for automatic token refresh, PKCE, and dynamic client registration."
|
||||
icon: "lock"
|
||||
---
|
||||
|
||||
<Info>
|
||||
This page covers **server-level OAuth**, where an admin authenticates once and the token is shared across all requests to that MCP server. If you need each end-user to authenticate with their own credentials (e.g., personal Notion or GitHub accounts), see [Per-User OAuth](./per-user-oauth).
|
||||
</Info>
|
||||
|
||||
## Overview
|
||||
|
||||
OAuth 2.0 authentication enables secure, user-delegated access to MCP servers. Bifrost handles:
|
||||
|
||||
- **Automatic token refresh** - Tokens are refreshed before expiration
|
||||
- **PKCE support** - For public clients without client secrets
|
||||
- **Dynamic registration** - Automatic client registration (RFC 7591)
|
||||
- **OAuth discovery** - Discover endpoints from server URLs
|
||||
- **Token management** - Store and revoke OAuth tokens
|
||||
|
||||
This is ideal for integrations that need user-based access, require periodic re-authorization, or must comply with OAuth 2.0 standards.
|
||||
|
||||
## OAuth Flow
|
||||
|
||||
Bifrost implements the **Authorization Code** flow, the most secure and widely-supported OAuth flow:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant App["Your App"]
|
||||
participant Bifrost as "Bifrost"
|
||||
participant AuthServer as "OAuth Server"
|
||||
participant MCPServer as "MCP Server"
|
||||
|
||||
User->>App: "Add new MCP tool"
|
||||
App->>Bifrost: POST /api/mcp/client (with auth_type: oauth)
|
||||
|
||||
Bifrost->>AuthServer: Request authorization code
|
||||
AuthServer-->>Bifrost: authorize_url + state
|
||||
|
||||
Bifrost-->>App: Return authorize_url
|
||||
App->>User: Redirect to authorize_url
|
||||
User->>AuthServer: Click authorize
|
||||
|
||||
AuthServer-->>User: Redirect to /api/oauth/callback?code=xxx&state=yyy
|
||||
User->>Bifrost: Follow redirect
|
||||
|
||||
Bifrost->>AuthServer: Exchange code for token
|
||||
AuthServer-->>Bifrost: access_token + refresh_token
|
||||
Bifrost->>Bifrost: Store token securely
|
||||
|
||||
App->>Bifrost: POST /api/mcp/client/{id}/complete-oauth
|
||||
Bifrost->>MCPServer: Use access_token for requests
|
||||
MCPServer-->>Bifrost: Tool execution with OAuth auth
|
||||
|
||||
Bifrost-->>App: MCP client connected
|
||||
App->>User: MCP tools now available
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic OAuth Setup
|
||||
|
||||
Configure OAuth authentication when creating an MCP client:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Web UI">
|
||||
|
||||
1. Navigate to **MCP Gateway** and click **New MCP Server**
|
||||
2. Select **HTTP** or **SSE** as connection type
|
||||
3. Set **Auth Type** to **OAuth 2.0**
|
||||
4. Provide OAuth configuration:
|
||||
- **Client ID**: Your OAuth application's client ID
|
||||
- **Client Secret**: (Optional for PKCE) Your OAuth application's secret
|
||||
- **Authorize URL**: OAuth provider's authorization endpoint
|
||||
- **Token URL**: OAuth provider's token endpoint
|
||||
- **Scopes**: Comma-separated list of requested scopes
|
||||
5. Click **Authorize** to start the OAuth flow
|
||||
6. Complete the authorization in the browser
|
||||
7. MCP client will be created with the OAuth token
|
||||
|
||||
</Tab>
|
||||
<Tab title="API">
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/mcp/client \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "authenticated-service",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://api.example.com/mcp",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "your-client-id",
|
||||
"client_secret": "your-client-secret",
|
||||
"authorize_url": "https://auth.example.com/oauth/authorize",
|
||||
"token_url": "https://auth.example.com/oauth/token",
|
||||
"scopes": ["mcp:read", "mcp:write"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}'
|
||||
```
|
||||
|
||||
This returns:
|
||||
```json
|
||||
{
|
||||
"status": "pending_oauth",
|
||||
"message": "OAuth authorization required",
|
||||
"oauth_config_id": "oauth_cfg_abc123",
|
||||
"authorize_url": "https://auth.example.com/oauth/authorize?client_id=...&state=xyz",
|
||||
"expires_at": "2026-01-24T12:30:00Z",
|
||||
"mcp_client_id": "mcp_client_abc123"
|
||||
}
|
||||
```
|
||||
|
||||
Redirect the user to `authorize_url`. After authorization, complete the flow:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/mcp/client/mcp_client_abc123/complete-oauth
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Go SDK">
|
||||
|
||||
```go
|
||||
import "github.com/maximhq/bifrost/core/schemas"
|
||||
|
||||
mcpConfig := &schemas.MCPClientConfig{
|
||||
Name: "authenticated-service",
|
||||
ConnectionType: schemas.MCPConnectionTypeHTTP,
|
||||
ConnectionString: schemas.EnvVar{
|
||||
Value: "https://api.example.com/mcp",
|
||||
},
|
||||
AuthType: schemas.MCPAuthTypeOauth,
|
||||
OauthConfigID: &oauthConfigID, // Set after OAuth flow
|
||||
ToolsToExecute: []string{"*"},
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Advanced OAuth Configuration
|
||||
|
||||
#### PKCE for Public Clients
|
||||
|
||||
For applications without a client secret, use PKCE (Proof Key for Code Exchange):
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "public-client-service",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://api.example.com/mcp",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "your-public-client-id",
|
||||
"authorize_url": "https://auth.example.com/oauth/authorize",
|
||||
"token_url": "https://auth.example.com/oauth/token",
|
||||
"scopes": ["mcp:read"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
Bifrost automatically generates and manages PKCE code verifiers.
|
||||
|
||||
#### Dynamic Client Registration
|
||||
|
||||
If your OAuth server supports RFC 7591, Bifrost can automatically register a client:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "auto-registered-service",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://api.example.com/mcp",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"registration_url": "https://auth.example.com/oauth/register",
|
||||
"server_url": "https://api.example.com",
|
||||
"scopes": ["mcp:read", "mcp:write"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
Bifrost will:
|
||||
1. Discover OAuth endpoints from `server_url`
|
||||
2. Register a new client using `registration_url`
|
||||
3. Use the registered client ID for authorization
|
||||
|
||||
#### OAuth Discovery
|
||||
|
||||
Bifrost can automatically discover OAuth endpoints from your MCP server's metadata:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "discovered-service",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://api.example.com/mcp",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "your-client-id",
|
||||
"server_url": "https://api.example.com",
|
||||
"scopes": ["mcp:read"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
If OAuth endpoints aren't provided, Bifrost will check:
|
||||
1. `/.well-known/oauth-authorization-server` (RFC 8414)
|
||||
2. `/.well-known/openid-configuration`
|
||||
3. Server MCP metadata
|
||||
|
||||
## Token Management
|
||||
|
||||
### View OAuth Token Status
|
||||
|
||||
Check the status of an OAuth configuration:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/oauth/config/oauth_cfg_abc123/status
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"id": "oauth_cfg_abc123",
|
||||
"status": "authorized",
|
||||
"created_at": "2026-01-24T10:00:00Z",
|
||||
"expires_at": "2026-01-31T10:00:00Z",
|
||||
"token_id": "oauth_token_xyz",
|
||||
"token_expires_at": "2026-01-25T10:00:00Z",
|
||||
"token_scopes": ["mcp:read", "mcp:write"]
|
||||
}
|
||||
```
|
||||
|
||||
**Status values:**
|
||||
- `pending`: User hasn't authorized yet
|
||||
- `authorized`: Token is valid and active
|
||||
- `failed`: Authorization failed or token is invalid
|
||||
|
||||
### Automatic Token Refresh
|
||||
|
||||
Bifrost automatically refreshes OAuth tokens before expiration. No action required - tokens are refreshed transparently during tool execution.
|
||||
|
||||
### Revoke OAuth Token
|
||||
|
||||
Revoke an OAuth token when you want to disconnect:
|
||||
|
||||
```bash
|
||||
curl -X DELETE http://localhost:8080/api/oauth/config/oauth_cfg_abc123
|
||||
```
|
||||
|
||||
This:
|
||||
- Revokes the token with the OAuth provider
|
||||
- Deletes the token from Bifrost
|
||||
- Removes the OAuth configuration
|
||||
- The MCP client can still be used if auth_type is changed
|
||||
|
||||
## Common OAuth Providers
|
||||
|
||||
### GitHub
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Configuration">
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "github-integration",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://github.example.com/api/v1/mcp",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "your-github-app-id",
|
||||
"client_secret": "your-github-app-secret",
|
||||
"authorize_url": "https://github.com/login/oauth/authorize",
|
||||
"token_url": "https://github.com/login/oauth/access_token",
|
||||
"scopes": ["repo", "user"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Setup Steps">
|
||||
|
||||
1. Go to Settings → Developer settings → OAuth Apps
|
||||
2. Click "New OAuth App"
|
||||
3. Fill in:
|
||||
- **Application name**: Bifrost MCP
|
||||
- **Homepage URL**: `https://your-bifrost-domain.com`
|
||||
- **Authorization callback URL**: `https://your-bifrost-domain.com/api/oauth/callback`
|
||||
4. Copy Client ID and Client Secret
|
||||
5. Use in Bifrost configuration above
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Google
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Configuration">
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "google-api",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://mcp.example.com/api",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "your-google-client-id.apps.googleusercontent.com",
|
||||
"client_secret": "your-google-client-secret",
|
||||
"authorize_url": "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
"token_url": "https://oauth2.googleapis.com/token",
|
||||
"scopes": ["openid", "email", "profile"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Setup Steps">
|
||||
|
||||
1. Go to [Google Cloud Console](https://console.cloud.google.com)
|
||||
2. Create a new project
|
||||
3. Enable OAuth 2.0 consent screen
|
||||
4. Create OAuth 2.0 Client ID (Web application)
|
||||
5. Add Authorized redirect URIs:
|
||||
- `https://your-bifrost-domain.com/api/oauth/callback`
|
||||
6. Copy Client ID and Client Secret
|
||||
7. Use in Bifrost configuration above
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Custom OAuth Server
|
||||
|
||||
For your own OAuth server:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "custom-oauth-service",
|
||||
"connection_type": "http",
|
||||
"connection_string": "https://mcp.yourcompany.com/mcp",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "bifrost-client-id",
|
||||
"client_secret": "bifrost-client-secret",
|
||||
"authorize_url": "https://auth.yourcompany.com/authorize",
|
||||
"token_url": "https://auth.yourcompany.com/token",
|
||||
"registration_url": "https://auth.yourcompany.com/register",
|
||||
"server_url": "https://mcp.yourcompany.com",
|
||||
"scopes": ["mcp:full"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### OAuth Flow Doesn't Start
|
||||
|
||||
**Problem:** `authorize_url` not returned when creating MCP client
|
||||
|
||||
**Solutions:**
|
||||
- Ensure `auth_type` is set to `"oauth"`
|
||||
- Check that `oauth_config` is provided in the request
|
||||
- Verify `authorize_url` is specified or `server_url` is provided for discovery
|
||||
|
||||
### Token Refresh Fails
|
||||
|
||||
**Problem:** Tools fail with "OAuth token expired" or "OAuth token invalid"
|
||||
|
||||
**Solutions:**
|
||||
- Check if the refresh token is still valid
|
||||
- Revoke and re-authorize: `DELETE /api/oauth/config/{id}` then create a new client
|
||||
- Verify the OAuth provider hasn't revoked the token
|
||||
- Check that scopes are still sufficient
|
||||
|
||||
### Authorization Callback Hangs
|
||||
|
||||
**Problem:** Redirect to `/api/oauth/callback` doesn't complete
|
||||
|
||||
**Solutions:**
|
||||
- Ensure Bifrost is accessible at the registered callback URL
|
||||
- Check network connectivity between Bifrost and OAuth provider
|
||||
- Verify the `state` parameter matches (for CSRF protection)
|
||||
- Check Bifrost logs for errors: `grep -i oauth /var/log/bifrost`
|
||||
|
||||
### MCP Client Won't Connect with OAuth
|
||||
|
||||
**Problem:** MCP client shows "error" state with OAuth configured
|
||||
|
||||
**Solutions:**
|
||||
- Verify OAuth token is still valid: `GET /api/oauth/config/{id}/status`
|
||||
- Check that OAuth token has required scopes
|
||||
- Ensure MCP server accepts the `Authorization: Bearer {token}` header
|
||||
- Test HTTP connectivity to MCP server
|
||||
|
||||
## API Reference
|
||||
|
||||
### Create MCP Client with OAuth
|
||||
|
||||
**POST** `/api/mcp/client`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "string",
|
||||
"connection_type": "http|sse",
|
||||
"connection_string": "string",
|
||||
"auth_type": "oauth",
|
||||
"oauth_config": {
|
||||
"client_id": "string",
|
||||
"client_secret": "string (optional)",
|
||||
"authorize_url": "string",
|
||||
"token_url": "string",
|
||||
"registration_url": "string (optional)",
|
||||
"server_url": "string (optional for discovery)",
|
||||
"scopes": ["string"]
|
||||
},
|
||||
"tools_to_execute": ["*"]
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** `OAuthFlowInitiation` with `authorize_url`
|
||||
|
||||
### Complete OAuth Flow
|
||||
|
||||
**POST** `/api/mcp/client/{mcp_client_id}/complete-oauth`
|
||||
|
||||
Called after user authorizes and is redirected back. Bifrost automatically handles the code exchange.
|
||||
|
||||
**Response:** `SuccessResponse`
|
||||
|
||||
### Get OAuth Config Status
|
||||
|
||||
**GET** `/api/oauth/config/{oauth_config_id}/status`
|
||||
|
||||
Returns current status of OAuth configuration and token information.
|
||||
|
||||
**Response:** `OAuthConfigStatus`
|
||||
|
||||
### Revoke OAuth Token
|
||||
|
||||
**DELETE** `/api/oauth/config/{oauth_config_id}`
|
||||
|
||||
Revokes the token and removes OAuth configuration.
|
||||
|
||||
**Response:** `SuccessResponse`
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use HTTPS** - Always use HTTPS for OAuth flows. OAuth providers won't accept HTTP callback URLs in production.
|
||||
|
||||
2. **Secure Client Secrets** - Store client secrets in environment variables or secure vaults, not in version control.
|
||||
|
||||
3. **Rotate Tokens** - Periodically revoke and re-authorize OAuth tokens for enhanced security.
|
||||
|
||||
4. **Monitor Token Status** - Check token status regularly, especially before critical operations.
|
||||
|
||||
5. **Handle Refresh Failures** - If token refresh fails, prompt user to re-authorize rather than silently failing.
|
||||
|
||||
6. **Limit Scopes** - Request only the scopes your MCP tools actually need.
|
||||
|
||||
7. **Log OAuth Operations** - Keep audit logs of OAuth authorizations and token usage.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- **Token Storage** - Bifrost stores OAuth tokens in the database encrypted. Never log or expose tokens.
|
||||
- **PKCE Requirement** - For public clients, PKCE is automatically enabled and verified.
|
||||
- **State Parameter** - CSRF protection via state parameter is enforced in OAuth flows.
|
||||
- **Token Expiration** - Tokens are automatically refreshed, reducing the window of vulnerability.
|
||||
- **Revocation Support** - Tokens can be revoked immediately if compromised.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Connect to MCP Servers →](./connecting-to-servers)
|
||||
- [Tool Execution →](./tool-execution)
|
||||
- [Agent Mode →](./agent-mode)
|
||||
Reference in New Issue
Block a user