본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 08. 00:12

MCP 서버를 위한 보안: 관리된 접근 방식이 ChatGPT에 스프레드시트를 업로드하는 것보다 나은 이유

요약

기업 환경에서 ChatGPT에 직접 데이터를 업로드하는 방식의 보안 및 일관성 문제를 지적합니다. 대신 MCP(Model Context Protocol) 서버를 활용하여 데이터 접근을 통제하고 비즈니스 로직을 표준화하는 관리된 인터페이스 구축의 중요성을 강조합니다.

핵심 포인트

  • 직접적인 데이터 업로드는 개인정보 노출 및 통제 불능 위험이 있음
  • 임시 프롬프트 사용 시 비즈니스 집계 결과의 불일치 발생 가능
  • MCP 서버는 모델과 데이터 사이의 통제된 인터페이스 역할을 수행
  • MCP를 통해 최소한의 데이터만 제공하여 보안과 일관성 확보

한 분석가가 고객 데이터가 포함된 스프레드시트를 내보내어 일반적인 AI 채팅창에 업로드하고, 판매 요약을 요청하자 몇 초 만에 답변을 얻었습니다. 생산적으로 느껴질 수 있습니다. 하지만 이는 기업에 AI를 도입하는 방식 중 통제가 가장 적은 방법 중 하나입니다. 모델은 가공되지 않은 원본 파일을 보게 됩니다. 조직은 어떤 필드가 노출되었는지, 개인정보(PII)가 포함되었는지, 동일한 데이터를 먼저 집계했어야 했는지, 혹은 애초에 사용자가 모든 행에 접근할 권한이 있었는지에 대해 거의 통제할 수 없습니다.

기업 환경에서는 그만큼 중요한 또 다른 실패 모드가 있습니다. 바로 일관성 없는 비즈니스 집계(Business Aggregation)입니다. 저는 한 회사에서 두 명의 관리자가 동일한 기초 보고서를 바탕으로 같은 경영 회의용 보고서를 준비했으나, ChatGPT로부터 극적으로 다른 답변을 얻는 것을 직접 목격했습니다. 한 관리자는 7월에 시작하는 회사의 회계연도를 사용하도록 지시했지만, 다른 관리자는 그렇게 하지 않았습니다. 한 명은 캐나다를 북미의 일부로 언급했지만, 다른 명은 이를 묻는 것을 잊었습니다. 두 보고서 모두 깔끔해 보였고 동일한 원시 데이터를 기반으로 했지만, 비즈니스 정의가 관리된 인터페이스(Governed Interface)가 아닌 임시 프롬프트(Ad hoc Prompts)에 저장되어 확률론적 LLM(Large Language Model)으로 전송되었기 때문에, 회의는 상충하는 수치와 함께 시작되었습니다.

이것은 기업용 AI를 위한 잘못된 운영 모델입니다.

Security of AI platforms

더 안전한 패턴은 AI 클라이언트를 MCP(Model Context Protocol) 서버에 연결하는 것입니다. MCP 서버는 모델과 기초 데이터 시스템 사이의 통제된 인터페이스 역할을 합니다. MCP 서버는 어떤 도구(Tools)가 존재하는지, 도구가 어떤 입력을 받는지, 어떤 데이터 형태(Data Shape)를 반환하는지, 그리고 어떤 인증된 사용자를 대신하여 동작하는지를 결정합니다. 모델은 스프레드시트 전체를 받지 않습니다. 질문에 답하는 데 필요한, 관리된 최소한의 데이터 조각만을 받게 됩니다.

잘 설계된 MCP 서버는 이러한 종류의 의미론적 드리프트 (semantic drift)를 방지합니다. 비즈니스 분석가 (business analyst)는 회계 연도가 7월에 시작된다는 점, 북미에 캐나다가 포함된다는 점, 수익이 특정 회계 규칙에 따라 인식된다는 점, 그리고 경영 보고서가 표준 집계 (aggregation)를 반환해야 한다는 점을 정의할 수 있습니다. 그러면 모든 사용자 및 모든 모델은 매 채팅마다 이러한 선택 사항들을 다시 논쟁하는 대신, 동일하고 통제된 비즈니스 정의를 바탕으로 작업하게 됩니다.

이 지점에서 이전 기사들에서 반복되었던 모티프가 다시 등장합니다. 훌륭한 MCP 설계는 항상 여러 당사자 간의 강점 사이의 균형을 맞추는 것입니다. 보안은 단일 구성 요소의 역할이 아닙니다. **비즈니스 분석가 (business analyst)**는 안전한 비즈니스 접점 (business surface)을 정의합니다. **비즈니스 사용자 (business user)**는 실행 시점의 질문을 가져옵니다. LLM은 의도를 해석합니다. **MCP 서버 (MCP server)**는 결정론적 (deterministically)으로 검증하고 실행합니다. 그리고 code mode 기사에서 보았듯이 접점이 더욱 강력해지면, **IT 관리자 (IT administrator)**가 정책, 승인 및 감사를 관리합니다. 각 당사자는 상대방의 약점을 보완합니다.

이 기사는 이러한 균형이 어떻게 프로덕션용 MCP 서버를 위한 보안 아키텍처 (security architecture)가 되는지 보여주며, 보안 계층들이 모여 AI 상호작용에 대한 전반적인 신뢰를 어떻게 강화하는지 설명합니다.

MCP란 무엇인가? (30초 요약 버전)

모델 컨텍스트 프로토콜 (Model Context Protocol, MCP, spec 2025-11-25)은 도구 (tools), 프롬프트 (prompts), 리소스 (resources)를 통해 AI 클라이언트와 외부 시스템 사이를 연결하는 인터페이스 계층입니다. 엔터프라이즈 배포 환경에서 MCP 서버는 내부 데이터 시스템 위에 구축된 얇고, 원격이며, 대부분 상태가 없는 (stateless) 인터페이스 계층이어야 합니다. HTTP 기반 애플리케이션이 엔터프라이즈 시스템에 대한 인간 중심의 인터페이스라면, MCP 서버는 AI 중심의 인터페이스입니다.

그러한 프레임워크는 보안 측면에서 매우 중요합니다. MCP 서버를 인터페이스 계층 (interface tier)으로 바라보는 순간, 적절한 통제 수단들이 명확해집니다: 인증된 요청 (authenticated requests), 타입이 지정된 입력 (typed inputs), 최소 권한 원칙에 따른 다운스트림 접근 (least-privilege downstream access), 출력 필터링 (output filtering), 감사 추적 (audit trails), 속도 제한 (rate limits), 그리고 능동적인 보안 테스트 (active security testing) 등이 그것입니다. 서버는 엔터프라이즈 통제 수단을 우회하는 지름길이 아닙니다. 오히려 AI를 위해 그러한 통제 수단들이 명시적으로 구현되어야 하는 지점입니다.

여기에는 업계 전반에 걸친 더 큰 교훈도 담겨 있습니다. 우리는 팀이 입력을 너무 신뢰하거나, 백엔드에 과도한 권한을 부여하거나, 요청별 권한 부여 (per-request authorization)를 생략하거나, 광범위한 공격 표면 (attack surfaces)을 노출한 채 클라이언트가 잘 작동하기만을 바랄 때 데이터 직면 인터페이스가 얼마나 취약해지는지를 이미 수십 년간 고통스럽게 배워왔습니다. SQL 인젝션 (SQL injection), 깨진 접근 제어 (broken access control), 자격 증명 유출 (credential leakage), 과도하게 넓은 서비스 ID (over-broad service identities), 테넌트 격리 실패 (tenant isolation failures), 그리고 데이터 유출 (data exfiltration)은 추상적인 위험이 아니었습니다. 그것들은 웹 보안의 역사였습니다. MCP는 사용자, 모델, 그리고 데이터 시스템 사이의 차세대 인터페이스 계층입니다. MCP는 이러한 교훈들로부터 시작해야 하며, 처음부터 다시 배울 필요가 없어야 합니다.

진정한 대안은 "MCP냐 아니냐"가 아닙니다

많은 엔터프라이즈 보안 논의가 잘못된 비교에서 시작됩니다. 실질적인 비교 대상은 다음과 같은 것이 아닙니다:

  • MCP 서버
  • 아무것도 없음

진정한 비교 대상은 대개 다음과 같습니다:

  • 관리되는 (governed) MCP 서버
  • 비즈니스 사용자가 일반 AI 채팅창에 민감한 자료를 붙여넣거나 업로드하는 행위

사용자가 스프레드시트를 직접 업로드할 때, 조직은 대부분의 통제 지점 (control points)을 상실하게 됩니다:

  • 데이터가 얼마나 최신인지 추적할 수 없음
  • 타입이 지정되거나 검증된 입력 계약 (input contract)이 없음
  • 서버 측 출력 형태 조정 (output shaping)이 불가능함
  • 도구별 권한 부여 경계 (per-tool authorization boundary)가 없음
  • 행 수준 (row-level) 또는 필드 수준 (field-level) 정책 강제를 보장할 수 없음
  • 어떤 비즈니스 운영이 관리되었는지에 대한 신뢰할 수 있는 감사 추적 (audit trail)이 없음

MCP 서버는 이러한 제어 지점(control points)을 복구합니다. "파일 자체"를 노출하는 대신, quarterly_sales_summary, customer_health_report, 또는 query_sales_cube와 같이 의도적으로 제한된 입력(inputs)과 출력(outputs)을 가진 도구(tool)를 노출할 수 있습니다. 이것이 기업 환경에서 MCP가 제공하는 보안상의 이점입니다. 즉, 은폐를 통한 비밀 유지가 아니라, 인터페이스 설계(interface design)를 통한 거버넌스(governance)를 실현하는 것입니다.

보안은 도구 설계에서 시작된다

첫 번째 기사에서는 도구 설계가 MCP의 UX 규율(UX discipline)이라고 주장했습니다. 이는 또한 MCP의 첫 번째 보안 계층(security layers) 중 하나이기도 합니다.

비즈니스 분석가(business analyst)는 설계 단계(design time)에서 직접적인 보안 역할을 수행합니다. 그들은 다음 사항을 결정합니다:

  • 어떤 비즈니스 작업이 도구로서 존재해야 하는지
  • 해당 작업에 어떤 입력(inputs)이 유효한지
  • 모델이 실제로 필요로 하는 출력(outputs)은 무엇인지
  • 어떤 필드(fields)는 절대 반환되어서는 안 되는지
  • 어떤 워크플로(workflows)를 임시 탐색(ad hoc exploration)에 맡기지 않고 프롬프트(prompts)로 패키징해야 하는지

이것이 중요한 이유는 대부분의 기업 데이터 노출이 암호화 제어(cryptographic control)가 실패하기 훨씬 이전에 발생하기 때문입니다. 데이터 노출은 잘못된 인터페이스가 공개될 때 발생합니다.

만약 분석가가 도구를 "재무 데이터에 대해 모든 SQL 실행"으로 정의한다면, 서버의 노출 범위(surface)는 이미 너무 넓습니다. 반면, 지역 범위를 위한 열거형(enum)과 검증된 분기(quarter) 필드, 그리고 고정된 출력 형태(output shape)를 갖춘 "선택된 분기에 대해 지역별 매출 요약"으로 정의한다면, 런타임(runtime)이 시작되기 전에 대부분의 리스크가 제거됩니다.

이는 우리가 이 시리즈 전체에서 사용해 온 것과 동일한 균형입니다. 분석가는 도메인 판단(domain judgment)을 제공하고, 서버는 결정론적 강제(deterministic enforcement)를 제공하며, 모델은 언어 이해(language understanding)에 기여합니다. 그리고 사용자는 구체적인 비즈니스 질문을 제공합니다. 각 주체가 모두 같은 일을 서투르게 수행하는 것이 아니기 때문에 보안이 향상됩니다.

타입이 지정된 입력은 보안 경계이다

유용한 패턴 중 하나이자 PMCP와 같은 Rust SDK가 잘 지원하는 방식은, 동일한 Rust 타입(types)으로부터 모델이 읽을 수 있으면서도 런타임에서 강제되는 도구 계약(tool contracts)을 만드는 것입니다.

이전 기사들에서는 도구의 사용성(usability)을 개선하기 위해 schemars 제약 조건과 deny_unknown_fields를 사용했습니다. 이러한 패턴들은 동일하게 보안 제어(security controls) 역할을 합니다.

  • 타입 안정성(type safety)은 비즈니스 로직이 실행되기 전에 잘못된 형식의 입력을 거부합니다.
  • 범위(range) 및 길이(length) 제약 조건은 명백하게 남용되는 입력을 조기에 거부합니다.
  • 열거형(enums)은 유효한 값의 범위를 좁힙니다.
  • deny_unknown_fields는 선언되지 않은 파라미터가 몰래 들어오는 것을 방지합니다.

이것이 보안의 전부를 말하는 것은 아니지만, 중요한 첫 번째 계층(layer)입니다. 비즈니스 분석가(business analyst)가 유효한 비즈니스 형태를 정의하면, 서버 구현체는 이를 일관되게 강제할 수 있습니다.

#[derive(Debug, Deserialize, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct SalesSummaryInput {
...

이것은 단순한 스키마 장식(schema decoration) 그 이상입니다. 이것은 비즈니스 계약(business contract)입니다. LLM은 도구 탐색(tool discovery) 과정에서 서버가 런타임(runtime)에 강제하는 것과 동일한 구조를 보게 됩니다.

이 지점에서 비즈니스 분석가의 역할이 구체화됩니다. 그들은 Rust 코드를 작성하지는 않지만, 분기(quarters)가 회계 형식(fiscal format)을 따라야 한다는 점, group_by가 자유 텍스트가 아닌 열거형(enum)이어야 한다는 점, 그리고 판매 요약 도구가 결코 제한 없는 결과 집합(unbounded result set)을 반환해서는 안 된다는 점을 결정합니다. 엔지니어는 코드 내에서 해당 계약을 구현합니다. 그러면 훌륭한 MCP 서버는 이를 탐색 가능하고 강제 가능한 인터페이스로 변환합니다.

출력 경계(Output Boundaries)는 대부분의 팀이 생각하는 것보다 더 중요합니다

기업들은 종종 누가 도구를 호출할 수 있는지에만 집중하며, 도구가 무엇을 반환할 수 있는지에 대해서는 투자를 소홀히 합니다. AI 워크로드(workloads)의 경우, 출력 경계(output boundaries) 역시 그만큼 중요합니다.

이것이 MCP가 문서를 직접 업로드하는 것보다 더 안전한 이유 중 하나입니다. 서버는 가공되지 않은 레코드(raw records) 대신 정형화된 결과(shaped result)를 노출할 수 있습니다. 행(rows) 대신 집계(aggregates)를 반환할 수 있습니다. 개인정보(PII) 필드를 완전히 생략할 수 있습니다. 조인(joins)이나 필터링(filtering)에는 유용하지만 모델 컨텍스트(model context)로 다시 방출되어서는 안 되는 값들을 가리거나(redact) 마스킹(mask)할 수 있습니다.

그러한 구분은 code mode article에서 다루는 롱테일(long-tail) 사례에서 중요하게 작용합니다. 데이터베이스 쿼리는 내부 계산이나 조인(join)을 위해 민감한 필드(sensitive fields)를 정당하게 필요로 할 수 있지만, 동시에 해당 필드들이 결과에 나타나는 것은 금지할 수 있습니다.

예를 들어, 코드 모드(code-mode) 정책은 서버 측에서 고객 테이블과 지원 테이블을 조인하는 쿼리를 허용하면서도, 반환되는 페이로드(payload)에 ssn, salary 또는 원본 이메일 주소와 같은 민감한 출력 필드가 나타나는 것은 차단할 수 있습니다. 민감한 필드는 계산에 참여할 수 있지만, 모델에게 노출될 필요는 없습니다.

이는 "스프레드시트를 업로드하고 모델에게 주의해달라고 요청하는 것"보다 훨씬 더 나은 엔터프라이즈 패턴(enterprise pattern)입니다.

동일한 원칙이 코드 모드 외부에도 적용됩니다:

  • 큐레이션된 도구(curated tools)에는 고정된 출력 스키마(fixed output schemas)를 사용하세요. 보안, 개인정보 보호 및 비용(토큰 절약) 측면에서 AI 흐름을 최적화하기 위해 데이터 시스템이 반환하는 데이터의 형태를 제어해야 합니다.
  • 행 덤프(row dumps)보다는 집계(aggregates)를 선호하세요. LLM이 sum이나 기타 통계적 수치를 정확하게 계산할 것이라고 신뢰하지 마세요. 이러한 기호적 계산(symbolic computation)에는 MCP 도구가 훨씬 더 적합합니다.
  • 일관성, 정확성 및 보안을 위해 도구 응답을 실제 비즈니스 질문에 맞게 유지하세요.
  • 답변에 불필요한 필드는 차단하세요.

보안은 단순히 잘못된 요청을 막는 것만이 아닙니다. 설계 단계부터 과도한 공유(oversharing)가 어렵도록 만드는 것이기도 합니다. 부수적인 효과로, 이는 대개 토큰과 처리 시간도 절약해 줍니다.

OAuth가 중요한 이유: 서버가 사용자를 대신하여 동작해야 하기 때문

이것은 AI 에이전틱 워크플로(AI agentics workflows)를 구축할 때 인증(authentication)에 있어 가장 중요한 지점입니다.

기업용 MCP 서버는 단일 공유 애플리케이션 API 키, 단일 데이터베이스 사용자 이름/비밀번호, 또는 모든 최종 사용자에게 동일한 접근 권한을 부여하는 단일 범용 서비스 ID를 사용하여 데이터베이스나 애플리케이션 앞에 위치해서는 안 됩니다. 이는 가장 오래된 기업 보안 실수인 '모든 사용자가 통합 계정의 권한을 갖게 되는 상황'을 재현하는 것입니다.

올바른 패턴은 MCP 클라이언트(client)와 MCP 서버(server)가 인증된 사용자를 대신하여 작동하는 것입니다.

이것이 바로 진지한 MCP 보안 모델에서 OAuth 2.0과 OIDC가 매우 중요한 이유입니다:

  • MCP 클라이언트는 OAuth 흐름과 토큰 갱신(token refresh)을 처리하여, 사용자가 한 번만 로그인하면 액세스 토큰(access token)과 리프레시 토큰(refresh token)의 안전한 관리를 수행할 수 있도록 합니다.
  • MCP 서버는 모든 요청에서 액세스 토큰을 검증하고 사용자 신원(identity), 테넌트 컨텍스트(tenant context), 그룹(groups), 그리고 스코프(scopes)를 추출합니다.
  • 다운스트림 시스템(downstream systems)은 사용자의 액세스 토큰을 전달(pass-through)함으로써, 가능한 한 사용자의 고유한 권한을 강제(enforce)합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0