OAuth2 내부 처리 흐름
Custom MCP 서버에 OAuth2 인증을 연동할 때, AIP 내부에서 이루어지는 처리 과정을 상세하게 설명합니다. OAuth2 인증 및 DCR 가이드의 사용자 관점 설명을 보완하는 기술 상세 문서입니다.
이 문서의 활용
OAuth2 인증 및 DCR 가이드는 “어떻게 연동하는가”에 집중합니다. 대부분의 경우 그것만으로 충분하지만, 다음과 같은 상황에서는 AIP 내부의 처리 흐름을 이해해야 합니다.
연동 실패 진단 — OAuth 팝업이 표시되지 않거나 인증이 실패할 때, 내부 흐름을 알면 Discovery, Token Exchange, 토큰 갱신 중 어느 단계에서 문제가 발생했는지 정확하게 진단할 수 있습니다. 예를 들어, OAuth 팝업이 아예 뜨지 않는다면 Discovery 단계의 실패이고, 팝업은 떴지만 로그인 후 에러가 발생한다면 Token Exchange 단계의 문제입니다.
보안 검토 및 감사 대응 — 기업 보안팀이 OAuth 구현의 안전성을 검토할 때 필요한 정보를 제공합니다. “Authorization Code가 가로채기당하면 어떻게 되는가?”라는 질문에 대해, AIP가 PKCE (Proof Key for Code Exchange)를 자동 적용하여 코드 가로채기 공격을 방지한다는 사실을 이 문서를 근거로 설명할 수 있습니다. State 토큰을 통한 CSRF 방지, Client Secret의 서버 측 관리, TLS를 통한 통신 암호화 등 보안 메커니즘의 상세를 확인할 수 있습니다.
MCP 서버 개발자의 구현 판단 — MCP 서버 개발자가 Authorization Server를 구현할 때, AIP가 실제로 어떤 요청을 보내고 어떤 응답을 기대하는지 알아야 합니다. 예를 들어, ASM에 code_challenge_methods_supported를 포함할지 여부, Token Endpoint에서 code_verifier를 어떻게 검증할지, DCR 등록 요청의 형식과 필수 필드는 무엇인지 등을 판단하는 데 이 문서가 참고가 됩니다. PKCE를 지원하지 않으면 AIP는 PKCE 없이 진행하지만, 지원하면 보안이 강화되므로 구현을 권장합니다.
토큰 생명주기 이해 — Access Token 만료, Refresh Token 갱신, Client Secret 변경 등 운영 중 발생하는 토큰 관련 이슈를 이해하고 대응하는 데 필요한 정보를 제공합니다. AIP가 Refresh Token을 사용하여 자동으로 Access Token을 갱신하는 흐름, Refresh Token 자체가 만료되었을 때의 재인증 절차, Client Secret이 변경되었을 때의 재설정 방법 등을 다룹니다.
전체 흐름 개요
MCP Server URL을 입력하면 AIP는 다음 순서로 처리합니다:
- 메타데이터 조회 — OAuth Discovery를 통해 인증 방식을 판정합니다.
- 클라이언트 등록 또는 수동 입력 — DCR 지원 여부에 따라 자동 등록하거나 사용자에게 Client ID/Secret을 요청합니다.
- Authorization URL 생성 — PKCE를 포함한 Authorization Code Flow를 시작합니다.
- OAuth 팝업 — 사용자가 서비스에 로그인합니다.
- 콜백 처리 및 토큰 교환 — Authorization Code를 Access Token으로 교환합니다.
- 토큰 저장 — 사용자별로 토큰을 저장하고 연동을 완료합니다.
1단계: OAuth Discovery 및 인증 방식 판정
메타데이터 조회 순서
MCP Server URL이 입력되면 AIP 백엔드가 다음 순서로 메타데이터를 조회합니다:
Protected Resource Metadata (PRM) 조회
MCP 서버에 POST 요청을 보내 인증 여부를 확인합니다.
- 401 응답 +
WWW-Authenticate헤더: 헤더에서resource_metadataURL을 추출하여 PRM을 가져옵니다. - 401이 아닌 응답:
/.well-known/oauth-protected-resource엔드포인트로 직접 조회합니다.
PRM에서 authorization_servers 필드를 추출하여 Authorization Server의 위치를 확인합니다.
Authorization Server Metadata (ASM) 조회
PRM에서 얻은 Authorization Server URL을 기반으로 ASM을 조회합니다. 다음 경로를 우선순위 순으로 시도합니다:
- RFC 8414:
/.well-known/oauth-authorization-server/{path} - OIDC (path insertion):
/.well-known/openid-configuration/{path} - OIDC (path appending):
/{path}/.well-known/openid-configuration
ASM 응답에는 authorization_endpoint, token_endpoint, scopes_supported, registration_endpoint(선택) 등이 포함됩니다.
인증 방식 판정
ASM 조회 결과에 따라 인증 방식을 결정합니다:
| 조건 | 판정 결과 |
|---|---|
| ASM 조회 실패 | NoAuth — OAuth 흐름을 시작하지 않음 |
ASM에 registration_endpoint 있음 | OAuthWithDCR — 자동 클라이언트 등록 |
ASM에 registration_endpoint 없음 | OAuth — 수동 Client ID/Secret 입력 |
ASM의 issuer 필드는 RFC 8414에 따라 검증되며, 일부 서비스(예: Slack)에서 서브도메인이 다른 경우에도 호환성을 위해 fallback 처리됩니다.
Discovery 실행 시점
OAuth Discovery(PRM → ASM 조회)는 두 번 실행됩니다:
- MCP Server URL 입력 시 — 인증 방식(NoAuth / OAuthWithDCR / OAuth)을 판정하기 위해 실행됩니다. 이 결과에 따라 사용자에게 표시할 UI(자동 진행 / Client ID·Secret 입력 다이얼로그 / OAuth 없이 계속 진행)가 결정됩니다.
- Client ID/Secret 제출 시 (또는 DCR 등록 시) — Authorization URL을 생성하기 위해 다시 실행됩니다. 이때 ASM에서
authorization_endpoint,token_endpoint,scopes_supported등 최신 값을 가져와 인가 요청에 사용합니다.
두 번째 실행은 첫 번째 조회와 실제 인가 요청 사이에 시간 차가 발생할 수 있으므로, 최신 메타데이터를 사용하기 위한 것입니다.
2단계: 클라이언트 등록 또는 수동 입력
OAuthWithDCR인 경우 (자동 등록)
AIP가 ASM의 registration_endpoint에 RFC 7591 형식으로 클라이언트 등록 요청을 보냅니다:
POST {registration_endpoint}
Content-Type: application/json
{
"client_name": "Custom MCP Client of AI Platform",
"redirect_uris": ["https://{aip-domain}/integration/oauth/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"scope": "read write",
"token_endpoint_auth_method": "client_secret_basic"
}성공 시 client_id와 client_secret을 자동으로 획득하고 3단계로 진행합니다.
DCR 등록이 실패하면 AIP는 자동으로 수동 입력 방식으로 fallback합니다. 사용자에게 Client ID/Secret 입력 다이얼로그가 표시됩니다.
OAuth인 경우 (수동 입력)
사용자에게 Client ID/Secret 입력 다이얼로그를 표시합니다. 다이얼로그에는 다음 정보가 포함됩니다:
- MCP Server URL — 연동 대상 서버 주소
- OAuth Callback URL — 사용자가 외부 서비스의 OAuth App에 등록해야 하는 Redirect URI (복사 버튼 제공)
- 필요 Scope 목록 — ASM의
scopes_supported에서 가져온 권한 목록 - Client ID / Client Secret 입력 필드
사용자는 외부 서비스에서 OAuth App을 생성하고 Callback URL을 등록한 뒤, 발급받은 Client ID와 Secret을 입력합니다.
인증 실패 시 에러 메시지와 함께 다이얼로그가 다시 표시되며, 이전에 입력한 값이 자동으로 채워져 재시도가 편리합니다.
3단계: Authorization URL 생성
Client ID/Secret이 확보되면 (DCR 자동 발급 또는 수동 입력), AIP 백엔드가 Authorization URL을 생성합니다.
PKCE (Proof Key for Code Exchange)
ASM의 code_challenge_methods_supported에 S256이 포함된 경우, AIP는 자동으로 PKCE를 적용합니다:
- Code Verifier 생성 — 암호학적으로 안전한 랜덤 문자열
- Code Challenge 생성 —
BASE64URL(SHA256(code_verifier)) - Code Verifier는 서버 측에 저장하고, Code Challenge만 Authorization URL에 포함
MCP 서버 개발자는 Authorization Server Metadata에 code_challenge_methods_supported: ["S256"]을 포함할 것을 강력히 권장합니다. 이 필드가 없으면 AIP는 PKCE 없이 처리를 진행하지만, Authorization Code 가로채기 공격을 방지하기 위해 PKCE 구현을 강력히 권장합니다.
State 토큰
CSRF 공격 방지를 위해 1회용 State 토큰을 생성합니다. State 토큰은 암호학적으로 안전한 랜덤 값이며, 인증 처리에 필요한 세션 정보는 AIP 서버 측에서만 관리됩니다. 토큰은 약 10분간 유효하며, 콜백에서 1회 소비되면 즉시 삭제됩니다.
Authorization URL 파라미터
최종 생성되는 Authorization URL에는 다음 파라미터가 포함됩니다:
| 파라미터 | 설명 |
|---|---|
client_id | DCR 발급 또는 수동 입력된 Client ID |
redirect_uri | AIP의 OAuth 콜백 URL |
response_type | code (Authorization Code Flow) |
state | 1회용 CSRF 방지 토큰 |
code_challenge | PKCE Challenge (지원 시) |
code_challenge_method | S256 (지원 시) |
scope | ASM의 scopes_supported |
resource | RFC 8707 Resource Indicator (지원 시) |
4단계: OAuth 팝업
생성된 Authorization URL로 브라우저 팝업이 열리며, 사용자는 외부 서비스에 로그인합니다. 로그인 성공 시 서비스는 AIP의 콜백 URL로 code와 state를 포함하여 리다이렉트합니다.
5단계: 콜백 처리 및 토큰 교환
콜백 수신
GET /integration/oauth/callback?state={state}&code={code}AIP는 다음을 수행합니다:
State 검증
수신된 state 값으로 저장된 세션 정보를 조회합니다. State가 유효하지 않거나 만료된 경우 인증이 실패합니다.
Token Exchange
저장된 정보(Client ID, Client Secret, Code Verifier)를 사용하여 Token Endpoint에 코드 교환을 요청합니다:
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code={authorization_code}
&client_id={client_id}
&client_secret={client_secret}
&redirect_uri={callback_url}
&code_verifier={code_verifier}토큰 수신
Token Endpoint에서 다음을 응답받습니다:
| 필드 | 설명 |
|---|---|
access_token | API 호출에 사용할 액세스 토큰 |
refresh_token | 토큰 갱신에 사용할 리프레시 토큰 (선택) |
expires_in | 액세스 토큰 만료 시간 (초) |
6단계: 토큰 저장 및 연동 완료
Auth Ticket
토큰 교환이 성공하면 AIP는 Auth Ticket을 생성합니다. Auth Ticket은 1회용 임시 토큰으로, 프론트엔드에 전달되어 연동 설치를 완료하는 데 사용됩니다.
Auth Ticket에는 다음이 포함됩니다:
| 항목 | 용도 |
|---|---|
| Access Token | MCP 서버 API 호출 |
| Refresh Token | 토큰 만료 시 갱신 |
| Client ID / Client Secret | 토큰 갱신 요청 시 인증 |
| Token Endpoint | 토큰 갱신 요청 대상 URL |
사용자별 토큰 관리
토큰은 사용자별로 독립적으로 저장됩니다. 같은 MCP 서버에 대해 여러 사용자가 각각 인증하면, 각 사용자는 자신만의 토큰을 갖게 됩니다.
토큰 갱신
Access Token이 만료되면 AIP는 저장된 Refresh Token을 사용하여 자동으로 갱신합니다:
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token={refresh_token}
&client_id={client_id}
&client_secret={client_secret}갱신이 성공하면 새로운 Access Token(및 경우에 따라 새 Refresh Token)이 저장됩니다. Refresh Token이 만료되거나 폐기된 경우, 사용자는 다시 OAuth 인증을 수행해야 합니다.
보안 고려사항
PKCE (Proof Key for Code Exchange)
AIP는 Authorization Server가 PKCE를 지원하는 경우 자동으로 적용합니다. PKCE는 Authorization Code 가로채기 공격을 방지하며, MCP 스펙에서 권장하는 보안 메커니즘입니다.
- Code Verifier는 서버 측에만 저장되며, 클라이언트에 노출되지 않습니다.
- Code Challenge는 SHA-256 해시이므로 원본 Verifier를 역산할 수 없습니다.
State 토큰
- 암호학적으로 안전한 랜덤 값으로 생성됩니다.
- 약 10분간 유효하며, 1회 사용 후 즉시 삭제됩니다.
- CSRF(Cross-Site Request Forgery) 공격을 방지합니다.
Client Secret 보관
- 수동 입력된 Client Secret은 Auth Ticket에 포함되어 서버 측에서만 관리됩니다.
- 토큰 갱신 시 필요하므로 Access Token과 함께 저장됩니다.
- 모든 통신은 TLS(HTTPS) 위에서 이루어집니다.
Redirect URI 검증
외부 서비스의 OAuth App에 AIP의 콜백 URL이 정확히 등록되어 있어야 합니다. Redirect URI가 일치하지 않으면 Authorization Server가 요청을 거부합니다.
문제 해결
DCR 등록 실패 후 수동 입력 전환
DCR 등록이 실패하면 AIP는 자동으로 수동 입력 다이얼로그를 표시합니다. 주요 실패 원인:
- Authorization Server가 DCR 요청 형식을 지원하지 않는 경우
registration_endpoint가 ASM에 있지만 실제로 동작하지 않는 경우- 네트워크 오류 또는 타임아웃
Token Exchange 실패
콜백은 수신되었으나 토큰 교환이 실패하는 경우:
- Client ID/Secret이 정확한지 확인합니다.
- OAuth App의 Redirect URI가 AIP 콜백 URL과 정확히 일치하는지 확인합니다.
- Authorization Server의 토큰 엔드포인트가 정상 동작하는지 확인합니다.
토큰 갱신 실패
- Refresh Token이 만료되었거나 폐기된 경우, 사용자에게 재인증을 요청합니다.
- Client Secret이 변경된 경우, MCP 연동을 삭제하고 새로운 Client ID/Secret으로 다시 설정합니다.
State 만료
OAuth 팝업에서 로그인에 10분 이상 소요되면 State 토큰이 만료됩니다. 이 경우 다시 연동 설정을 시작해야 합니다.