블로그
MCP

게시일 수정일

Shouryamaan 및 Anshu

MCP 인증 및 권한 부여 완벽 가이드

Markdown으로 읽기

MCP 인증은 클라이언트와 그 클라이언트가 대신하는 사용자의 신원을 확인합니다. 권한 부여는 이들이 접근할 수 있는 도구, tenant, 리소스, 작업을 결정합니다. 원격 HTTP 서버의 경우 현재 MCP 명세는 OAuth 검색, PKCE, 리소스 지시자, bearer token, 대상 검증을 사용합니다. 최종 리소스에 대한 권한은 여전히 백엔드에서 확인해야 합니다.

로컬 stdio 서버는 이 HTTP 권한 부여 흐름 대신 프로세스 환경을 사용합니다. 프로토콜의 모양을 맞추겠다는 이유만으로 원격 OAuth 설계를 stdio에 그대로 적용하지 마세요.

원격 MCP 권한 부여의 역할

MCP 권한 부여 명세는 세 가지 역할을 정의합니다.

  • MCP client는 OAuth client 역할을 합니다.
  • MCP server는 보호 대상인 resource server 역할을 합니다.
  • authorization server는 리소스 소유자를 인증하고 access token을 발급합니다.

authorization server는 같은 서비스에 포함될 수도 있고 별도의 identity 플랫폼일 수도 있습니다. 어느 쪽이든 MCP server가 토큰을 검증하고 접근 권한을 적용할 책임은 달라지지 않습니다.

검색은 보호 리소스에서 시작됩니다

클라이언트가 유효한 권한 없이 보호된 MCP server를 호출하면 서버는 401 응답과 보호 리소스 메타데이터 위치를 가리키는 WWW-Authenticate header를 반환합니다. 이 메타데이터는 어떤 authorization server가 해당 리소스용 토큰을 발급할 수 있는지 클라이언트에 알려 줍니다.

이어서 클라이언트는 OAuth authorization-server 메타데이터를 읽어 권한 부여 endpoint와 token endpoint를 찾습니다. 범용 클라이언트는 처음 보는 서버에 연결할 수 있으므로 MCP에는 보호 리소스 메타데이터와 authorization-server 메타데이터가 모두 필요합니다.

요청 대상을 MCP server로 한정하세요

클라이언트는 권한 부여 요청과 token 요청 모두에 resource parameter를 넣습니다. 이 값은 요청 대상인 MCP server를 식별합니다. MCP server는 제시된 토큰이 자신을 대상으로 발급되었는지 확인해야 합니다.

이렇게 대상을 묶어 두면 한 서비스에 발급된 토큰이 다른 서비스에서 재사용되는 것을 막을 수 있습니다. 서명이 유효하더라도 대상이 틀리면 충분하지 않습니다.

authorization code를 보호하세요

공개 MCP client는 client secret을 안전하게 보관할 수 없습니다. 따라서 명세는 PKCE로 알려진 Proof Key for Code Exchange를 요구합니다. 흐름을 시작한 클라이언트는 authorization code를 교환할 때 verifier를 가지고 있음을 증명합니다.

Redirect URI는 등록한 뒤 정확히 일치시켜야 합니다. 클라이언트는 state 값을 사용하고 검증해 callback을 자신이 시작한 요청에 연결해야 합니다. localhost 개발 redirect를 제외하면 HTTPS가 필수입니다.

토큰은 authorization header로만 보내세요

보호된 모든 HTTP 요청에는 다음 header가 포함됩니다.

Authorization: Bearer <access-token>

MCP 명세는 query string에 access token을 넣는 것을 금지합니다. URL은 header보다 브라우저 방문 기록, reverse-proxy log, analytics, screenshot, referrer 데이터에 유출되기 쉽습니다.

유효하지 않거나 만료된 토큰에는 401을 반환합니다. 신원은 유효하지만 필요한 scope나 권한이 부족하면 403을 반환합니다.

MCP 토큰을 다운스트림으로 전달하지 마세요

access token은 MCP server를 위한 것입니다. 서버는 이 토큰을 서드파티 API로 전달하면 안 됩니다. 도구가 업스트림 서비스를 호출한다면 MCP server는 별도의 OAuth client 역할을 하거나 해당 서비스용으로 발급된 별도의 백엔드 자격 증명을 가져와야 합니다.

토큰 전달은 confused deputy 문제를 만들고 대상 경계를 무너뜨립니다. 업스트림 자격 증명을 어디에 보관해야 하는지는 MCP API key 가이드에서 설명합니다.

사용자, tenant, 리소스, 작업에 권한을 부여하세요

scope는 여러 계층 중 하나일 뿐입니다. 토큰을 검증한 다음 현재 애플리케이션 상태를 기준으로 접근 권한을 계산하세요.

  1. 어떤 사용자 또는 서비스 신원을 대신하고 있는가?
  2. 어떤 tenant 또는 조직이 활성 상태인가?
  3. 요청한 리소스를 해당 tenant가 소유하는가?
  4. 이 신원의 역할에 허용된 작업인가?
  5. 현재의 승인이나 정책 판단이 필요한 작업인가?
  6. 자격 증명이 여전히 활성 상태이고 제한 범위 안에 있는가?

다운스트림 API에서도 리소스 수준의 권한을 다시 확인해야 합니다. 도구 이름이 read_invoice라고 해서 선언만으로 API 호출이 읽기 전용이 되지는 않습니다.

영향이 큰 작업의 승인은 별도로 받으세요

OAuth 동의는 특정 범주의 접근을 허용합니다. 이를 이후의 모든 삭제, 구매, 광범위한 변경에 대한 승인으로 간주해서는 안 됩니다. 결과가 큰 작업은 호출 시점에 정확한 리소스와 영향을 보여 주세요.

MCP 도구 명세는 도구 호출에 관해 사용자가 분명히 알 수 있게 하고 확인을 받도록 권장합니다. 안전한 인프라 가이드는 cloud 작업에 plan과 apply 경계를 추가합니다.

실패 사례를 테스트하세요

테스트 예상 결과
bearer token 없음 보호 리소스 메타데이터 위치와 함께 401
만료된 토큰 백엔드 실행 없이 401
다른 대상을 위한 토큰 도구 전달 전에 거부
유효한 토큰, scope 누락 403
올바른 scope, 잘못된 tenant 리소스 정보가 드러나지 않는 거부 응답
업스트림 API에 제시된 MCP 토큰 설계상 불가능
변경된 redirect URI 권한 부여 거부
재생된 파괴적 요청 한 번만 실행되거나 승인 요구

log, error tracker, trace, analytics에 access token이나 refresh token이 남는지도 확인하세요. 서버가 자격 증명을 기록한다면 검증을 올바르게 구현해도 소용이 없습니다.

토큰 하나가 멈추는 지점까지 추적하세요

인증되지 않은 첫 요청부터 시작해, 발급된 access token이 MCP server에서 검증될 때까지 따라가세요. 그런 다음 별도의 업스트림 자격 증명을 추적하세요. 같은 토큰이 두 경계를 모두 넘는다면 도구를 더 추가하기 전에 그 문제부터 고쳐야 합니다.

아래 프롬프트는 서버를 호출하지 않고도 이 추적 결과와 누락된 테스트를 만들어 줍니다.