770 lines
26 KiB
YAML
770 lines
26 KiB
YAML
oauth-callback:
|
|
get:
|
|
operationId: handleOAuthCallback
|
|
summary: OAuth callback endpoint
|
|
description: |
|
|
Handles the OAuth provider callback after user authorization.
|
|
This endpoint processes the authorization code and exchanges it for an access token.
|
|
On success, displays an HTML page that closes the authorization window.
|
|
tags:
|
|
- OAuth
|
|
parameters:
|
|
- name: state
|
|
in: query
|
|
required: true
|
|
description: State parameter for OAuth security (CSRF protection)
|
|
schema:
|
|
type: string
|
|
- name: code
|
|
in: query
|
|
required: true
|
|
description: Authorization code from the OAuth provider
|
|
schema:
|
|
type: string
|
|
- name: error
|
|
in: query
|
|
required: false
|
|
description: Error code if authorization failed
|
|
schema:
|
|
type: string
|
|
- name: error_description
|
|
in: query
|
|
required: false
|
|
description: Error description if authorization failed
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OAuth authorization successful. Returns HTML page that closes the authorization window.
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
'400':
|
|
description: OAuth authorization failed or missing required parameters
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
|
|
oauth-config-status:
|
|
get:
|
|
operationId: getOAuthConfigStatus
|
|
summary: Get OAuth config status
|
|
description: |
|
|
Retrieves the current status of an OAuth configuration.
|
|
Shows whether the OAuth flow is pending, authorized, or failed,
|
|
and includes token expiration and scopes if authorized.
|
|
tags:
|
|
- OAuth
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: OAuth config ID
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OAuth config status retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/oauth.yaml#/OAuthConfigStatus'
|
|
'404':
|
|
description: OAuth config not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'500':
|
|
$ref: '../../openapi.yaml#/components/responses/InternalError'
|
|
|
|
delete:
|
|
operationId: revokeOAuthConfig
|
|
summary: Revoke OAuth config
|
|
description: |
|
|
Revokes an OAuth configuration and its associated access token.
|
|
After revocation, the MCP client will no longer be able to use this OAuth token.
|
|
tags:
|
|
- OAuth
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: OAuth config ID
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OAuth token revoked successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
|
|
'500':
|
|
$ref: '../../openapi.yaml#/components/responses/InternalError'
|
|
|
|
# ─── Per-User OAuth 2.1 Authorization Server ───────────────────────────────
|
|
# These endpoints implement RFC 7591 (dynamic registration), RFC 7636 (PKCE),
|
|
# and the OAuth 2.1 authorization code flow. MCP clients use them automatically
|
|
# when connecting to Bifrost's /mcp endpoint. Only active when at least one MCP
|
|
# client is configured with auth_type: per_user_oauth.
|
|
|
|
per-user-oauth-register:
|
|
post:
|
|
operationId: registerPerUserOAuthClient
|
|
summary: Register OAuth client (RFC 7591)
|
|
description: |
|
|
Dynamic Client Registration per RFC 7591. MCP clients (Claude Code, Cursor, etc.)
|
|
call this endpoint to obtain a `client_id` before initiating the authorization flow.
|
|
|
|
This endpoint is only available when at least one MCP client is configured with
|
|
`auth_type: per_user_oauth`. Returns `404` otherwise.
|
|
|
|
Authentication is not required — this is part of the unauthenticated OAuth bootstrap flow.
|
|
tags:
|
|
- OAuth
|
|
- Per-User OAuth
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/oauth.yaml#/PerUserOAuthClientRegistrationRequest'
|
|
example:
|
|
client_name: "Claude Code"
|
|
redirect_uris: ["http://localhost:54321/callback"]
|
|
grant_types: ["authorization_code"]
|
|
response_types: ["code"]
|
|
token_endpoint_auth_method: "none"
|
|
responses:
|
|
'201':
|
|
description: Client registered successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/oauth.yaml#/PerUserOAuthClientRegistrationResponse'
|
|
example:
|
|
client_id: "550e8400-e29b-41d4-a716-446655440000"
|
|
client_name: "Claude Code"
|
|
redirect_uris: ["http://localhost:54321/callback"]
|
|
grant_types: ["authorization_code"]
|
|
token_endpoint_auth_method: "none"
|
|
'400':
|
|
$ref: '../../openapi.yaml#/components/responses/BadRequest'
|
|
'404':
|
|
description: No per-user OAuth MCP clients configured
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
'503':
|
|
description: Config store is disabled
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
|
|
per-user-oauth-authorize:
|
|
get:
|
|
operationId: authorizePerUserOAuth
|
|
summary: Authorization endpoint (OAuth 2.1)
|
|
description: |
|
|
OAuth 2.1 authorization endpoint. Validates the request parameters, creates a
|
|
browser-bound `PendingFlow` record (15-minute TTL), and redirects the user to
|
|
the Bifrost consent screen at `/oauth/consent?flow_id=xxx`.
|
|
|
|
**PKCE is required** — `code_challenge` and `code_challenge_method=S256` must
|
|
be provided. Plain code challenges are not supported.
|
|
|
|
A `__bifrost_flow_secret` HttpOnly SameSite=Lax cookie is set on redirect to
|
|
bind the consent flow to the initiating browser session (CSRF protection).
|
|
|
|
Authentication is not required — this is part of the unauthenticated OAuth bootstrap flow.
|
|
tags:
|
|
- OAuth
|
|
- Per-User OAuth
|
|
parameters:
|
|
- name: response_type
|
|
in: query
|
|
required: true
|
|
description: Must be `code`
|
|
schema:
|
|
type: string
|
|
enum: [code]
|
|
- name: client_id
|
|
in: query
|
|
required: true
|
|
description: Client ID obtained from the registration endpoint
|
|
schema:
|
|
type: string
|
|
- name: redirect_uri
|
|
in: query
|
|
required: true
|
|
description: Must match a URI registered for this client
|
|
schema:
|
|
type: string
|
|
- name: code_challenge
|
|
in: query
|
|
required: true
|
|
description: PKCE code challenge (Base64URL-encoded SHA-256 of the code verifier)
|
|
schema:
|
|
type: string
|
|
- name: code_challenge_method
|
|
in: query
|
|
required: true
|
|
description: Must be `S256`
|
|
schema:
|
|
type: string
|
|
enum: [S256]
|
|
- name: state
|
|
in: query
|
|
required: false
|
|
description: Opaque value to maintain state between request and callback (CSRF protection)
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'302':
|
|
description: Redirect to consent screen at `/oauth/consent?flow_id=xxx`
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
description: URL of the consent screen
|
|
Set-Cookie:
|
|
schema:
|
|
type: string
|
|
description: "`__bifrost_flow_secret` HttpOnly SameSite=Lax cookie for browser binding"
|
|
'400':
|
|
$ref: '../../openapi.yaml#/components/responses/BadRequest'
|
|
'404':
|
|
description: No per-user OAuth MCP clients configured, or unknown client_id
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
'503':
|
|
description: Config store is disabled
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
|
|
per-user-oauth-token:
|
|
post:
|
|
operationId: exchangePerUserOAuthToken
|
|
summary: Token endpoint (OAuth 2.1)
|
|
description: |
|
|
OAuth 2.1 token endpoint. Exchanges a single-use authorization code (5-minute TTL)
|
|
for a Bifrost-issued access token (24-hour TTL) using PKCE verification.
|
|
|
|
The request body must be `application/x-www-form-urlencoded`.
|
|
|
|
The returned `access_token` is the Bearer token to use on subsequent `/mcp` requests.
|
|
It carries the user's upstream service tokens (Notion, GitHub, etc.) linked to their
|
|
identity (Virtual Key or User ID) from the consent flow.
|
|
|
|
Authentication is not required — this is part of the unauthenticated OAuth bootstrap flow.
|
|
tags:
|
|
- OAuth
|
|
- Per-User OAuth
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- grant_type
|
|
- code
|
|
- code_verifier
|
|
properties:
|
|
grant_type:
|
|
type: string
|
|
description: Must be `authorization_code`
|
|
enum: [authorization_code]
|
|
code:
|
|
type: string
|
|
description: Authorization code received in the redirect callback
|
|
redirect_uri:
|
|
type: string
|
|
description: Must match the redirect_uri used in the authorize request (if provided)
|
|
client_id:
|
|
type: string
|
|
description: Client ID (optional — code is already bound to the client)
|
|
code_verifier:
|
|
type: string
|
|
description: PKCE code verifier — the raw secret whose SHA-256 matches the code_challenge
|
|
responses:
|
|
'200':
|
|
description: Token issued successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/oauth.yaml#/PerUserOAuthTokenResponse'
|
|
example:
|
|
access_token: "abc123xyz..."
|
|
token_type: "Bearer"
|
|
expires_in: 86400
|
|
scope: "mcp:read mcp:write"
|
|
'400':
|
|
description: Invalid grant, expired code, PKCE failure, or unsupported grant type
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
enum: [invalid_grant, invalid_request, unsupported_grant_type]
|
|
error_description:
|
|
type: string
|
|
'404':
|
|
description: No per-user OAuth MCP clients configured
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
'500':
|
|
description: Server error or session creation failed
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
enum: [server_error]
|
|
error_description:
|
|
type: string
|
|
|
|
per-user-oauth-upstream-authorize:
|
|
get:
|
|
operationId: authorizeUpstreamPerUserOAuth
|
|
summary: Upstream OAuth proxy — authorize with upstream service
|
|
description: |
|
|
Initiates an OAuth flow with an upstream MCP service (Notion, GitHub, etc.)
|
|
on behalf of the current user. Used during the consent flow (via "Connect" buttons
|
|
on the MCPs page) and at runtime when a tool call is made to an unauthenticated service.
|
|
|
|
**Consent flow** — provide `flow_id` (from the pending consent flow). The browser-binding
|
|
cookie (`__bifrost_flow_secret`) is validated.
|
|
|
|
**Runtime flow** — provide `session` (the Bifrost session ID from the token endpoint).
|
|
Used when a service was skipped during consent and needs to be connected later.
|
|
|
|
On success, redirects the user to the upstream provider's authorize URL. After the user
|
|
grants access, the upstream callback lands at `/api/oauth/callback`, stores the upstream
|
|
token against the user's identity, and redirects back to the consent screen (consent flow)
|
|
or returns an authorization success page (runtime flow).
|
|
|
|
Authentication is not required — cookie/session validation is performed instead.
|
|
tags:
|
|
- OAuth
|
|
- Per-User OAuth
|
|
parameters:
|
|
- name: mcp_client_id
|
|
in: query
|
|
required: true
|
|
description: ID of the per-user OAuth MCP client to authenticate with
|
|
schema:
|
|
type: string
|
|
- name: flow_id
|
|
in: query
|
|
required: false
|
|
description: |
|
|
Pending consent flow ID. Required if `session` is not provided.
|
|
The `__bifrost_flow_secret` cookie must be present and match the flow.
|
|
schema:
|
|
type: string
|
|
- name: session
|
|
in: query
|
|
required: false
|
|
description: |
|
|
Bifrost session ID (from the token endpoint). Required if `flow_id` is not provided.
|
|
Used for runtime (post-consent) upstream authorization.
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'302':
|
|
description: Redirect to upstream OAuth provider's authorize URL
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
description: Upstream provider authorization URL with PKCE parameters
|
|
'400':
|
|
$ref: '../../openapi.yaml#/components/responses/BadRequest'
|
|
'401':
|
|
description: Invalid or expired flow/session
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'403':
|
|
description: Browser-binding cookie mismatch (CSRF protection)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'404':
|
|
description: MCP client not found or not configured for per-user OAuth
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'503':
|
|
description: Config store is disabled
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
|
|
# ─── Per-User OAuth Consent Flow (browser UI) ──────────────────────────────
|
|
# These endpoints serve HTML pages and handle form submissions for the
|
|
# multi-step consent flow. They are browser-facing, not JSON API endpoints.
|
|
# All endpoints validate the __bifrost_flow_secret browser-binding cookie.
|
|
|
|
consent-identity-page:
|
|
get:
|
|
operationId: getConsentIdentityPage
|
|
summary: Consent identity selection page
|
|
description: |
|
|
Renders the identity selection screen where the user chooses how to identify
|
|
themselves for the session: Virtual Key, User ID, or Skip (session-only auth).
|
|
|
|
The `__bifrost_flow_secret` HttpOnly cookie set during `/api/oauth/per-user/authorize`
|
|
must be present — it binds the consent flow to the initiating browser.
|
|
|
|
The Skip option is only shown when `enforce_auth_on_inference` is `false` in config.
|
|
tags:
|
|
- Per-User OAuth
|
|
- Consent Flow
|
|
parameters:
|
|
- name: flow_id
|
|
in: query
|
|
required: true
|
|
description: Pending flow ID from the authorize redirect
|
|
schema:
|
|
type: string
|
|
- name: error
|
|
in: query
|
|
required: false
|
|
description: Error message to display (used on redirect-back from failed form submissions)
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Identity selection HTML page
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
'400':
|
|
description: Missing or expired flow_id
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
'403':
|
|
description: Browser-binding cookie mismatch
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
|
|
consent-mcps-page:
|
|
get:
|
|
operationId: getConsentMCPsPage
|
|
summary: Consent MCP services page
|
|
description: |
|
|
Renders the MCP services connection screen. Shows all per-user OAuth MCP servers
|
|
available on the user's Virtual Key (or all servers if no VK was selected).
|
|
Each service shows a "Connect" link or a "Connected ✓" badge.
|
|
|
|
Requires the `__bifrost_flow_secret` browser-binding cookie.
|
|
tags:
|
|
- Per-User OAuth
|
|
- Consent Flow
|
|
parameters:
|
|
- name: flow_id
|
|
in: query
|
|
required: true
|
|
description: Pending flow ID
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: MCP services connection HTML page
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
'400':
|
|
description: Missing or expired flow_id
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
'403':
|
|
description: Browser-binding cookie mismatch
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
|
|
consent-submit-vk:
|
|
post:
|
|
operationId: submitConsentVirtualKey
|
|
summary: Submit Virtual Key identity
|
|
description: |
|
|
Validates the submitted Virtual Key and links it to the pending flow as the user's
|
|
identity. On success, redirects to the MCPs page. On failure, redirects back to the
|
|
identity page with an error message.
|
|
|
|
Request body is `application/x-www-form-urlencoded` (browser form submission).
|
|
tags:
|
|
- Per-User OAuth
|
|
- Consent Flow
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required: [flow_id, vk]
|
|
properties:
|
|
flow_id:
|
|
type: string
|
|
description: Pending flow ID
|
|
vk:
|
|
type: string
|
|
description: Virtual Key value (validated against the database)
|
|
responses:
|
|
'302':
|
|
description: |
|
|
Redirect to `/oauth/consent/mcps?flow_id=xxx` on success, or back to
|
|
`/oauth/consent?flow_id=xxx&error=...` on failure.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
|
|
consent-submit-user-id:
|
|
post:
|
|
operationId: submitConsentUserID
|
|
summary: Submit User ID identity
|
|
description: |
|
|
Links a self-declared User ID to the pending flow as the user's identity.
|
|
On success, redirects to the MCPs page.
|
|
|
|
The User ID is self-declared with no server-side verification — it matches
|
|
the trust model of the `X-Bf-User-Id` header in the LLM Gateway path.
|
|
|
|
Request body is `application/x-www-form-urlencoded` (browser form submission).
|
|
tags:
|
|
- Per-User OAuth
|
|
- Consent Flow
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required: [flow_id, user_id]
|
|
properties:
|
|
flow_id:
|
|
type: string
|
|
description: Pending flow ID
|
|
user_id:
|
|
type: string
|
|
description: Self-declared user identifier (max 255 characters)
|
|
responses:
|
|
'302':
|
|
description: |
|
|
Redirect to `/oauth/consent/mcps?flow_id=xxx` on success, or back to
|
|
`/oauth/consent?flow_id=xxx&error=...` on failure.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
|
|
consent-skip:
|
|
post:
|
|
operationId: skipConsentIdentity
|
|
summary: Skip identity selection
|
|
description: |
|
|
Skips identity selection and proceeds directly to the MCPs page. Upstream service
|
|
tokens will be stored against the session token only (not a persistent identity),
|
|
so they will not carry over to other sessions or the LLM Gateway.
|
|
|
|
Only available when `enforce_auth_on_inference` is `false` in config. Returns a
|
|
redirect back to the identity page with an error if auth enforcement is enabled.
|
|
|
|
Request body is `application/x-www-form-urlencoded` (browser form submission).
|
|
tags:
|
|
- Per-User OAuth
|
|
- Consent Flow
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required: [flow_id]
|
|
properties:
|
|
flow_id:
|
|
type: string
|
|
description: Pending flow ID
|
|
responses:
|
|
'302':
|
|
description: |
|
|
Redirect to `/oauth/consent/mcps?flow_id=xxx` on success, or back to
|
|
`/oauth/consent?flow_id=xxx&error=...` if identity enforcement is required.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
|
|
consent-submit:
|
|
post:
|
|
operationId: submitConsent
|
|
summary: Finalize consent flow
|
|
description: |
|
|
Finalizes the consent flow atomically:
|
|
1. Creates a `TablePerUserOAuthSession` (24h Bifrost session token)
|
|
2. Transfers upstream tokens from the flow proxy to the session
|
|
3. Issues a single-use `TablePerUserOAuthCode` (5-minute TTL, PKCE-bound)
|
|
4. Deletes the `PendingFlow`
|
|
5. Redirects to the MCP client's `redirect_uri` with `code` and `state`
|
|
|
|
The MCP client then exchanges the code at `/api/oauth/per-user/token`.
|
|
|
|
Request body is `application/x-www-form-urlencoded` (browser form submission).
|
|
tags:
|
|
- Per-User OAuth
|
|
- Consent Flow
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required: [flow_id]
|
|
properties:
|
|
flow_id:
|
|
type: string
|
|
description: Pending flow ID
|
|
responses:
|
|
'302':
|
|
description: |
|
|
Redirect to the MCP client's registered `redirect_uri` with
|
|
`?code=xxx&state=yyy` query parameters.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
description: MCP client callback URL with code and state
|
|
'400':
|
|
$ref: '../../openapi.yaml#/components/responses/BadRequest'
|
|
'403':
|
|
description: Browser-binding cookie mismatch
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'409':
|
|
description: Consent flow already submitted (duplicate submission prevention)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'410':
|
|
description: Consent flow expired
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
|
|
'500':
|
|
$ref: '../../openapi.yaml#/components/responses/InternalError'
|
|
|
|
# ─── OAuth Discovery (RFC 9728 + RFC 8414) ─────────────────────────────────
|
|
# These well-known endpoints enable MCP clients to auto-discover Bifrost's
|
|
# OAuth configuration. Only active when at least one MCP client is configured
|
|
# with auth_type: per_user_oauth.
|
|
|
|
oauth-protected-resource-metadata:
|
|
get:
|
|
operationId: getOAuthProtectedResourceMetadata
|
|
summary: Protected Resource Metadata (RFC 9728)
|
|
description: |
|
|
Returns the OAuth 2.0 Protected Resource Metadata document per RFC 9728.
|
|
|
|
MCP clients fetch this after receiving a `401` response from `/mcp` (with a
|
|
`WWW-Authenticate: Bearer resource_metadata=".../.well-known/oauth-protected-resource"`
|
|
header). The response tells the client which authorization server(s) protect the
|
|
`/mcp` resource so it can proceed with discovery.
|
|
|
|
Returns `404` when no MCP clients are configured with `auth_type: per_user_oauth`.
|
|
tags:
|
|
- OAuth
|
|
- Per-User OAuth
|
|
responses:
|
|
'200':
|
|
description: Protected resource metadata
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/oauth.yaml#/ProtectedResourceMetadata'
|
|
example:
|
|
resource: "https://your-bifrost-domain.com/mcp"
|
|
authorization_servers: ["https://your-bifrost-domain.com"]
|
|
scopes_supported: ["mcp:read", "mcp:write"]
|
|
bearer_methods_supported: ["header"]
|
|
'404':
|
|
description: No per-user OAuth MCP clients configured
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
|
|
oauth-authorization-server-metadata:
|
|
get:
|
|
operationId: getOAuthAuthorizationServerMetadata
|
|
summary: Authorization Server Metadata (RFC 8414)
|
|
description: |
|
|
Returns the OAuth 2.0 Authorization Server Metadata document per RFC 8414.
|
|
|
|
After fetching the Protected Resource Metadata, MCP clients fetch this endpoint
|
|
to discover Bifrost's OAuth endpoints (register, authorize, token) and capabilities
|
|
(PKCE methods, grant types, etc.).
|
|
|
|
Returns `404` when no MCP clients are configured with `auth_type: per_user_oauth`.
|
|
tags:
|
|
- OAuth
|
|
- Per-User OAuth
|
|
responses:
|
|
'200':
|
|
description: Authorization server metadata
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../../schemas/management/oauth.yaml#/AuthorizationServerMetadata'
|
|
example:
|
|
issuer: "https://your-bifrost-domain.com"
|
|
authorization_endpoint: "https://your-bifrost-domain.com/api/oauth/per-user/authorize"
|
|
token_endpoint: "https://your-bifrost-domain.com/api/oauth/per-user/token"
|
|
registration_endpoint: "https://your-bifrost-domain.com/api/oauth/per-user/register"
|
|
response_types_supported: ["code"]
|
|
grant_types_supported: ["authorization_code"]
|
|
code_challenge_methods_supported: ["S256"]
|
|
token_endpoint_auth_methods_supported: ["none"]
|
|
scopes_supported: ["mcp:read", "mcp:write"]
|
|
'404':
|
|
description: No per-user OAuth MCP clients configured
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|