인기 오픈 소스 LLM 게이트웨이에 대해 MCP 게이트웨이 운영 준비성 감사를 실시했습니다. 그 결과는 다음과 같습니다.
요약
오픈 소스 LLM 게이트웨이인 LiteLLM을 대상으로 MCP(Model Context Protocol) 운영 준비성을 감사한 결과입니다. 보안, 관측성, 비용 제어 등 7가지 차원에서 검토를 진행하여 실제 운영 환경에서의 안정성을 분석했습니다.
핵심 포인트
- LiteLLM은 '주의 사항이 있는 운영 준비 완료' 상태로 평가됨
- ID 및 비밀 정보 관리(Secrets) 측면에서 높은 보안성을 보임
- OAuth 토큰 교환을 통한 MCP 토큰의 권한 전파 지원 확인
- 운영 환경 도입 전 Fail-close/Fail-open 동작 방식 검토 필요
인기 오픈 소스 LLM 게이트웨이에 대해 MCP 게이트웨이 운영 준비성 감사를 실시했습니다. 그 결과는 다음과 같습니다.
LLM 게이트웨이를 MCP 도구에 연결하는 대부분의 팀은 한 가지 질문을 던집니다. "이게 작동하는가?" 하지만 출시 후 밤잠을 설치느냐 아니냐를 결정하는 더 어려운 질문은 따로 있습니다. 권한 확인(Authorization check) 과정에서 예상치 못한 예외(Exception)가 발생했을 때, 게이트웨이는 호출을 거부할까요, 아니면 허용할까요? 이 단 한 줄의 동작 방식이 성숙한 플랫폼과 조용한 화요일에 터질 사고를 가르는 기준이 됩니다.
그래서 저는 이 질문에 답하기 위한 구조화된 방법을 구축했고, 이 방법론에 아부하지 않을 대상을 타겟으로 정했습니다.
타겟이 아닌 방법론
이번 감사는 다음 7가지 차원에 걸쳐 읽기 전용(Read-only)으로 진행되었으며, 증거에 기반한 검토입니다: 도구 액세스 거버넌스 및 RBAC(역할 기반 액세스 제어), Fail-close(실패 시 차단) 대 Fail-open(실패 시 허용) 동작, MCP 및 에이전트 온보딩, 관측성(Observability) 및 트레이싱(Tracing), 멀티 LLM 라우팅 및 비용 제어, 비밀 정보(Secrets) 및 ID(Identity), 그리고 더 넓은 의미의 운영 준비성(Production-readiness)입니다. 모든 발견 사항은 팀이 파일을 열어 제가 읽은 것과 동일한 줄을 읽을 수 있도록, 특정 커밋(Commit)에 고정된 정당한 근거 코드를 지목해야 합니다. 라이브 결함 주입(Fault injection)이나 추측은 없으며, 모든 주장은 해당 리비전(Revision)의 코드로 추적됩니다. 만약 제어 기능이 코드에는 존재하지만 운영자가 직접 활성화해야만 효과가 나타나는 경우, 그 역시 기록됩니다. 왜냐하면 대부분의 배포 환경에서는 기본 설정(Default)이 그대로 적용되기 때문입니다.
실제 사례 연구를 위해 저는 특정 커밋에 고정된 BerriAI의 LiteLLM을 사용했습니다. 이는 널리 배포되고 있는 오픈 소스 LLM 프록시(Proxy)이며, 코드가 공개되어 있고, 허술한 대상보다는 허술한 방법론을 드러낼 만한 성숙한 프로젝트입니다. 결과에 대해 미리 명확히 말씀드리자면, 점수는 좋았습니다. 7개 차원(Dimension) 중 4개는 녹색(Green), 3개는 황색(Yellow), 0개는 적색(Red)을 기록했습니다. 최종 판정은 "주의 사항이 있는 운영 준비 완료(production-ready with caveats)"였습니다. 이는 유능한 플랫폼에 대한 공정한 평가이며, 비난을 위한 것이 아닙니다. 흥미로운 점은 강력한 게이트웨이라 할지라도 구조화된 검사를 거치면 한계점이 드러난다는 것이며, 그 한계점들이야말로 MCP를 운영 환경(Production)에서 실행하는 모든 팀이 자체 배포 환경에서 직접 확인해야 할 바로 그 요소들입니다.
잘 구현된 부분
안전성 비중이 가장 높은 차원들이 가장 강력한 모습을 보였습니다.
ID(Identity) 및 비밀 정보(Secrets) 항목은 큰 격차 없이 녹색을 기록했습니다. 설정 파일 내에 인라인(Inline)으로 포함된 비밀 값은 없었습니다. 실제 설정은 os.environ 및 os.getenv를 통해 환경 변수를 참조하며, 트리 내에서 발견된 유일한 sk- 스타일의 문자열은 독스트링(Docstring) 예시뿐이었습니다. ID는 단순히 대시보드 로그인에 국한되지 않고 실제 게이트웨이 호출 경로에 기반한 JWT 및 OIDC를 기반으로 하며, 최종 사용자 ID는 하나의 공유 서비스 자격 증명으로 통합되지 않고 MCP 처리 및 비용 로그(Spend logs)까지 전파됩니다. MCP 토큰의 경우, 게이트웨이는 대상(Audience) 및 범위(Scope) 바인딩을 포함한 RFC 8693 OAuth 토큰 교환(Token-exchange)을 지원하므로, MCP 서버는 전달된 사용자 토큰 대신 자신을 위해 발행된(Minted) 토큰을 받게 됩니다. 이는 현재 MCP 사양(Specification)이 지향하는 리소스 서버(Resource-server) 패턴을 따릅니다. 한 가지 솔직한 세부 사항을 덧붙이자면, 이는 기본 설정(Default)이 아니라 운영자가 활성화해야 하는 모드이므로, 상속받는 기능이라기보다는 직접 켜야 하는 제어 항목(Control)으로 간주됩니다.
관측성 (Observability) 또한 양호 (green)했습니다. OpenTelemetry는 전용 GenAI 시맨틱 컨벤션 (semantic-convention) 매핑을 갖춘 일급 시민 (first-class) 통합 기능이므로, 나중에 덧붙이는 방식이 아니라 모델별 토큰 및 비용 할당 (attribution)이 가능합니다. 인바운드 W3C traceparent 헤더는 표준 프로파게이터 (propagator)를 통해 추출되며, 이는 홉 (hop) 간의 엔드 투 엔드 (end-to-end) 트레이스 연속성 (trace continuity) 달성이 가능함을 의미합니다.
LiteLLM이 목적으로 설계된 차원인 라우팅 (Routing) 및 비용 (cost) 측면도 성능을 입증했습니다. 선언적인 model_list는 가상 모델 이름을 물리적 배포 (deployment)에 매핑하며, 예산 상한선 (budget caps)이 실제로 강제됩니다. 예산 초과 시에는 단순히 경고를 보내고 지출을 계속하게 두는 것이 아니라, BudgetExceededError를 발생시킵니다. 요청 수 및 분당 토큰 수에 대한 속도 제한 (Rate limits)은 키(key)별, 모델별, 심지어 MCP 서버별로 표현할 수 있습니다. 이는 돈이 이미 다 빠져나간 후에 빨간색으로 변하는 대시보드가 아니라, 청구서 충격 (bill-shock) 및 자산 고갈 공격 (denial-of-wallet)에 대응하는 실제적이고 강제적인 경로입니다.
관측성에 대한 한 가지 솔직한 주의 사항: 이번 검토는 라이브 백엔드가 없는 공개 리포지토리 (public repo)를 대상으로 한 정적 검토였기 때문에, 실제 엔드 투 엔드 트레이스를 추출하여 재구성되는 과정을 관찰할 수는 없었습니다. 구성 요소들은 존재하며 표준을 준수하고 있습니다. 실제 요청 하나가 엔드 투 엔드로 연결되는지 확인하는 것은 모든 팀이 자체 스테이징 (staging) 환경에서 실행해야 할 단계입니다.
모든 배포 시 확인해야 할 세 가지 주의 사항 (yellows)
이 중 어느 것도 제어 항목이 누락된 것은 아닙니다. 이는 기본값 (defaulting) 및 운영상의 공백이며, 이는 아키텍처 재설계보다는 강화 (hardening)가 필요한 역량 있는 플랫폼의 전형적인 특징입니다.
첫째, 한 줄의 fail-open(실패 시 허용) 사례가 발견되었습니다. 모든 레벨별 권한 결정기(permission resolver)는 fail-closed(실패 시 차단) 방식으로 동작합니다. 즉, 예기치 않은 예외(exception)가 발생하면 로그를 남기고 빈 세트(empty set)를 반환하며, 이는 하류(downstream)에서 "접근 권한 없음"으로 해결됩니다. 이는 올바른 태세입니다. 예외적인 부분은 최상위 래퍼(wrapper)인 get_allowed_mcp_servers()로, 예기치 않은 오류 발생 시 빈 리스트 대신 모든 서버를 허용하는 서버 세트를 반환합니다. 영향 범위(blast radius)는 운영자가 이미 공개(public)로 표시한 서버들로 제한되지만, 권한 결정기에서의 fail-open은 프레임워크 전체에서 가장 위험도가 높은 클래스입니다. 검사 기능이 저하되었을 때 조용히 "허용"으로 바뀌기 때문입니다. 또한 이는 단 한 줄의 수정과 회귀 테스트(regression test)만으로 해결 가능하므로, 이번 감사에서 노력 대비 가장 높은 위험 감소 효과를 제공합니다.
둘째, 고정되지 않은(unpinned) 제3자 MCP 서버들입니다. 큐레이션된 카탈로그는 npx -y @sentry/mcp-server와 같이 버전, 다이제스트(digest) 또는 체크섬(checksum) 고정 없이 유동적인 명령어를 사용하는 stdio 서버를 실행합니다. 이는 패키지 변조를 통한 공급망 사고(supply-chain incident)로 이어질 수 있는 상태이며, OWASP가 2025년 목록에서 LLM03으로 분류한 유형입니다. 버전과 다이제스트로 고정하고, 고정되지 않은 모든 것을 거부함으로써 이를 차단할 수 있습니다.
셋째, 도구별 최소 권한(least-privilege) 원칙이 선택 사항(opt-in)입니다. 게이트웨이에서의 권한 부여(authorization)는 강력합니다. 호출자 신원(caller identity)에 대해 키(key), 팀(team), 최종 사용자(end-user), 에이전트(agent), 조직(org) 권한의 엄격한 교집합으로 강제되며, 모델은 권한 결정 과정에서 완전히 배제됩니다. 이것이 프롬프트 주입을 통한 도구 호출(prompt-injection-to-tool-call)을 방어하는 핵심입니다. 하지만 서버별 allowed_tools 허용 목록(allowlist)이 없다면, 서버에 접근 권한이 있는 모든 호출자는 쓰기 권한이나 외부 도구를 포함하여 해당 서버의 모든 도구를 호출할 수 있습니다. 이는 OWASP가 LLM06으로 추적하는 과도한 권한 노출(excessive-agency exposure)에 해당합니다. 온보딩 시 이 허용 목록을 필수화하고 CI에서 검증함으로써, 최소 권한 원칙을 선택 사항에서 기본값(default)으로 전환할 수 있습니다.
교훈
구조화된 감사 (structured audit)는 결정적인 증거(smoking gun)를 찾는 과정이 아닙니다. 성숙한 대상에서는 대개 결정적인 증거가 발견되지 않으며, 이번 사례도 마찬가지였습니다. 대신 7가지 차원의 검토를 통해 드러난 것은, 훌륭한 코드베이스 속에 숨어 있는 프로덕션 준비성 (production-readiness)의 경계 지점들이었습니다. 다른 리졸버 (resolver)들이 안전을 지향할 때 노출 쪽으로 치우치는 리졸버 하나, 버전을 고정 (pinning)하는 대신 유동적으로 두는 공급망 (supply chain), 그리고 누군가 선택(opt in)하기를 기다리는 최소 권한 제어 (least-privilege control) 등이 그것입니다. 이러한 문제들은 "작동하는가?"라고 물을 때는 나타나지 않습니다. 게이트웨이는 잘 작동하기 때문입니다. 하지만 경계 지점에서 무엇이 일어나는지, 오류 상황에서는 어떤지, 그리고 대부분의 운영자가 절대 변경하지 않는 기본값 (defaults)에서는 어떤 일이 발생하는지를 물을 때 비로소 드러납니다.
이것이 바로 이 방법론의 가치입니다. 이 방법론은 "괜찮을 것 같다"라는 막연한 생각을 명명된 수정 사항, 노력 추정치, 그리고 각 발견 사항 뒤에 숨겨진 정확한 코드가 포함된 점수화된 그림으로 바꿔줍니다. 이를 통해 팀은 막연한 느낌이 아니라 구체적인 동작 라인을 두고 논의할 수 있게 됩니다.
이 결과를 만들어낸 감사 키트 (audit kit)는 읽기 전용 (read-only)으로 실행되며 Claude Code, Cursor 또는 모든 MCP 클라이언트에서 작동합니다. 만약 프로덕션 도구 앞에 MCP 게이트웨이를 배치하고 있으며, 여러분의 배포 환경에 대해서도 이와 동일하게 점수화되고 증거에 기반한 검토를 원하신다면, 그것이 바로 제가 수행하는 범위 지정된 프로젝트 (scoped engagement)입니다.
Sources
- LiteLLM (BerriAI), pinned commit
51ba6e39cd23576b9c2110361f1045782762f3e4— 실제 감사 대상이 된 소스; 모든 발견 사항은 이 리비전(revision)의 코드를 가리키므로, 동일한 라인에서 다시 확인할 수 있습니다. - RFC 8693 — OAuth 2.0 Token Exchange — 대상(audience) 및 범위(scope)가 제한된 MCP 토큰의 기반이 되는 토큰 교환 (token-exchange) 모델.
- Model Context Protocol specification (2025-06-18) — 게이트웨이의 MCP 토큰 설계가 따르는 리소스 서버 (resource-server) 모델.
- OWASP Top 10 for LLM Applications (2025) — LLM03 (공급망 보안, Supply Chain) 및 LLM06 (과도한 권한 부여, Excessive Agency) 항목이 고정되지 않은 서버(unpinned-server) 및 최소 권한(least-privilege) 관련 발견 사항의 프레임워크를 제공합니다.
- W3C Trace Context — 엔드 투 엔드 추적 연속성 (end-to-end trace continuity)을 가능하게 하는
traceparent전파 표준. - OpenTelemetry GenAI semantic conventions — 게이트웨이가 통합하는 모델별 토큰 및 비용 할당 (cost attribution) 매핑.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기