File tree Expand file tree Collapse file tree 5 files changed +29
-9
lines changed
packages/web/src/app/api/(server)
oauth-authorization-server Expand file tree Collapse file tree 5 files changed +29
-9
lines changed Original file line number Diff line number Diff line change @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
88## [ Unreleased]
99
10+ ### Fixed
11+ - Avoid advertising OAuth support on MCP endpoints if that entitlment is not actually configured.
12+
1013## [ 4.15.1] - 2026-03-06
1114
1215### Fixed
Original file line number Diff line number Diff line change 11import { apiHandler } from '@/lib/apiHandler' ;
2- import { env } from '@sourcebot/shared' ;
2+ import { env , hasEntitlement } from '@sourcebot/shared' ;
33
44// RFC 8414: OAuth 2.0 Authorization Server Metadata
5- // @note : we do not gate on entitlements here. That is handled in the /register,
6- // /token, and /revoke routes.
75// @see : https://datatracker.ietf.org/doc/html/rfc8414
86export const GET = apiHandler ( async ( ) => {
7+ if ( ! hasEntitlement ( 'oauth' ) ) {
8+ return Response . json (
9+ { error : 'not_found' , error_description : 'OAuth authorization server metadata is not available on this plan.' } ,
10+ { status : 404 }
11+ ) ;
12+ }
13+
914 const issuer = env . AUTH_URL . replace ( / \/ $ / , '' ) ;
1015
1116 return Response . json ( {
Original file line number Diff line number Diff line change 11import { apiHandler } from '@/lib/apiHandler' ;
2- import { env } from '@sourcebot/shared' ;
2+ import { env , hasEntitlement } from '@sourcebot/shared' ;
33import { NextRequest } from 'next/server' ;
44
55// RFC 9728: OAuth 2.0 Protected Resource Metadata (path-specific form)
66// For a resource at /api/mcp, the well-known URI is /.well-known/oauth-protected-resource/api/mcp.
7- // @note : we do not gate on entitlements here. That is handled in the /register,
8- // /token, and /revoke routes.
97// @see : https://datatracker.ietf.org/doc/html/rfc9728#section-3
108const PROTECTED_RESOURCES = new Set ( [
119 'api/mcp'
1210] ) ;
1311
1412export const GET = apiHandler ( async ( _request : NextRequest , { params } : { params : Promise < { path : string [ ] } > } ) => {
13+ if ( ! hasEntitlement ( 'oauth' ) ) {
14+ return Response . json (
15+ { error : 'not_found' , error_description : 'OAuth protected resource metadata is not available on this plan.' } ,
16+ { status : 404 }
17+ ) ;
18+ }
19+
1520 const { path } = await params ;
1621 const resourcePath = path . join ( '/' ) ;
1722
Original file line number Diff line number Diff line change 11import { apiHandler } from '@/lib/apiHandler' ;
2- import { env } from '@sourcebot/shared' ;
2+ import { env , hasEntitlement } from '@sourcebot/shared' ;
33
44// RFC 9728: OAuth 2.0 Protected Resource Metadata
55// Tells OAuth clients which authorization server protects this resource.
66// @see : https://datatracker.ietf.org/doc/html/rfc9728
77export const GET = apiHandler ( async ( ) => {
8+ if ( ! hasEntitlement ( 'oauth' ) ) {
9+ return Response . json (
10+ { error : 'not_found' , error_description : 'OAuth protected resource metadata is not available on this plan.' } ,
11+ { status : 404 }
12+ ) ;
13+ }
14+
815 const issuer = env . AUTH_URL . replace ( / \/ $ / , '' ) ;
916
1017 return Response . json ( {
Original file line number Diff line number Diff line change @@ -9,7 +9,7 @@ import { StatusCodes } from 'http-status-codes';
99import { NextRequest } from 'next/server' ;
1010import { sew } from '@/actions' ;
1111import { apiHandler } from '@/lib/apiHandler' ;
12- import { env } from '@sourcebot/shared' ;
12+ import { env , hasEntitlement } from '@sourcebot/shared' ;
1313
1414// On 401, tell MCP clients where to find the OAuth protected resource metadata (RFC 9728)
1515// so they can discover the authorization server and initiate the authorization code flow.
@@ -18,7 +18,7 @@ import { env } from '@sourcebot/shared';
1818// @see : https://datatracker.ietf.org/doc/html/rfc9728
1919function mcpErrorResponse ( error : ServiceError ) : Response {
2020 const response = serviceErrorResponse ( error ) ;
21- if ( error . statusCode === StatusCodes . UNAUTHORIZED ) {
21+ if ( error . statusCode === StatusCodes . UNAUTHORIZED && hasEntitlement ( 'oauth' ) ) {
2222 const issuer = env . AUTH_URL . replace ( / \/ $ / , '' ) ;
2323 response . headers . set (
2424 'WWW-Authenticate' ,
You can’t perform that action at this time.
0 commit comments