중견 바이오제약 회사의 한 품질 엔지니어가 QMS(품질관리시스템)에 연동된 새로운 MCP 기반 AI 어시스턴트를 테스트하고 있었습니다. 이 어시스턴트는 자연어 질의만으로 일탈(deviation)을 조회하고, CAPA를 검색하며, 배치 기록(batch record)을 불러올 수 있었습니다. 그런데 정기 감사 중 컴플라이언스 팀이 단순하지만 핵심적인 질문 하나를 던졌습니다. “AI가 QMS를 호출할 때 누구의 자격 증명(credentials)을 사용하는가?”

아무도 답하지 못했습니다. MCP 서버가 공유 서비스 계정과 정적 API 키로 배포되어 있었기 때문입니다. QA 부서의 제인(Jane)이 일탈을 조회하든, CI/CD 파이프라인이 유효성 검증을 실행하든, 로그에 기록된 모든 도구 호출(tool call)은 완전히 동일해 보였습니다. 귀속성(attributability, 작업 주체 식별 가능성)은 제로였습니다. 해당 시스템은 그날 오후 즉시 프로덕션 환경에서 퇴출되었습니다.

이는 가상의 시나리오가 아닙니다. 현재 프로덕션 환경에 배포된 MCP 서버 중 41%는 인증이 전혀 적용되어 있지 않습니다. 프로토콜 자체는 강력하지만, 보안 완성도는 철저히 구현 방식에 좌우됩니다. 로컬 프로토타입을 넘어선 실무 환경에 MCP를 배포하려 한다면, 프로토콜 수준에서 인증(Authentication)과 인가(Authorization)가 실제로 어떻게 동작하는지 파악하는 것이 규정을 준수하는 시스템과 감사 적발(audit finding) 사이의 결정적 차이를 만듭니다.

핵심 설계: 두 가지 트랜스포트, 두 가지 보안 모델

MCP는 두 가지 트랜스포트 메커니즘을 지원하며, 각각의 인증 전략은 완전히 다릅니다.

stdio (로컬 트랜스포트)

MCP 클라이언트가 stdio를 통해 로컬 서버를 생성(spawn)할 때는 네트워크 인증이 발생하지 않습니다. 서버는 호스트 사용자의 OS 권한 아래에서 자식 프로세스로 실행됩니다. 통신은 stdin/stdout 파이프를 통해 이루어지므로, 네트워크 노출도, 베어러 토큰(Bearer token)도, OAuth 흐름도 없습니다. 다운스트림 서비스를 위한 비밀 정보(데이터베이스 비밀번호, API 키 등)는 시작 시 환경 변수를 통해 주입됩니다.

이 모델은 데스크톱 도구와 로컬 개발 환경에 적합합니다. 하지만 원격 서버, 멀티테넌트 배포, 또는 귀속성(attributability)이 중요한 환경에서는 작동하지 않습니다.

Streamable HTTP (원격 트랜스포트)

모든 인증의 복잡성은 바로 여기서 발생합니다. 기존의 SSE 트랜스포트는 2025년 3월 사양 개정(2025-03-26)에서 사용 중단(deprecated)되었고, 2026년 4월 1일에 수명 종료(end-of-life)되었으며, 2026년 7월 개정판에서는 마지막 남았던 GET 스트림 엔드포인트마저 제거되었습니다. 이제 Streamable HTTP가 유일한 표준 원격 트랜스포트이며, 여기에는 OAuth 2.1 인가 프레임워크가 필수로 적용됩니다.

가장 중요한 아키텍처적 결정은 MCP 서버는 오직 OAuth 2.1 리소스 서버(Resource Server)일 뿐이라는 점입니다. MCP 서버는 토큰을 검증(validate)하기만 합니다. 토큰을 발급하거나, 사용자 로그인을 관리하거나, 인가 서버(Authorization Server) 역할을 수행하지 않습니다. 그러한 책임은 전적으로 외부 아이덴티티 공급자(Identity Provider, IdP)에 있습니다.

4가지 역할

MCP 인증 모델은 표준 OAuth 2.1 역할과 깔끔하게 매핑됩니다.

OAuth 역할 MCP 대응 요소 책임
리소스 소유자 (Resource Owner) 최종 사용자 (End User) 서버가 노출하는 데이터/액션의 소유권 보유
클라이언트 (Client) MCP 클라이언트 (Claude, VS Code, 커스텀 에이전트) 사용자를 대신하여 접근 요청
리소스 서버 (Resource Server) MCP 서버 도구/리소스 호스팅 및 토큰 검증
인가 서버 (Authorization Server) 외부 IdP (Keycloak, Okta, Entra ID) 사용자 인증 및 토큰 발급

이러한 역할 분리는 선택 사항이 아닙니다. MCP 서버가 자체 인가 서버 역할까지 겸하는 패턴은 2025년 6월 사양 개정에서 명시적으로 사용 중단되었습니다. MCP 서버는 검증하고, IdP는 발급합니다.

탐색 흐름

토큰이 교환되기 전에, MCP 클라이언트는 어디에서 인증을 받아야 하는지 먼저 탐색해야 합니다. 명세서는 2단계 탐색 프로세스를 의무화하고 있습니다.

1단계: 보호된 리소스 메타데이터 (RFC 9728)

인증되지 않은 클라이언트가 MCP 서버를 호출하면, 서버는 401 상태 코드와 함께 메타데이터 문서를 가리키는 헤더로 응답합니다.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"

메타데이터 문서는 MCP 서버가 신뢰하는 인가 서버가 무엇인지 클라이언트에게 알려줍니다.

{
  "resource": "https://mcp.example.com",
  "authorization_servers": ["https://idp.example.com"],
  "scopes_supported": ["mcp:read", "mcp:write"],
  "bearer_methods_supported": ["header"]
}

이는 필수 구현 사항입니다. MCP 서버는 이를 반드시 구현해야 하며, MCP 클라이언트는 이를 반드시 사용해야 합니다. /authorize 및 /token과 같은 기본 엔드포인트로 폴백(fallback)하던 이전 방식은 완전히 제거되었습니다.

2단계: 인가 서버 메타데이터 (RFC 8414)

클라이언트는 인가 서버를 선택하고 해당 인가 서버의 설정을 가져옵니다.

GET /.well-known/oauth-authorization-server

이 요청은 실제 OAuth 엔드포인트들(인가 엔드포인트, 토큰 엔드포인트, 등록 엔드포인트, JWKS URI, 지원되는 스코프 목록, PKCE 방식)을 반환합니다.

인가 흐름

엔드포인트를 확보한 클라이언트는 몇 가지 MCP 고유 요구사항이 포함된 표준 OAuth 2.1 인가 코드 흐름(Authorization Code flow)을 실행합니다.

모든 클라이언트에 PKCE가 필수입니다. 대부분의 MCP 클라이언트는 클라이언트 시크릿(client secret)을 안전하게 보관할 수 없는 퍼블릭 애플리케이션(데스크톱 앱, CLI 도구 등)이므로, S256을 사용하는 PKCE가 선택이 아닌 필수로 요구됩니다.

리소스 지시자(Resource Indicators, RFC 8707)가 필수입니다. 인가 요청의 resource 파라미터는 반드시 MCP 서버의 URL이어야 합니다. 인가 서버는 토큰을 해당 대상자(audience)에 바인딩해야 하며, MCP 서버는 올바른 대상자 바인딩이 누락된 토큰을 반드시 거부해야 합니다.

이 제어 장치는 여러 MCP 서버 간의 토큰 재전송(replay) 공격을 방지합니다. 서로 다른 MCP 서버 표면과 통신하는 5개의 서브에이전트가 있을 때, 리소스 지시자는 QMS 서버용으로 발급된 토큰이 LIMS 서버에 재사용되지 않도록 보장합니다.

발급자 검증(Issuer validation, RFC 9207)이 필수로 요구됩니다. 인가 서버는 인가 응답에 iss 파라미터를 반환하며, 클라이언트는 코드를 교환하기 전에 이를 반드시 검증해야 합니다. 이는 클라이언트가 여러 인가 서버와 상호작용할 때 발생하는 믹스업 공격(mix-up attacks)을 방지합니다.

전체 흐름은 다음과 같습니다.

Client → MCP Server: POST /mcp (no token)
MCP Server → Client: 401 + WWW-Authenticate (metadata URL)
Client → Auth Server: Discovery + Registration
Client → Auth Server: /authorize + PKCE + resource indicator
User → Auth Server: Login + consent
Auth Server → Client: Authorization code
Client → Auth Server: /token (code + code_verifier)
Auth Server → Client: Access token + refresh token
Client → MCP Server: POST /mcp + Authorization: Bearer <token>
MCP Server: Validate signature, issuer, audience, expiry, scopes
MCP Server → Client: 200 + response

클라이언트 등록: DCR 문제

OAuth 흐름이 시작되기 전에 클라이언트에는 client_id가 필요합니다. MCP 명세서는 다음과 같은 우선순위 계층을 정의합니다.

클라이언트 ID 메타데이터 문서(Client ID Metadata Documents, CIMD) — 2026년 7월 기준으로 권장되는 방식입니다. 클라이언트는 자신이 제어하는 URL에 메타데이터 문서를 호스팅합니다. 인가 서버는 이 문서를 가져와 클라이언트에 대한 정보를 파악합니다. 사전 등록이 필요 없으면서도 검증 가능한 신원을 제공합니다.

동적 클라이언트 등록(Dynamic Client Registration, DCR, RFC 7591) — 현재 공식적으로 사용 중단되었습니다. 클라이언트가 런타임에 등록 엔드포인트로 POST 요청을 보냅니다. 초기 사양에서는 주된 메커니즘이었으나, 심각한 보안 문제로 인해 사용이 중단되었습니다. 2026년 5월 테스트 가능한 119개의 OAuth 활성화 MCP 서버를 조사한 결과, 96.6%에서 DCR 취약점이 발견되었습니다. 테스트된 모든 서버에서 최소 하나 이상의 취약점이 확인되었습니다.

사전 등록된 정적 클라이언트 ID(Pre-registered static client IDs) — 통제된 환경에서 가장 단순한 접근 방식입니다. 클라이언트와 인가 서버를 모두 제어할 수 있으므로 사전에 등록해 둘 수 있습니다.

수동 입력(Manual entry) — 사용자가 UI를 통해 client_id를 직접 입력합니다. 특수한 엣지 케이스에 적합합니다.

핵심 규칙: 여러 MCP 클라이언트가 동일한 OAuth client_id를 공유해서는 안 됩니다. 공유할 경우 인가 서버가 클라이언트를 서로 구분할 수 없게 되며, 스코프 캐싱으로 인해 클라이언트 간에 데이터가 유출될 위험이 있습니다.

토큰 검증

MCP 서버가 Bearer 토큰이 포함된 요청을 수신하면, 최소한 다음 사항들을 검증해야 합니다.

검증 항목 검증 내용
서명 (Signature) 토큰이 신뢰할 수 있는 발급자에 의해 실제로 발급되었는지 확인
발급자 (iss) 기대하는 IdP와 일치하는지 확인
대상자 (aud / resource) 토큰이 ‘해당’ MCP 서버용으로 발급되었는지 확인
만료일 (exp) 토큰이 만료되지 않았는지 확인
유효 시작일 (nbf) 토큰의 유효 기간이 이미 시작되었는지 확인
스코프 (Scopes) 토큰에 필요한 권한이 포함되어 있는지 확인

가장 권장되는 방식은 상태 비저장(stateless) JWT 검증입니다. MCP 서버가 IdP의 JWKS(공개키 모음)를 다운로드하여 로컬에서 직접 서명을 검증합니다. 요청마다 인가 서버를 호출할 필요가 없으며, 인트로스펙션 지연 시간도 없어 완전한 확장성(scalability)을 확보할 수 있습니다.

불투명 토큰(opaque token)을 사용하거나 즉각적인 토큰 무효화(active revocation)가 필요한 환경의 경우, 인가 서버에 대한 토큰 인트로스펙션(token introspection)이 대안이 됩니다. 지연 시간은 증가하지만 자격 증명을 즉각 취소할 수 있습니다.

2026년 7월 변경 사항

2026-07-28 사양 개정은 지금까지의 MCP 인가 요구사항 중 가장 중대한 강화 조치였습니다. 주요 변경 사항은 다음 6가지입니다.

  1. 발급자 검증 (RFC 9207) — 멀티 서버 배포 환경에서 인가 서버 믹스업 공격을 방지합니다.

  2. 애플리케이션 유형 선언 — 클라이언트는 등록 시 web인지 native인지를 선언해야 합니다. 이를 통해 데스크톱 앱에서 인가 서버가 localhost 리디렉션을 거부하던 오랜 문제가 해결되었습니다.

  3. 발급자에 자격 증명 바인딩 — 클라이언트 자격 증명을 다른 인가 서버에서 재사용할 수 없도록 하여, AS 간 토큰 재전송(cross-AS token replay)을 방지합니다.

  4. 오프라인 접근 스코프 — offline_access 스코프를 통해 리프레시 토큰 요청 방식을 표준화했습니다.

  5. 단계적 스코프 확장 (Scope step-up) — 권한 요구사항이 점진적으로 증가할 때 클라이언트가 이를 처리하는 방식을 공식화했습니다. 특정 도구가 추가 스코프를 요구할 때, 서버는 필요한 항목을 알리고 클라이언트는 기존 스코프와 신규 스코프의 합집합을 요청합니다.

  6. 무상태 트랜스포트 — 트랜스포트 계층에서 프로토콜 세션이 제거되었습니다. 기존의 initialize/Mcp-Session-Id 모델은 사라졌습니다. 이제 요청은 독립적으로 라우팅될 수 있습니다. 게이트웨이는 HTTP 헤더인 Mcp-Method 및 Mcp-Name을 라우팅과 인가 결정에 활용할 수 있습니다.

또한 동적 클라이언트 등록(DCR)은 CIMD를 권장하며 공식적으로 사용 중단되었고, 엔터프라이즈 관리형 인가(EMA)는 공식 확장 규격으로 승격되었습니다.

엔터프라이즈 관리형 인가

서버마다 일일이 동의 화면을 띄우는 것이 비실용적인 엔터프라이즈 배포 환경을 위해, MCP 명세서는 이제 EMA(Enterprise-Managed Authorization) 확장을 지원합니다. 이는 2026년에 추가된 가장 중요한 엔터프라이즈 기능입니다.

문제점: EMA가 없으면 모든 MCP 서버마다 각자의 OAuth 동의 흐름이 필요합니다. QMS, LIMS, ELN, ERP, 문서 관리 등 수십 개의 MCP 서버를 운영하는 기업에서는 사용자가 동의 화면 피로도(consent-screen fatigue)를 겪게 되며, 관리자가 사용자의 서버 접근을 중앙에서 제어하기 어렵습니다.

EMA 동작 원리:

  1. 엔터프라이즈 아이덴티티 공급자(IdP)가 정책을 총괄합니다: 어떤 MCP 클라이언트가 어떤 사용자를 대신하여 어떤 MCP 서버에 접근할 수 있는지 결정합니다.
  2. IdP는 관리자 정책에 따라 서명된 아이덴티티 어설션 JWT 인가 권한(Identity Assertion JWT Authorization Grant, ID-JAG)을 발급합니다.
  3. MCP 서버의 인가 서버는 해당 어설션을 검증하고 스코프가 지정된 액세스 토큰을 발급합니다.
  4. 사용자별 동의 화면은 표시되지 않습니다. 접근 권한은 엔터프라이즈 정책에 의해 관리됩니다.

ID-JAG 클레임 포함 항목:

  • iss — 아이덴티티 공급자 발급자 URL
  • sub — 사용자 주체(principal) 식별자
  • aud — 대상 MCP 서버 식별자
  • groups — 보안 그룹 멤버십
  • roles — 할당된 역할
  • exp — 만료 시간

2026년 중반 기준으로 EMA는 Anthropic(Claude, Claude Code, Cowork), Microsoft(VS Code), Okta뿐만 아니라 Asana, Atlassian, Figma, Slack, Supabase 등 주요 서버 배포사들에 의해 지원되고 있습니다.

규제 대상인 생명과학 환경에서 EMA를 도입하면, 관리자는 “QA 팀원은 MCP-QMS, MCP-LIMS, MCP-ELN에 접근할 수 있다”는 단일 IdP 정책을 설정할 수 있습니다. 각 사용자가 모든 서버마다 일일이 ’허용(Allow)’을 클릭할 필요가 없어집니다.

신원 전파: 가장 까다로운 과제

인증(Authentication)은 MCP 서버에 누가 호출하고 있는지를 알려줍니다. 하지만 실제 배포 환경에서 MCP 서버는 권한 상승(privilege escalation) 없이 해당 신원을 내부 사용자 컨텍스트로 변환해야 합니다.

원칙: MCP 서버는 결코 권한이 승격된 서비스 계정으로 동작해서는 안 됩니다. 토큰에서 sub 클레임을 추출하고, 내부 사용자를 조회한 후, 해당 사용자의 권한으로 비즈니스 로직을 실행해야 합니다.

동일 프로세스(co-located) 모드에서는 OrderService.create_order(userContext)와 같은 직접 호출이 이루어집니다. 마이크로서비스 모드에서는 사용자 ID나 토큰이 다운스트림으로 전달되며, 각 다운스트림 서비스는 사람이 UI에서 버튼을 클릭했을 때와 완전히 동일한 권한 검사를 수행합니다.

대리인 혼동 문제(The confused deputy problem): MCP 서버가 업스트림 서비스(CRM, 데이터베이스, 외부 API 등)를 호출해야 할 때, MCP 클라이언트로부터 받은 토큰을 그대로 전달(forward)해서는 안 됩니다. 해당 토큰은 업스트림 서비스가 아니라 MCP 서버를 대상자(audience)로 하여 발급된 것이기 때문입니다. 이를 그대로 전달하면, 업스트림 서비스가 자신을 위해 발급되지 않은 토큰을 신뢰하게 되는 대리인 혼동 취약점이 발생합니다.

올바른 패턴: MCP 서버는 토큰 교환(Token Exchange, RFC 8693)을 사용하여 다운스트림 리소스에 맞게 스코프가 지정된 자체 토큰을 획득하거나, 명시적인 사용자 컨텍스트 전파와 함께 자체 서비스 자격 증명을 사용해야 합니다.

머신 대 머신(M2M) 인증

모든 MCP 클라이언트가 사람인 것은 아닙니다. 스케줄링된 에이전트, CI/CD 파이프라인, 백그라운드 검증 작업, 모니터링 에이전트는 모두 대화형 사용자 로그인 없이 MCP 서버를 호출해야 합니다.

MCP 명세서는 이러한 시나리오를 위해 OAuth 클라이언트 자격 증명 흐름(Client Credentials flow)을 지원합니다. 이때 주체(principal)는 사람이 아니라 서비스 신원(service identity)입니다. Keycloak은 실험적 기능으로 토큰 교환 위임(token exchange delegation)을 도입하여, 서브에이전트가 공유 서비스 계정 대신 위임된 사용자 신원으로 동작할 수 있도록 지원하기 시작했습니다. 이는 감사 귀속성(audit attributability) 측면에서 훨씬 우수합니다.

M2M 시나리오에서 가장 본질적인 질문은 바로 **“주체(principal)가 누구인가?”**입니다. 사람 중심의 OAuth에서는 Jane → Agent → MCP Server의 흐름을 추적할 수 있습니다. 반면 M2M에서는 주체가 서비스 신원이 됩니다. 이 차이는 규제 대상 환경의 감사 추적(audit trail)에서 막대한 영향을 미칩니다.

도구 수준 인가: 명세서가 다루지 않는 부분

가장 중요한 한계점은 다음과 같습니다. MCP 명세서는 도구 수준(tool-level)의 접근 제어를 정의하지 않습니다. 사용자가 MCP 서버에 연결하도록 인증 및 인가되었다면, 해당 사용자는 서버가 노출하는 모든 도구를 호출할 수 있습니다.

프로토콜 수준에서는 다음에 대한 메커니즘을 전혀 제공하지 않습니다:

  • 역할 기반 도구 권한 (Role-based tool permissions)
  • 리소스 수준 ACL (Resource-level ACLs)
  • 도구별 스코프 요구사항 (Per-tool scope requirements)
  • 파라미터 수준 인가 (Parameter-level authorization)

이는 이해 부족으로 인한 공백이 아니라 명세서 자체의 공백입니다. 구현자는 각 도구를 실행하기 전에 JWT 클레임(역할, 그룹, 스코프)을 활용하여 접근을 차단하는 도구 수준 인가 로직을 서버 애플리케이션 코드에 직접 구축해야 합니다.

규제 대상 환경을 위해 권장되는 패턴은 사용자뿐만 아니라 여러 요소를 함께 고려하는 정책 계층을 정의하는 것입니다.

Subject:       Who is the user?
Agent:         Which AI agent is making the request?
Tool:          What operation is being requested?
Resource:      Which specific record (CAPA, batch, deviation)?
Action:        Read, create, modify, approve, release?
Context:       Production? GxP? Business hours? Human approval required?

GxP 환경에서는 단순한 ALLOW/DENY만으로는 불충분합니다. 정책 결정 범위에는 REQUIRE_HUMAN(사람 개입 필수), REQUIRE_SECOND_APPROVER(2차 승인자 필수), REQUIRE_ELECTRONIC_SIGNATURE(전자 서명 필수) 등이 포함되어야 합니다.

7계층 방어 모델

규제 대상 배포 환경에서 MCP 인증은 심층 방어(defense-in-depth) 아키텍처의 한 계층이어야 합니다.

┌──────────────────────────────────────┐
│ Layer 1: Network                     │
│ TLS, mTLS, private networking, WAF   │
├──────────────────────────────────────┤
│ Layer 2: MCP Authentication          │
│ OAuth 2.1, OIDC, JWT validation      │
├──────────────────────────────────────┤
│ Layer 3: Identity                    │
│ Human, agent, service, tenant        │
├──────────────────────────────────────┤
│ Layer 4: RBAC                        │
│ Role-to-tool mapping                 │
├──────────────────────────────────────┤
│ Layer 5: ABAC                        │
│ Department, environment, risk level  │
├──────────────────────────────────────┤
│ Layer 6: Tool Authorization          │
│ READ=auto, APPROVE=HITL, RELEASE=HITL│
├──────────────────────────────────────┤
│ Layer 7: Audit                       │
│ Who, what, when, agent, tool, params,│
│ policy decision, result              │
└──────────────────────────────────────┘

모든 계층은 독립적으로 거부(no)를 선언할 수 있어야 합니다.

인가는 최소한 두 번 이루어져야 합니다. 에이전트 하네스(Agent harness)는 에이전트 전용 정책(해당 에이전트가 어떤 도구를 호출할 수 있는지)을 강제하고, MCP 서버는 리소스 수준의 보안(어떤 사용자가 어떤 데이터에 접근할 수 있는지)을 강제합니다. 심층 방어가 구축되어 있다면, 프롬프트 인젝션(prompt injection)으로 에이전트를 속이더라도 두 계층 모두를 우회할 수는 없습니다.

결론

MCP 인증은 필수 PKCE, 대상자 바인딩을 위한 리소스 지시자, 그리고 리소스 서버와 인가 서버 간의 명확한 역할 분리가 적용된 OAuth 2.1입니다. 2026년 7월 개정판에서는 발급자 검증, 자격 증명 바인딩, 단계적 스코프 확장, CIMD 도입에 따른 동적 클라이언트 등록(DCR) 중단 등 사양이 대폭 강화되었습니다.

하지만 인증은 문제의 절반에 불과합니다. 어떤 사용자가 어떤 파라미터로 어떤 도구를 호출할 수 있는지를 통제하는 인가(Authorization)는 여전히 프로토콜 외부에 남아 있습니다. 규제 대상 환경에서는 주체, 에이전트, 도구, 리소스, 작업, 컨텍스트를 종합적으로 고려하는 정책 엔진으로 이 공백을 반드시 메워야 합니다.

프로토콜은 신원 전송을 위한 표준화된 수단을 제공할 뿐입니다. 도구 수준의 RBAC, 직무 분리(segregation of duties), 전자 서명, 불변의 감사 추적(immutable audit trails) 등 그 밖의 모든 것은 엔지니어가 직접 구축해야 할 아키텍처의 영역입니다. MCP는 건물이 아니라 기초 토대일 뿐입니다.


연구 노트: [[MCP Authentication and Authorization - Comprehensive Report]]

관련 글