인증 & 권한

apphub-mcp 는 OAuth 2.0 Bearer 토큰만 받아요. scope 3단계 (read/write/admin) 와 앱 단위 권한을 호출할 때마다 확인해요.

OAuth 토큰으로만 인증해요

개인 API 키 (PAT) 는 이제 쓸 수 없어요

예전에 쓰던 PAT 인증은 완전히 없어졌어요. MCP 엔드포인트는 OAuth 2.0 Bearer 토큰만 받아요. app-key 토큰은 읽기 전용 API tool 4개만 쓸 수 있어요 (아래에서 설명할게요).

모든 /mcp 요청에는 Authorization: Bearer <토큰> 헤더를 꼭 넣어 주세요. 토큰이 없거나 만료됐으면 WWW-Authenticate 헤더와 함께 401 Unauthorized 를 돌려줘요. JSON-RPC 에러 코드는 -32001 이에요.

401 응답 예시
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://api.jocodingax.ai/.well-known/oauth-protected-resource"
Content-Type: application/json

{"jsonrpc":"2.0","id":1,"error":{"code":-32001,"message":"인증 정보가 필요합니다"}}

토큰은 어디서 받아요?

메타데이터부터 확인해요

401 응답에 담겨오는 resource_metadata URL 을 따라가면 어떤 authorization server 에서 토큰을 받고, 어떤 scope 가 필요한지 알 수 있어요.

Terminal
$ curl https://api.jocodingax.ai/.well-known/oauth-protected-resource

응답은 RFC 9728 포맷이에요. authorization_servers, scopes_supported, resource 가 담겨 있어요.

토큰을 받아와요

메타데이터에 있는 authorization_servers 에서 client_credentialsauthorization_code 플로우로 access token 을 받아주세요. 서버는 요청이 올 때마다 토큰을 확인하고, 토큰 주인의 ID 와 scope 를 뽑아내요.

Scope 는 3단계예요

Scope뭘 할 수 있어요?예시 tool
read조회·목록·검색만list_my_apps, get_app_url, list_apis, search_table, preflight_check
write상태를 바꾸는 작업deploy_app, rollback_deploy, restart_app, env_vars, records (insert/update)
admin조직·보안까지 손댈 수 있어요import_and_deploy, set_app_spec, manage_oauth_client, connect_repo, manage_api_key

admin 이 있으면 readwrite 도 자동으로 가진 걸로 쳐요.

tool 안에서도 scope 가 달라져요

같은 tool 이라도 action 에 따라 필요한 scope 가 달라져요:

  • manage_app: updatewrite, archive/unarchive/deleteadmin
  • manage_ci: listread, rerunwrite, enable/disableadmin
  • manage_table: list/describeread, create/dropwrite
  • records: queryread, insert/update/delete/bulk_insertwrite
  • connect_repo: 모든 액션이 admin

권한은 두 단계로 확인해요

tools/call 을 부를 때마다 서버는 이 두 단계를 순서대로 돌려요.

1단계 — 전역 · scope · 인증 타입 확인

순서대로:

  1. 금지 목록 (deny list) 에 올라온 tool 이면 바로 차단해요. (관리 중인 tool 이 있을 때 쓰여요)
  2. Scope 검사 — 토큰 scope 에 해당 tool 이 요구하는 scope 가 있나 확인해요.
  3. 인증 타입 제한app-key 토큰은 딱 4개 tool 만 쓸 수 있어요:
list_apis, get_api_schema, test_api, discover_apis

2단계 — 앱 단위 OAuth 권한 확인

OAuth 토큰이면 ResolveApp(args) 로 대상 앱을 찾고, 그 앱에서 사용자가 가진 실제 권한 (canManage, scopes) 을 계산해요.

  • read 가 아닌 작업인데 앱 관리 권한이 없으면 → forbidden (endpoint_forbidden)
  • 사용자 scope 에 필요한 권한이 없으면 → forbidden (missing_scope)

세션 주인 확인

Mcp-Session-Id 헤더는 JSON-RPC 요청과 SSE 스트림 양쪽에서 검증돼요. 토큰 주인과 세션 주인이 안 맞으면 세션 ID 는 그냥 무시되고, 리소스 구독·태스크 호출은 Mcp-Session-Id 헤더가 필요합니다 로 거절해요.

에러 코드 모음

JSON-RPC 코드HTTP뭘 뜻해요?
-32001401인증이 없거나 실패 (WWW-Authenticate 도 같이 옴)
-32600400리소스 구독 때 세션 ID 가 빠짐
-32601200없는 메서드/tool 을 불렀을 때
-32602200파라미터 형식이 잘못됨
-32603200서버 내부 에러 (패닉 복구 포함)
forbidden200scope/권한 부족 — oauth_only, missing_scope, resource_scope, endpoint_forbidden 같은 세부 이유 포함