원격 MCP 서버와 OAuth를 연결할 때 “로그인은 됐다”는 사실만으로 연결이 안전해지는 것은 아니다. 제공된 MCP 보안 지침은 토큰이 어느 MCP 서버를 위한 것인지 분명히 하고, 그 서버가 실제 대상인지 확인해야 한다고 설명한다. 이 글은 그 원칙을 구현 점검 항목으로 바꾼다.
먼저 확인할 핵심: 토큰의 대상 리소스
MCP 클라이언트는 권한 요청과 토큰 요청 모두에 resource 매개변수를 넣어 대상 MCP 서버를 밝혀야 한다. MCP 서버는 받은 토큰이 자신을 대상으로 발급됐는지 검증하고, 자신이 대상이 아니라면 거부해야 한다. Model Context Protocol Authorization
OAuth Resource Indicators에서 resource 값은 보호할 리소스를 식별한다. 이 값은 권한 서버가 해당 리소스에 맞는 토큰을 발급하고 audience 제한을 적용하도록 돕는다. audience가 제한된 토큰은 원래 의도한 리소스가 아닌 다른 리소스에서 재사용하기 어려워진다. RFC 8707
왜 클라이언트와 서버가 모두 확인해야 할까
클라이언트가 resource를 요청에 넣는 일은 “이 토큰이 어디에 쓰일지”를 권한 서버에 전달하는 단계다. 서버의 검증은 “지금 제시된 토큰이 정말 나를 위한 것인지”를 확인하는 단계다. 둘 중 하나만으로는 제공된 MCP 규격이 요구하는 요청과 거부의 흐름을 모두 충족했다고 볼 수 없다.
| 점검 지점 | 해야 할 일 | 근거가 되는 효과 |
|---|---|---|
| 권한 요청 | 대상 MCP 서버를 가리키는 resource 포함 |
토큰 대상 리소스를 명시 |
| 토큰 요청 | 같은 대상 MCP 서버의 resource 포함 |
대상에 맞는 토큰 발급 요청 |
| MCP 서버 | 토큰이 자신을 대상으로 발급됐는지 검증 | 대상이 아니면 거부 |
| 권한 서버 | resource에 맞춰 토큰을 발급하고 audience 제한 적용 |
다른 리소스 재사용을 어렵게 함 |
토큰 패스스루를 금지해야 하는 이유
토큰 패스스루는 MCP 서버가 토큰을 검증하지 않은 채 다운스트림 API로 전달하는 안티패턴이다. MCP 보안 지침은 이 방식이 대상 서비스의 보안 통제를 우회하고, 감사 추적을 약화하며, 탈취된 토큰이 데이터 반출 프록시로 악용될 수 있다고 설명한다. 또한 MCP 서버는 자신을 대상으로 명시적으로 발급되지 않은 토큰을 받아서는 안 된다고 명시한다. MCP Security Best Practices
따라서 “API 호출이 성공하는가”를 기준으로 전달 여부를 정하면 안 된다. 먼저 토큰의 대상이 현재 MCP 서버인지 확인하고, 확인할 수 없거나 대상이 다르면 요청을 거부하는 흐름이 필요하다. 이 판단은 편의 기능이 아니라 토큰을 검증 없이 중계하지 않기 위한 경계다.
PKCE를 연결 흐름에 포함하기
PKCE는 authorization code interception 공격을 완화하기 위한 방식이다. 클라이언트는 code_verifier와 code_challenge를 사용한다. 공격자가 authorization code만 가로채더라도, 원래 클라이언트의 verifier 없이는 토큰으로 교환하기 어려워진다. RFC 7636
구현 순서
- 권한 요청을 만들 때 대상 MCP 서버를 나타내는
resource를 포함한다. - PKCE용
code_verifier를 만들고, 그에 대응하는code_challenge를 권한 요청에 포함한다. - authorization code를 받은 뒤 토큰 요청을 보낼 때도 대상 MCP 서버의
resource를 포함한다. - 토큰 교환 시 원래의
code_verifier를 사용한다. - MCP 서버는 도착한 토큰이 자신을 대상으로 발급됐는지 검증한다.
- 대상이 다르거나 검증할 수 없으면 다운스트림 API로 전달하지 않고 거부한다.
배포 전 체크리스트
- [ ] 권한 요청에
resource가 있다. - [ ] 토큰 요청에도
resource가 있다. - [ ] 두 요청의 대상이 연결하려는 MCP 서버와 일치한다.
- [ ] 서버가 토큰의 대상 리소스를 검증한다.
- [ ] 대상이 아닌 토큰을 거부한다.
- [ ] 검증하지 않은 토큰을 다운스트림 API에 전달하지 않는다.
- [ ] authorization code 흐름에 PKCE의 verifier와 challenge가 포함된다.
- [ ] code만 탈취된 경우에도 verifier 없이는 교환하기 어렵다는 PKCE의 목적을 테스트 항목에 반영한다.
한계도 분명히 보기
resource와 audience 제한은 토큰을 의도한 리소스에 묶는 데 도움을 주지만, 이 자료만으로 모든 OAuth 위협이 해결된다고 말할 수는 없다. PKCE 역시 authorization code interception 완화에 관한 장치다. 제공된 근거는 토큰 저장 방식, 저장 기간, 운영 환경별 로그 처리 방식까지 규정하지 않는다. 그러므로 이 글의 체크리스트는 대상 검증, 패스스루 차단, PKCE 적용에 초점을 둔 최소 점검표로 사용해야 한다.
구매 전 판매 페이지의 구성과 사용 대상을 다시 확인해.
FAQ
resource는 권한 요청에만 넣으면 되나?
아니다. MCP 규격은 권한 요청과 토큰 요청 모두에 resource를 포함해 대상 MCP 서버를 명시하도록 한다. Model Context Protocol Authorization
토큰이 유효하면 그대로 다운스트림 API로 보내도 되나?
아니다. MCP 보안 지침은 검증하지 않은 토큰을 전달하는 토큰 패스스루를 안티패턴으로 본다. 서버는 자신을 대상으로 명시적으로 발급되지 않은 토큰을 받아서는 안 된다. MCP Security Best Practices
PKCE가 해결하는 범위는 무엇인가?
PKCE는 authorization code가 가로채이는 공격을 완화한다. code만 가진 공격자는 원래 클라이언트의 verifier 없이는 토큰 교환이 어려워진다. RFC 7636
안전한 연결의 핵심은 단순하다. 토큰이 누구를 위한 것인지 요청 단계에서 명시하고, 서버 단계에서 다시 확인하며, 확인하지 않은 토큰은 전달하지 않는 것이다.
이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.