> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getbifrost.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 2.0 Authentication

> Configure OAuth 2.0 authentication for MCP HTTP and SSE connections. Support for automatic token refresh, PKCE, and dynamic client registration.

<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 theme={null}
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 theme={null}
    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 theme={null}
    {
      "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 theme={null}
    curl -X POST http://localhost:8080/api/mcp/client/mcp_client_abc123/complete-oauth
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    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 theme={null}
{
  "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 theme={null}
{
  "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

<Warning>
  The `redirect_uri` is registered with the upstream provider at this point and is **locked** to Bifrost's current client URL (`mcp_external_client_url`, or the `Host` header if unset). If you later change Bifrost's public URL, the upstream provider will reject the authorize call with **"Invalid redirect URI"**. To recover, clear the stored client credentials for this MCP server so Bifrost re-runs Dynamic Client Registration with the new URL.
</Warning>

#### OAuth Discovery

Bifrost can automatically discover OAuth endpoints from your MCP server's metadata:

```json theme={null}
{
  "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 theme={null}
curl http://localhost:8080/api/oauth/config/oauth_cfg_abc123/status
```

Response:

```json theme={null}
{
  "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 theme={null}
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 theme={null}
    {
      "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 theme={null}
    {
      "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 theme={null}
{
  "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 theme={null}
{
  "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)
