NVIDIA AI Agent 안전 플랫폼: OpenShell과 Sentry는 JSON Tool Call을 어떻게 제한하나
모델은 JSON만 채운다. 2026년 9월 28일 NVIDIA는 경계를 모델 밖에 두었다. OpenShell은 샌드박스 프록시에서 tools/call의 도구 이름을 본다. Sentry는 BlueField-4에서 대역 밖으로 격리한다. lookup_order를 허용해도 임의의 order_id를 허용하는 것은 아니다.
읽기 전 요약
| 층 | 공식 사실 | 무엇이 호출을 막나 |
|---|---|---|
| OpenShell | Apache 2.0. 샌드박스와 커널 격리. 프록시는 샌드박스가 MCP 서버로 보내는 요청 본문을 검사한다 | 도구 이름으로 allow / deny. 인자는 맞추지 않는다 |
| Sentry | BlueField-4의 대역 밖 워치독. 소프트웨어 경계를 벗어나면 밀리초 안에 격리한다. 참조 설계이며 선택 | 하드웨어가 실행을 멈춘다. JSON을 채우지 않는다 |
| 정책 증명 | 게이트웨이의 prover. 새 자격 증명 도달, 새 HTTP 메서드, 클라우드 메타데이터는 자동 승인을 막는다 | 정책 변경 전. 실행 시 Schema가 아니다 |
| 호스트 Schema | 문서: 허용된 도구는 아무 인자나 받는다 | 실행 전에 arguments를 검증한다 |
사실은 2026-09-28 NVIDIA 뉴스, 기술 블로그, OpenShell 정책 문서. 주문 A-1042는 허구. 아래 JSON은 문서 YAML과 같은 필드이며, 공개되지 않은 Sentry 와이어 형식이 아니다.
OpenShell은 도구 이름을 막고, Sentry는 경계를 넘은 실행을 막는다
Open Agent Safety Platform은 두 조각이다. 채팅 권한을 하나 더 얹은 것이 아니다. 첫째는 OpenShell이다. Apache 2.0이고 널리 쓸 수 있다. CPU 위의 Agent를 샌드박스에 넣는다. 커널이 파일, 시스템 호출, 네트워크를 묶고, 프록시가 샌드박스를 떠나는 HTTP를 본다. MCP 엔드포인트는 protocol: mcp를 쓴다. 샌드박스가 서버로 보내는 요청 본문을 검사하고, 메서드와 tools/call 도구 이름으로 허용하거나 거부한다. 둘째는 Sentry다. 참조 설계다. BlueField-4 DPU에서, 대역 밖에서, Agent가 닿지 않는 곳에서 돈다. Agent가 소프트웨어 경계를 벗어나면 Sentry가 밀리초 안에 격리하고 멈춘다. Vera Rubin POD에서 이 DPU는 노드에서 모델로 가는 유일한 경로 위에 있다. 셋째, 인자는 이 두 층에 없다. OpenShell은 도구 인자 매칭을 아직 지원하지 않으며, 허용된 도구는 서버가 받는 아무 인자나 받는다고 적는다.
- OpenShell:
lookup_order는 허용할 수 있다.refund_order는deny_rules에 넣는다. - Sentry: 선택적 하드웨어 층. 상호작용, 정책 결정, 도구 접근을 묶고 신원을 확인한다. 도구 목록을 대체하지 않는다.
- 호스트:
A-1042가 합법한지는 여전히 Schema로arguments를 본다.
세션 안의 allow / ask / deny는 다른 문이다. Coding Agent 권한 모델. MCP tools/call의 모양은 Coding Agent가 MCP를 부르는 방법. 랩이 평가 환경을 벗어난 사건은 이미 썼다. Agent 안전 위기와 JSON 검증. 이 글은 그 사건을 다시 쓰지 않는다. OpenShell과 Sentry가 한 번의 도구 호출을 어떻게 막는지 나눈다.
프록시가 보는 것은 tools/call이지, 모델의 산문이 아니다
OpenShell이 파싱하는 것은 샌드박스 프로세스가 MCP 엔드포인트로 보내는 JSON-RPC 요청이다. 허구 주문. 호스트 이름은 orders.example.com:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "lookup_order",
"arguments": { "order_id": "A-1042" }
}
}
맞추는 것은 method와 params.name이다. 기본으로 도구 이름은 ^[A-Za-z0-9_.-]{1,128}$에도 맞아야 한다. 이 스위치가 mcp.strict_tool_names이고 기본은 true다. 와일드카드 tool 매처는 이 스위치를 켠 채로 둔다. arguments 안의 order_id는 이 정책에 들어가지 않는다. JSON-RPC 응답과, 응답 본문이나 SSE에서 서버가 클라이언트로 보내는 MCP 메시지는 중계되며 지금은 정책을 파싱하지 않는다. 배치의 한 호출이 거부되면 배치 전체가 거부된다.
정책은 도구 이름으로 쓰고, 인자는 다른 문에 둔다
문서가 주는 것은 YAML이고, openshell policy set으로 통째로 넣는다. 증분 policy update --add-endpoint는 아직 mcp를 받지 않는다. 아래는 같은 필드의 JSON이라 Diff하기 쉽다. 조회는 허용, 환불은 거부. mcp.allow_all_known_mcp_methods 기본값은 false라 메서드를 하나씩 적는다. mcp.versions를 빼면 허용되는 개정은 2025-11-25뿐이다:
{
"version": 1,
"network_policies": {
"orders": {
"name": "orders",
"endpoints": [{
"host": "orders.example.com",
"port": 443,
"path": "/mcp",
"protocol": "mcp",
"enforcement": "enforce",
"mcp": {
"strict_tool_names": true,
"max_body_bytes": 65536
},
"rules": [
{ "allow": { "method": "initialize" } },
{ "allow": { "method": "notifications/initialized" } },
{ "allow": { "method": "tools/list" } },
{ "allow": { "method": "tools/call", "tool": "lookup_order" } }
],
"deny_rules": [
{ "method": "tools/call", "tool": "refund_order" }
]
}],
"binaries": [{ "path": "/usr/bin/python3" }]
}
}
}
filesystem_policy와 landlock는 샌드박스 생성 때 잠긴다. network_policies는 핫 리로드할 수 있다. 바이너리 경로도 적는다. 어느 프로그램이 어느 엔드포인트에 닿는가이다. 아웃바운드는 기본적으로 사설망을 허용하지 않고, 루프백, 링크 로컬, 클라우드 메타데이터 주소도 인가하지 않는다. lookup_order를 허용한 뒤의 인자 문은 호스트에 있다:
{
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
},
"required": ["order_id"],
"additionalProperties": false
}
이 Schema는 OpenShell 필드가 아니다. 프록시가 도구 이름을 허용한 뒤에도 호스트는 빠진 필드, 여분 필드, A-1042 모양이 아닌 order_id를 거부한다. Schema가 문인 이유는 AI가 JSON Schema를 필요로 하는 이유.
네 문을 하나로 합치지 않는다
모두 안전이라고 불린다. 보는 대상은 다르다:
| 문 | 무엇을 보나 |
|---|---|
| OpenShell 프록시 | 샌드박스에서 orders.example.com:443/mcp로 가는 요청. 메서드, 도구 이름, 호출한 바이너리. arguments는 보지 않는다. |
| 호스트 Schema | lookup_order의 인자. 타입, 필수, pattern. 문을 통과한 뒤 실행한다. |
| Coding Agent의 allow / ask / deny | 세션 안의 Shell, Git, 파일 도구. 그것은 harness의 명단이다. OpenShell은 샌드박스 밖의 다른 층이다. |
| Sentry | BlueField-4 위의 대역 밖 실행. 경계를 넘으면 격리한다. 공개 자료에 Sentry JSON 필드 표는 없다. 이 정책 객체를 그 표로 쓰지 않는다. |
정책 변경은 적용 전에 prover도 통과할 수 있다. 새 자격 증명 도달, 새 HTTP 메서드, 클라우드 메타데이터 접근을 표시한다. 발견이 있으면 자동 승인하지 않는다. 명령은 openshell-prover이고 CI에 둘 수 있다. Agent는 Policy Advisor로 좁은 제안만 낸다. 승인은 샌드박스 밖에서 한다. 루프와 상태가 어디에 앉는지는 Agent Harness와 JSON State.
규칙을 넓히기 전 여섯 단계
Sentry를 먼저 켜지 않는다. 어느 호출을 어느 층이 막았는지 먼저 적는다:
- 모델 JSON과 런타임 정책을 나눈다. 모델은
params.name을 채운다. OpenShell이 그 이름이 샌드박스를 떠날 수 있는지 정한다. - 샌드박스를 만들 때 파일시스템과 Landlock을 적는다. 이 둘은 네트워크 규칙처럼 핫 리로드되지 않는다.
- MCP 엔드포인트를 채운다.
host,port,path: /mcp,protocol: mcp,enforcement: enforce. 다른 프로토콜과 그 호스트와 포트를 공유하지 않는다. - 도구 이름을 하나씩 적는다.
initialize,notifications/initialized,tools/list, 그다음tools/call에lookup_order.refund_order는deny_rules.strict_tool_names는 true로 둔다. - 인자는 호스트 Schema에 넘긴다. 프록시는
order_id를 읽지 않는다. 이미 허용된 도구의 인자에 환불을 넣어도 이 층은 보지 않는다. - 넓히기 전에 Diff하고 prover를 돌린다. Sentry는 BlueField-4의 선택 층이다. 그 DPU가 없으면 격리를 이미 일어난 일로 쓰지 않는다.
JSON-RPC 배치에서 한 호출이 거부되면 배치 전체가 거부된다. 조회와 환불을 같은 배치에서 시험하지 않는다. 서버 응답은 이 정책 밖에 있다.
규칙을 넓히기 전에 객체 세 벌을 펼친다
거부는 도구 이름, 바이너리 경로, 호스트와 포트, 또는 인자 모양이다. 프롬프트를 고치기 전에 나눈다.
tools/call과 정책을 포맷하고, Schema 검증로arguments가 문을 통과하는지 본다.- JSONPath 추출로
$.params.name,$.method,$.arguments.order_id를 뽑는다. - 넓히기 전과 후의
network_policies를 JSON Diff한다. 프롬프트보다 먼저 새로 생긴 tool을 본다. - 샌드박스 로그는 거부된 host, path, binary를 보여 준다.
openshell logs --tail --source sandbox. - 로그의 토큰은 먼저 가리기. 주문과 비밀을 공개 포매터에 붙이지 않는다. JSONSort는 브라우저 로컬에서 돈다.
세 객체가 맞으면 refund_order를 막은 층이 보인다. Sentry 격리 기록은 이 세 JSON에 없다.
흔한 실수
- OpenShell을 세션의 allow / ask / deny로 여긴다. 그것은 harness의 명단이다. OpenShell은 샌드박스 프록시와 커널이다. 두 정책을 남긴다.
- 도구 이름을 허용했으니 order_id도 검사했다고 생각한다. 문서는 인자 매칭이 아직 없다고 적는다. 호스트 Schema는 빼지 않는다.
- 모델 응답만 검사한다. 프록시가 보는 것은 MCP 엔드포인트로 보내는 요청 본문이다. 응답과 SSE는 지금 파싱하지 않는다.
- 샌드박스가 자기 정책을 승인하게 둔다. Policy Advisor는 제안만 낸다. 승인은 샌드박스 밖이다. prover에 발견이 있으면 자동 승인하지 않는다.
- Sentry를 JSON Schema로 쓴다. 공개 자료가 적는 것은 BlueField-4의 대역 밖 격리와 상관 기록이다. 필드 표가 없으면 만들지 않는다.
- 이 글로 탈출 사건을 다시 쓴다. 그 사건은 이미 사이트에 있다. 여기서는 경계가 한 번의
tools/call을 어떻게 막는지 적는다.
FAQ
Sentry가 OpenShell을 대신할 수 있나?
없다. OpenShell은 소프트웨어 런타임이다. 샌드박스, 커널, 아웃바운드 정책을 맡는다. Sentry는 BlueField-4의 선택적 대역 밖 층이고, 경계를 넘으면 밀리초 안에 격리한다. 그 DPU가 없으면 OpenShell 층만 있다. 둘 다 모델 밖에 있다.
프록시가 tools/call 인자를 읽나?
읽지 않는다. 메서드와 도구 이름을 맞춘다. 허용된 도구는 아무 인자나 받는다. 배치의 한 호출이 거부되면 전체가 거부된다. 인자 모양은 호스트 Schema가 다시 검증한다.
이것은 Cursor나 Claude Code 권한 파일과 같은가?
아니다. 그 파일은 세션 안의 Shell, Git, 파일 도구를 실행할지를 정한다. OpenShell은 샌드박스 안의 어느 바이너리가 어느 호스트와 포트로 MCP 요청을 보낼지를 정한다. 하나는 harness 안이고, 하나는 샌드박스 경계다.
prover는 무엇을 막나?
정책이 적용되기 전에 형식 검증을 한다. 새 자격 증명 도달, 새 HTTP 메서드, 클라우드 메타데이터 접근을 표시하고, 발견이 있으면 자동 승인하지 않는다. 실행 시 도구 이름 규칙이나 Schema를 대신하지 않는다.
서버의 MCP 응답도 정책으로 거르나?
현재 문서에서는 거르지 않는다. JSON-RPC 응답과, 응답 본문이나 SSE의 서버에서 클라이언트로 가는 MCP 메시지는 정책 파싱 없이 중계된다. 검사할 것은 샌드박스를 떠나는 요청이다.
결론
NVIDIA의 이 플랫폼은 도구 호출의 경계를 모델 밖에 둔다. OpenShell은 MCP 도구 이름으로 허용하거나 거부한다. Sentry는 BlueField-4에서 경계를 넘은 실행을 격리한다. 인자는 호스트가 Schema로 검증한다.
lookup_order는 rules에, refund_order는 deny_rules에, A-1042는 호스트 Schema에 있다고 먼저 적는다. 세 곳이 맞으면 이 호출은 제한된 것이다.
이어서 읽기
- Coding Agent 권한 모델 allow / ask / deny는 샌드박스와 같은 층이 아니다
- Coding Agent는 MCP를 어떻게 부르나 tools/call의 JSON-RPC 모양
- Agent 안전 위기와 JSON 검증 사건은 이미 썼다. 이 글은 다시 쓰지 않는다
- Agent Harness와 JSON State 루프, 문, 상태
- AI는 왜 JSON Schema가 필요한가 Schema는 문이다
- JSONSort 로컬 도구 포맷, 검증, Diff, Schema
- 모든 글 JSON과 AI 개발에 대한 다른 노트
변경 기록: 처음 게시