MCP 접근 정책

MCP 접근 정책 (MCP access policies)

MCP 접근 정책으로 조직 관리자가 Model Context Protocol(MCP) 서버 등록과 에이전트 동작을 어떻게 제어하는지 설명할게요.

출처: 문서

본문

MCP 접근 정책은 조직 관리자가 개발자들이 등록할 수 있는 Model Context Protocol(MCP) 서버와, 에이전트가 Docker의 MCP 게이트웨이를 통해 할 수 있는 일을 제어하게 해요. 이 정책으로 신뢰할 수 있는 서버를 승인하고, 서버 접근을 철회하고, 도구 호출에 승인을 요구하고, 호스트에서 실행되는 서버를 제한할 수 있어요. MCP 서버를 등록하고 샌드박스에 연결하려면 MCP 게이트웨이를 참고하세요.

MCP 접근 정책은 서버 등록과 Docker의 MCP 게이트웨이가 처리하는 요청에만 적용돼요. 에이전트나 MCP 클라이언트가 샌드박스 안에서 직접 구성해 연결하는 MCP 서버는 이 정책이 통제하지 않아요. 원격 MCP 서버로의 직접 연결은 아웃바운드 샌드박스 트래픽이므로, 네트워크 접근 정책이 샌드박스가 그 서버에 도달할 수 있는지 결정해요. 두 경로를 모두 막으려면 MCP 접근 정책에서 서버를 차단하고, 네트워크 접근 정책에서 그 네트워크 대상을 차단하세요.

네트워크 접근 정책이나 파일시스템 접근 정책과 달리, MCP 정책은 Cedar로 작성된 organization 정책이에요. Docker가 MCP 네임스페이스를 정의하며, 여기에는 정책이 매칭할 수 있는 액션, 리소스 타입, 속성, 승인 동작이 포함돼요. 이 페이지는 대표적인 접근 패턴에 초점을 맞춰요. Docker의 정확한 정책 표면은 MCP 정책 참조를, Cedar 문법과 언어 의미론은 Cedar 문서를 참고하세요.

서버 수명주기 통제 (Govern the server lifecycle)

MCP 정책은 서버 수명주기의 두 지점에 적용돼요. 한 지점에 대한 규칙이 다른 지점을 자동으로 통제하지는 않아요.

관리자 결정 평가 지점 매칭 대상
서버를 등록할 수 있는지 개발자가 sbx mcp add를 실행할 때 등록된 이름과 해석된 서버 속성(예: identityURL)
에이전트가 MCP 게이트웨이를 통해 할 수 있는 일 게이트웨이가 통제 대상 요청을 처리할 때 등록된 서버 이름, 도구 어노테이션, 리소스 URI, 또는 프롬프트 이름

등록 규칙은 향후 등록에 영향을 줘요. 저장된 등록을 제거하거나, sbx mcp load로 기존 등록이 로드되는 것을 막지는 않아요. 사용 시점 규칙은 이미 등록되거나 로드된 서버에서의 도구 호출, 리소스 읽기, 프롬프트 조회를 통제해요.

서버 이름은 등록 시 선택돼요. 등록 규칙은 선택한 이름과 해석된 서버 정체성(identity)을 함께 매칭할 수 있어요. 사용 시점에는 도구, 리소스, 프롬프트가 등록된 이름과 연결되므로, 기존 서버에 대한 규칙은 그 서버가 등록된 모든 이름을 매칭해야 해요.

mcp-add, code-mode, OAuth 인증 헬퍼 같은 내장 게이트웨이 도구도 사용 시점에 통제돼요. 이들은 등록된 서버와 연결된 도구가 아니라 MCP::Primordial 리소스예요. 자세한 내용은 내장 게이트웨이 도구를 참고하세요.

사용 시점 정책은 기존 등록을 숨기거나 제거하지 않아요. 도구와 리소스 목록에는 에이전트가 사용하려 할 때 정책이 거부하는 항목도 포함될 수 있어요.

접근 태세 선택 (Choose an access posture)

사용자에 대해 MCP 정책 시행이 활성화되면, 매칭되는 permit이 허용하지 않는 한 등록과 통제 대상 MCP 요청은 거부돼요. 매칭되는 forbid는 @requireApproval이 붙은 permit을 포함해 어떤 permit보다 우선해요.

허용목록(allowlist) 정책에는 permit을 쓰세요. 명시적 제한을 제외한 MCP 활동을 허용하는 차단목록(blocklist) 정책을 만들려면 액션 없는 permit으로 시작하세요:

permit (principal, action, resource);

이 문은 Cedar 평가에 도달하는 모든 MCP 액션을 허용해요. 정책이 시행해야 하는 제한에 대해 forbid 문을 추가하세요.

정책 스코프가 principal을 제공해요. Cedar에서 사용자, 팀, 테넌트, 역할을 매칭하는 대신 organization이나 team 스코프를 사용하세요. 사용자에 대해 MCP 정책 시행이 활성화되지 않으면 게이트웨이는 Cedar 정책을 평가하지 않고 MCP 활동을 허용해요. MCP에는 네트워크 정책과 같은 로컬 프리셋이 없어요.

서버 승인 (Approve a server)

허용목록의 경우 서버 등록과 사용 시점 기능을 모두 승인하세요. 다음 정책은 원격 서버가 예상 identity URL로 example이라는 이름으로 등록된 경우에만 승인해요. 그 등록된 서버에서 읽기 전용 도구 호출, 리소스 읽기, 프롬프트 조회를 허용해요:

// Permit registration with the expected name and identity URL.
permit (principal, action == MCP::Action::"register", resource)
when {
  resource in MCP::Server::"example" &&
  resource.identityURL == "https://mcp.example.com/mcp"
};

// Permit read-only tool calls.
permit (principal, action == MCP::Action::"invokeTool", resource)
when {
  resource in MCP::Server::"example" &&
  resource.readOnly == true
};

// Permit resource reads.
permit (principal, action == MCP::Action::"readResource", resource)
when { resource in MCP::Server::"example" };

// Permit prompt retrieval.
permit (principal, action == MCP::Action::"getPrompt", resource)
when { resource in MCP::Server::"example" };

이름과 identity URL을 모두 매칭하면 정규 등록이 확립돼요. 개발자가 승인된 이름으로 다른 엔드포인트를 등록하거나, 승인된 엔드포인트를 다른 이름으로 등록하는 것을 막아요. 사용자가 그 기능이 필요 없다면 리소스나 프롬프트 permit을 제거하세요.

MCP elicitation으로 확인 요구 (Require confirmation with MCP elicitation)

@requireApproval을 사용하면 MCP를 통해 요청별 확인을 요구해요. 요청이 어노테이션된 permit과 매칭되면, 게이트웨이는 통제 대상 요청을 보낸 동일한 MCP 클라이언트 세션에 elicitation/create 요청을 보내요. 사람이 조작하는 클라이언트에서는 에이전트를 조작하는 사람이 프롬프트를 보고 계속할지 결정해요.

다음 정책은 example로 등록된 서버의 읽기 전용이 아닌 도구에 대해 확인을 요구해요. 서버 등록이나 다른 기능 사용에 필요한 permit과 함께 사용하세요. 어노테이션 문자열은 elicitation에 표시되는 이유가 돼요:

@requireApproval("non-read-only tool call")
permit (principal, action == MCP::Action::"invokeTool", resource)
when {
  resource in MCP::Server::"example" &&
  resource.readOnly == false
};

도구 어노테이션은 서버가 제공하며 참고용(advisory)이에요. readOnly는 선언하지 않은 도구에 대해 기본값 false이므로, 이 패턴은 어노테이션이 없는 도구에 대해 확인을 요구해요.

게이트웨이는 매칭되는 요청을 다음과 같이 처리해요:

flowchart TD
  request["Agent sends a governed MCP request"] --> evaluate["Gateway evaluates MCP policy"]
  evaluate -->|"Normal permit"| forward["Forward request"]
  evaluate -->|"No permit or matching forbid"| deny["Deny request"]
  evaluate -->|"Permit with @requireApproval"| elicit["Send MCP elicitation to connected client"]
  elicit --> confirm{"Client returns explicit confirmation?"}
  confirm -->|"No, unsupported, or error"| deny
  confirm -->|"Yes"| reevaluate["Re-evaluate with approval digest"]
  reevaluate -->|"Allowed"| forward
  reevaluate -->|"Denied or changed"| deny

프롬프트는 서버나 게이트웨이 도구를 식별하고 어노테이션 이유를 포함해요. 원시 도구 인자는 포함하지 않아요. 매칭되는 요청마다 새 확인이 필요해요. 확인 후 게이트웨이는 응답을 평가된 인증 요청에 바인딩하는 다이제스트로 요청을 다시 평가해요.

이 메커니즘을 사람이 조작하는 클라이언트를 위한 확인 가드레일로 사용하세요. 관리자 승인이나 직무 분리를 만들어 주지는 않아요. 자율 MCP 클라이언트는 in-protocol elicitation에 프로그래밍 방식으로 응답할 수 있어요. 절대 실행되면 안 되는 작업에는 forbid를 사용하세요.

원래 클라이언트 세션이 MCP elicitation을 처리할 수 없거나, 사용자가 거절하거나, elicitation이 실패하거나, 재평가가 요청을 허용하지 않으면 요청은 거부돼요. sbx mcp add는 elicitation을 표시할 수 없으므로 @requireApproval이 붙은 등록 permit은 거부로 이어져요. code-mode 안에서의 호출을 포함해 elicitation을 중계할 수 없는 실행 컨텍스트에서 이루어진 도구 호출도 거부돼요.

서버 접근 철회 (Withdraw server access)

더 넓은 규칙이 허용하는 서버의 접근을 철회하려면 등록 시점과 사용 시점 모두에서 차단하세요. 등록 정책은 향후 sbx mcp add 작업을 통제하고, 사용 시점 정책은 이미 등록되거나 로드된 서버의 요청을 통제해요.

identity URL을 매칭해 서버의 향후 등록을 막으세요:

forbid (principal, action == MCP::Action::"register", resource)
when { resource.identityURL == "https://mcp.example.com/mcp" };

서버를 가리키는 각 등록된 이름에 대해 사용 시점 요청을 거부하세요:

forbid (principal, action == MCP::Action::"invokeTool", resource)
when { resource in MCP::Server::"example" };

forbid (principal, action == MCP::Action::"readResource", resource)
when { resource in MCP::Server::"example" };

forbid (principal, action == MCP::Action::"getPrompt", resource)
when { resource in MCP::Server::"example" };

등록은 저장된 채로 남아 계속 나열되거나 로드될 수 있어요. 이 규칙들은 identity URL에 대한 추가 등록을 막고, 등록된 이름 아래의 통제 대상 사용을 거부해요. 서버가 다른 이름으로도 등록되어 있다면 그 이름들에 대해 사용 시점 규칙을 추가하세요.

OAuth 인증 헬퍼는 등록된 서버의 자식이 아니라 내장 게이트웨이 도구예요. 에이전트가 서버에 대한 인증을 시작하지 못하게 하려면 헬퍼를 별도로 통제하세요:

forbid (principal, action == MCP::Action::"invokePrimordial", resource)
when { resource in MCP::Primordial::"example-authorize" };

호스트 실행 서버 제한 (Restrict host-run servers)

Local stdio 서버는 샌드박스 VM 밖인 호스트에서 실행돼요. 여기에는 명시적 호스트 명령과 호스트 Docker로 시작한 OCI 패키징 stdio 서버가 포함돼요. 이 경계에 대한 자세한 내용은 Docker Engine 격리를 참고하세요.

등록을 달리 허용하는 차단목록 정책에서는 호스트 실행 서버 타입을 거부하세요:

forbid (principal, action == MCP::Action::"register", resource)
when { resource.type == "local-stdio" };

local-stdio는 Docker 컨테이너를 시작하는 명령을 포함한 명시적 명령과, --local로 레지스트리나 매니페스트 메타데이터에서 해석된 OCI 패키징 stdio 서버를 다뤄요.

더 알아보기 (Learn more)