MCP에 이제 사람 개입 없이 에이전트가 인증하는 공식 방법이 생겼다. SEP-1046은 OAuth client_credentials 그랜트를 Model Context Protocol의 공식 확장으로 추가한다. 권장 클라이언트 인증 방식은 private_key_jwt(RFC 7523 JWT 클라이언트 어설션)이고, 호환성을 위해 일반 클라이언트 시크릿도 허용된다. 2025년 10월에 승인되었고, 지난 몇 달 사이 TypeScript, Python, 그리고 최근에는 Ruby SDK까지 구현이 들어갔다. 엔터프라이즈 환경에서 에이전트를 운영한다면, SEP 번호를 알고 있었든 아니든 이것이 바로 기다리던 퍼즐 조각이다.

본론에 앞서 고백 하나: 이 글은 하마터면 쓰이지 못할 뻔했다. 에이전틱 AI 분야는 그 자체로 글쓰기가 일정 관리 문제가 될 만큼 빠르게 움직인다. SEP-1046은 다른 세 가지 일이 출시되는 동안 초안 폴더에 묵혀 있었고, Brad Webb의 엔터프라이즈 MCP 인가 패턴 정리 글이 읽기 목록에 들어와 그림이 독자의 시간을 쓸 만큼 완성된 지금에서야 시간을 냈다. 그의 글도 함께 읽기를 권한다. 이 글은 엔터프라이즈 팀에 실제로 중요한 것만 추린, 더 짧고 주관이 실린 버전이다.

GitHub 이슈 하나가 보안 계층이 되기까지

2025년 7월 24일, Darin McAdams가 MCP 명세 저장소에 issue #1046을 열었다. 이력이 중요한 대목이다. McAdams는 Amazon에서 거의 26년을 일했고 마지막 시기는 Senior Principal Software Engineer였으며, 아이덴티티 보안 회사 Defakto Security의 Architect로 옮기기 전 마지막 몇 주에 이 제안을 썼다. 제안 자체는 짧고 정확하다. 초기 MCP 인가 명세는 client credentials 플로우를 언급했지만 이후 개정에서 빠졌고, 결국 명세는 엔터프라이즈에서 가장 흔한 시나리오, 즉 대화형 동의 화면을 클릭해 줄 최종 사용자가 없는 상태에서 MCP 서버를 호출해야 하는 워크로드에 대해 침묵하게 되었다.

제안은 SEP-1046으로 승인되어 2025년 10월 30일 확정되었고, 코어 명세 변경이 아니라 MCP 확장 io.modelcontextprotocol/oauth-client-credentials로 출시되었다. 이어서 구현이 따라왔다. TypeScript SDK의 PrivateKeyJwtProvider, Python SDK의 PrivateKeyJWTOAuthProvider, 그리고 가장 최근에는 Koichi ITO(RuboCop으로 유명한 koic)가 공식 Ruby SDK에 private_key_jwt 지원을 컨포먼스 시나리오까지 갖춰 커밋했다. 제안에서 승인된 SEP로, 다시 공유 컨포먼스 스위트를 통과하는 독립 구현들로 이어지는 이 흐름이 바로 프로토콜이 성숙해 가는 모습이다. 2년 전 "MCP 인증"이란 환경 변수에 넣은 bearer 토큰과 기도가 전부였다.

client credentials가 중요한 이유: 에이전트에게는 브라우저가 없다

기본 MCP 명세가 기반으로 삼는 OAuth authorization code 플로우는 사람을 전제한다. 누군가 동의 화면을 보고, 아이덴티티 프로바이더에 인증하고, 자기 권한의 일부를 클라이언트에 위임한다. 이 모델은 Claude Desktop이 CRM에 연결하는 상황에는 맞는다. 하지만 엔터프라이즈가 실제로 배포하는 워크로드에는 맞지 않는다. 야간 대사 작업 에이전트, 내부 MCP 서버를 조회하는 CI 파이프라인, 새벽 3시에 전문 에이전트들에게 작업을 분배하는 슈퍼바이저 에이전트. 그 시간에 "허용"을 눌러 줄 사람은 아무도 깨어 있지 않다.

Client credentials는 모든 엔터프라이즈 IAM 플레이북에 있는 서비스 계정 패턴을 MCP에 적용한 것이다. 워크로드는 아이덴티티 플랫폼에 사전 등록된 자기 자신의 아이덴티티를 갖고, 자기 자신으로서 인증한다. 빌려 온 사용자 세션도, 사람 흉내를 내는 헤드리스 브라우저 자동화도, 시크릿 매니저에 임시방편으로 붙여 둔 장수 개인 액세스 토큰도 없다. 에이전트는 고유한 권한, 고유한 감사 추적, 고유한 라이프사이클을 가진 일급 주체가 된다. 보안 팀이 "에이전트가 Dave로 인증하고 있다"는 이유로 MCP 도입을 막아 왔다면, 이것이 그들에게 줄 답이다.

private_key_jwt: 올바른 기본값, 그리고 그 비용

SEP-1046은 클라이언트 인증을 의도적으로 두 가지 옵션으로 제한한다. HTTP Basic을 통한 클라이언트 시크릿은 허용되는데, 지구상의 모든 아이덴티티 프로바이더가 오늘 당장 지원하기 때문이다. 하지만 권장 방식은 private_key_jwt다. 클라이언트가 개인 키로 짧은 수명의 JWT 어설션에 서명해 시크릿 대신 제시한다. SDK 구현의 설계 세부는 읽어 볼 가치가 있다. 실제 보안 판단이 그대로 담겨 있기 때문이다.

  • 어설션은 클라이언트 ID로 설정된 isssub, 인가 서버의 issuer 식별자로 설정된 aud, 300초짜리 exp, 고유한 jti를 담는다. 탈취된 어설션은 5분이면 만료되고 재사용할 수 없다.
  • 개인 키는 클라이언트를 떠나지 않으며 토큰 스토리지에 기록되지도 않는다. 인가 서버 데이터베이스에 덤프되기를 기다리며 놓여 있는 공유 시크릿이 없다.
  • client_id는 요청 본문에서 완전히 생략되고, 아이덴티티는 서명된 어설션 안에 담겨 이동한다. 토큰 요청은 RFC 8707 resource 파라미터도 함께 보내므로, 돌아오는 토큰은 해당 issuer를 받아들이는 아무 서버가 아니라 특정 MCP 서버 하나에 바인딩된다.

비용은 키 관리다. 비대칭 키는 생성, 배포, 로테이션, 폐기가 필요한데, SEP-1046은 서버가 어설션 검증을 위해 클라이언트의 JWKS를 발견하는 방법을 의도적으로 아직 명세하지 않는다. 그 부분은 WIMSE headless JWT 작업과 IETF에서 성숙 중인 Client ID Metadata 드래프트를 기다린다. 실무에서는 대부분의 팀이 일단 클라이언트 시크릿으로 출시하고, 아이덴티티 플랫폼 툴링이 따라오면 JWT 어설션으로 이전하게 된다는 뜻이다. 그래도 괜찮다. 명세된 업그레이드 경로가 있는 상태에서 오늘 호환 가능한 옵션을 고르는 것과 경로 자체가 없는 것은 전혀 다른 일이다.

의도적 누락 하나가 이슈 스레드에서 논쟁을 불렀다. mTLS다. 여러 코멘터가 RFC 8705 클라이언트 인증서를 범위에 넣자고 했고, 반박이 그 이유를 설명한다. 실제 배포에서 TLS는 CDN이나 로드 밸런서에서 종료되는데, 이는 MCP가 실제로 동작하는 애플리케이션 계층보다 몇 홉 앞이라 인프라 곡예 없이는 서버가 클라이언트 인증서를 볼 수 없다. 내부 PKI가 제대로 돌아가는 엔터프라이즈는 자체 서비스 간에 여전히 mTLS를 쓸 수 있다. 명세는 그 전제를 모두에게 강요하기를 거부했을 뿐이다.

엔터프라이즈 현실에서 살아남는 패턴

Webb의 글은 어떤 프로토콜 비교표보다 결정을 잘 프레이밍한다. OAuth 플로우 메뉴에서 고르지 말고, 에이전트의 권한이 어디에서 유래하는지에서 출발하라. 나머지는 그 질문에서 자연히 따라 나온다. 세 가지 패턴이 거의 모든 엔터프라이즈 케이스를 커버한다.

  • 대화형 도구에는 위임된 사용자 권한: 사람의 권한이 authorization code 플로우를 통해 에이전트로 흐른다. 여기서의 함정은 토큰 패스스루, 즉 업스트림 아이덴티티 프로바이더의 토큰을 MCP 서버로 그대로 전달하는 것이다. 데모에서는 동작하지만, 프로덕션에서는 에이전트 플랫폼을 외부 토큰 포맷과 신뢰 모델에 결합시킨다. 토큰을 특정 MCP 서버용으로 발급된 짧은 수명의 토큰으로 교환하고 audience 검증을 강제하라. 명세의 RFC 8707 resource indicator 요구사항은 정확히 범용 토큰 세탁이 실패하도록 만들기 위해 존재한다.
  • 무인 워크로드에는 머신 아이덴티티: SEP-1046 client credentials, private_key_jwt 우선, 플랫폼 전체가 공유하는 "agents" 클라이언트 하나가 아니라 에이전트 워크로드마다 등록된 클라이언트 하나. 폭발 반경은 등록 granularity를 따라간다.
  • 흥미로운 중간 지대에는 이중 아이덴티티: 사용자를 대신해 행동하지만 무인으로 실행되는 에이전트다. 토큰은 행위자(에이전트)와 대상(사용자)을 모두 표현해야 하고, 토큰 교환이 이를 지원하며 대부분의 인가 서버가 이제 표현할 수 있다. 감사에서 "이 행동에 책임지는 사람이 누구인가"에 답할 수 있게 유지해 주는 패턴이며, 컴플라이언스 팀이 실제로 물을 질문이 바로 이것이다.

등록 자체에 대해서는, SEP-991이 사전 관계가 없는 클라이언트와 서버를 위해 OAuth Client ID Metadata Documents, 즉 HTTPS URL을 클라이언트 식별자로 쓰는 방식을 선호 패턴으로 만들었다. 열린 생태계에는 우아한 방식이다. 하지만 닫힌 엔터프라이즈에서는 기업 아이덴티티 플랫폼을 통한 사전 등록이 여전히 더 강한 기본값이다. 소유권, 허용 목록, 라이프사이클 통제를 제공하고, 메타데이터 페치 SSRF 우려라는 위협 범주 하나를 통째로 위협 모델에서 제거해 주기 때문이다.

SEP-1046은 하나의 차선일 뿐, 도로 전체가 아니다

스펙 저장소의 auth 라벨에서 한 시간만 보내면 단일 SEP 관점은 무너진다. 정기 회의를 여는 상설 auth 워킹 그룹이 있고, 엔터프라이즈 MCP 인가의 다음 단계를 그리는 제안 대기열이 있다. SEP-1488은 혼합 인증 서버를 위해 도구 메타데이터에 securitySchemes를 추가한다. 공개 도구와 OAuth로 보호된 도구를 한 서버가 함께 노출하는 경우다. SEP-1489는 세션 중간에 OAuth 플로우를 트리거하는 도구 오류를 표준화한다. 에이전트 용어로는 step-up 인가다. SEP-2742는 원격 서버가 인증 방식을 미리 선언하게 해서, 클라이언트가 연결 전에 무엇을 만나게 될지 알게 한다. HTTP 메시지 서명은 SEP-1415가 휴면 상태가 된 뒤 PR #2752로 돌아왔다. 굵직한 SEP 사이사이에 보강도 계속 들어온다. mix-up 공격을 막는 RFC 9207 issuer 검증 의무화(#1721), RFC 9396 Rich Authorization Requests(#1670), 오프라인 접근을 위한 refresh token 전달(#1735), 그리고 인가 스펙을 기반 OAuth RFC에 위임해 슬림하게 만들려는 진행 중인 작업(#3054). 기업에서 에이전트 보안을 책임지고 있다면 이 이슈 대기열이 곧 로드맵이다. 자신의 백로그를 읽듯 읽어라.

월요일에 할 일

조직 안에 MCP를 도입하는 플랫폼 팀이나 보안 팀이라면, 구체적으로 이렇게 하면 된다.

  • 모든 MCP 통합을 목록화하고 분류하라: 대화형, 무인, 대리 실행. 플로우는 분류를 따라가며, 그 반대가 되어서는 안 된다.
  • 모든 무인 에이전트에 아이덴티티 프로바이더의 등록된 클라이언트를 각각 부여하라. 툴링이 요구하면 클라이언트 시크릿으로 시작하되, private_key_jwt를 지금 로드맵에 올리고 사용하는 SDK가 이미 지원하는지 확인하라. TypeScript, Python, Ruby는 지원한다.
  • 운영하는 모든 MCP 서버에서 audience 검증을 강제하라. 한 서버용으로 발급된 토큰은 다른 서버에서 실패해야 한다. 이것이 스택 전체에서 가장 저렴한 통제이자 가장 흔히 생략되는 통제다.
  • 문자열로 조립한 SQL을 금지하듯 코드 리뷰에서 토큰 패스스루를 금지하라. 에이전트 아이덴티티의 SQL 인젝션이다. 편리하고, 어디에나 있고, 잘못됐다.
  • 에이전트 권한은 기본 읽기 전용으로 유지하고 모든 변경 경로에 게이트를 두라. Agents on Call 게이트웨이 글에서 인프라 계층에 대해 주장한 것과 같은 자세다. 인증은 에이전트가 누구인지 알려 줄 뿐, 무엇을 해도 되는지는 아무것도 말해 주지 않는다.

더 큰 그림은 이렇다. 매달 "X 때문에 엔터프라이즈는 에이전트를 도입할 수 없다"의 또 다른 조각이 어딘가의 GitHub 이슈에서 조용히 해결된다. 인증은 가장 큰 X였다. 1년 전 "우리 무인 에이전트는 MCP 서버에 어떻게 인증하나"에 대한 정직한 답은 어깨를 으쓱하는 것이었다. 지금은 SEP 번호 하나, 클라이언트 인증 방식 두 가지, 세 SDK의 컨포먼스 테스트다. 우리는 무엇을 어떻게 만들 수 있는지 매주 조금씩 더 배우고 있다. 이 틈이 닫히는 과정을 추적하는 팀은 완성된 교과서를 기다리는 팀보다 1년 앞서 출시할 것이다. 교과서는 나오지 않을 것이기 때문이다.

이어서 읽기

아이덴티티는 에이전트 보안의 절반일 뿐이다. IAM for LLM Apps: Least Privilege When the Caller Is a Model은 AWS에서의 인가라는 나머지 절반을 다룬다. 자매 사이트의 Agent Toolkit for AWS: The Docs Have a New Reader는 인프라를 소비하는 에이전트가 매뉴얼도 직접 읽게 될 때 무슨 일이 벌어지는지 살펴보고, ercanermis.com에는 내가 어디에 무엇을 쓰는지 전체 지도가 있다.

참고 자료