본문으로 건너뛰기

정책

정책은 가드레일 계층입니다. 샌드박스 안의 에이전트가 어떤 명령과 기능을 즉시 실행할 수 있는지, 먼저 확인해야 하는지, 절대 실행할 수 없는지를 결정합니다. defineSandboxPolicy()는 이러한 규칙을 이식 가능한 방식으로 한 번 설명하며, 각 provider의 하네스 어댑터가 이를 자체 네이티브 권한 시스템에 매핑합니다. defineSandbox({ policy })를 통해 샌드박스에 정책을 연결하면, workspace 설정과 연결된 tools가 실행하는 명령을 정책이 보호합니다.

import { defineSandboxPolicy, defineSandbox } from '@tanstack/ai-sandbox'
import { dockerSandbox } from '@tanstack/ai-sandbox-docker'

const policy = defineSandboxPolicy({
commands: {
allow: ['pnpm test', 'pnpm typecheck', 'git diff'],
ask: ['pnpm install', 'curl *'],
deny: ['sudo *', 'rm -rf *'],
},
capabilities: { fileWrite: 'allow', network: 'ask' },
default: 'ask',
})

const sandbox = defineSandbox({
id: 'repo-agent',
provider: dockerSandbox({ image: 'node:22' }),
policy,
})

결정

모든 명령 또는 기능은 다음 세 가지 결정 중 하나로 해석됩니다.

결정의미
allow에이전트가 인터럽트 없이 실행합니다.
ask에이전트가 일시 중지되고, 작업을 진행하기 전에 클라이언트가 답할 승인 요청을 하네스가 내보냅니다.
deny작업이 즉시 차단됩니다. 에이전트가 실행할 수 없습니다.

명령

commands에는 명령 패턴 목록 세 가지인 allow, ask, deny가 들어갑니다. 패턴은 에이전트가 실행하려는 명령과 일치합니다.

import { defineSandboxPolicy } from '@tanstack/ai-sandbox'

const policy = defineSandboxPolicy({
commands: {
allow: ['pnpm test', 'pnpm typecheck', 'git diff'],
ask: ['pnpm install', 'curl *'],
deny: ['sudo *', 'rm -rf *'],
},
})

글로브 패턴

패턴은 * 글로브를 지원하므로 하나의 항목으로 전체 명령군을 제어할 수 있습니다. curl *는 모든 curl 호출과 일치하고, sudo *sudo를 통해 실행되는 모든 항목과 일치합니다. pnpm test와 같은 정확한 문자열은 해당 명령에만 일치합니다. allow 목록에는 이름이 지정된 워크스페이스 스크립트 (pnpm test, pnpm build)를 우선 사용합니다. 이렇게 하면 자유 형식 셸 대신 정책이 일치시킬 안정적인 이름을 제공할 수 있습니다.

기능

capabilities는 개별 명령이 아니라 파일 시스템 쓰기나 외부 네트워크 액세스 같은 대략적인 기능에 동일한 allow / ask / deny 결정을 적용합니다.

import { defineSandboxPolicy } from '@tanstack/ai-sandbox'

const policy = defineSandboxPolicy({
capabilities: {
fileWrite: 'allow', // let the agent edit the working tree freely
network: 'ask', // pause for approval before any outbound request
},
})

이는 광범위한 최종 방어선입니다. 특정 네트워크 명령이 commands 목록에 없더라도 network: 'ask'는 외부로 연결되는 모든 작업에 승인을 요구합니다.

일부 provider는 network: 'deny'인 경우 생성 시에도 네트워크를 적용합니다. 매핑은 Providers를 참조합니다.

Docker Sandboxes의 네트워크 정책

대부분의 provider는 capabilities.network 적용을 하네스에 맡깁니다. sbxSandbox()는 호스트 HTTP/HTTPS 프록시에서도 이를 적용합니다(networkPolicy: true).

sbx policy는 호스트를 허용하거나 거부할 수 있습니다. ask는 없습니다. 거부가 허용보다 우선하므로 network: 'deny'는 전체 거부가 아니라 허용 목록입니다.

TanStack capabilities.networksbxSandbox()가 작성하는 내용
정책 없음 및 allowNetwork / denyNetwork 없음정책 목록이 비어 있으면 sbxSandbox()sbx policy init deny-all을 실행합니다. 그런 다음 알려진 어댑터(grok-build, claude-code, codex)는 해당 deny-all 위에 모델 API 호스트와 localhost를 샌드박스별 허용 항목으로 작성합니다. 알려지지 않은 어댑터는 머신 사전 설정을 유지합니다.
정책 없음 및 allowNetwork모델 API 호스트(어댑터가 알려진 경우), localhost, allowNetwork를 샌드박스별로 허용한 다음 denyNetwork를 적용합니다.
정책 없음 및 denyNetwork만 있음해당 호스트를 샌드박스별로 거부합니다. 허용 목록은 비어 있습니다. 자동 호스트와 localhost는 없습니다. 이는 머신 사전 설정에 추가로 적용되는 거부입니다.
allow**를 허용한 다음 denyNetwork를 적용합니다.
deny모델 API 호스트, localhost, allowNetwork를 허용한 다음 denyNetwork를 적용합니다.
ask (또는 network가 설정되지 않았을 때 정책의 default)deny와 동일한 허용 목록을 사용합니다. 하네스는 여전히 도구와 명령에 대해 묻습니다.

자동으로 허용되는 모델 호스트:

  • grok-buildapi.x.ai
  • claude-codeapi.anthropic.com
  • codexapi.openai.com
  • opencode 또는 알려지지 않은 어댑터 → 없음

deny 또는 ask에서 허용 목록이 비게 되면 생성 시 오류가 발생합니다. allowNetwork를 전달하거나 grokBuildText / claudeCodeText / codexText를 사용합니다.

게스트는 도구 브리지를 위해 계속 host.docker.internal에 연결합니다. sbx 프록시는 정책이 일치하기 전에 해당 호스트를 localhost로 다시 씁니다. sbxSandbox()는 실제 허용 목록을 작성할 때 localhost를 추가합니다. denyNetwork만 사용하는 경우에는 localhost를 추가하지 않습니다.

import { sbxSandbox } from '@tanstack/ai-sandbox-docker'
import { defineSandbox, defineSandboxPolicy } from '@tanstack/ai-sandbox'

const sandbox = defineSandbox({
id: 'repo-agent',
provider: sbxSandbox({
allowNetwork: ['*.npmjs.org', 'registry.npmjs.org'],
}),
policy: defineSandboxPolicy({
capabilities: { network: 'deny' },
commands: { allow: ['pnpm test'], deny: ['sudo *'] },
}),
})

명령 규칙과 fileWrite는 하네스가 계속 처리합니다. sbx는 명령줄을 확인하지 않습니다.

우선순위: deny > ask > allow

둘 이상의 규칙이 작업과 일치할 수 있으면 가장 엄격한 규칙이 우선합니다. 순서는 deny > ask > allow:

  • 일치하는 규칙 중 하나라도 deny이면 작업이 차단되며 다른 규칙이 이를 재정의할 수 없습니다.
  • 그렇지 않고 일치하는 규칙 중 하나라도 ask이면 작업에 승인이 필요합니다.
  • 그렇지 않고 규칙이 allow이면 작업을 실행합니다.
  • 일치하는 항목이 없으면 default 결정이 적용됩니다.
import { defineSandboxPolicy } from '@tanstack/ai-sandbox'

const policy = defineSandboxPolicy({
commands: {
// `curl` is allowed broadly…
allow: ['curl *'],
// …but `deny` wins, so this specific host is always blocked.
deny: ['curl * internal.example.com*'],
},
default: 'deny',
})

따라서 광범위한 allow를 설정하고 더 좁은 ask / deny 패턴으로 예외를 만들 수 있으며, 예외가 우선 적용된다는 확신을 가질 수 있습니다.

기본값

default는 어떤 규칙과도 일치하지 않는 항목에 적용되는 결정입니다. 경계에서 원하는 보안 태세로 설정합니다.

  • default: 'allow'는 허용적입니다. 명시적으로 ask하거나 deny한 항목만 제어합니다. 신뢰할 수 있는 개발 루프에 적합합니다.
  • default: 'ask'는 신중한 설정입니다. 알 수 없는 작업은 승인을 위해 일시 중지됩니다. 적절한 중간 지점입니다.
  • default: 'deny'는 잠금 상태입니다. 에이전트는 명시적으로 allow한 항목만 실행할 수 있습니다. 신뢰할 수 없거나 프로덕션에서 실행할 때 가장 강력한 설정입니다.

생략하면 기본값을 ask로 처리하여 예상하지 못한 작업이 조용히 실행되지 않고 표시되도록 합니다.

ask가 표시되는 방식

ask 결정은 SDK가 추측하는 것이 아니라 사용자에게 전달되는 질문입니다. 에이전트가 ask로 제어되는 작업을 시도하면 하네스가 에이전트를 일시 중지하고 실행 스트림에 승인 요청을 내보냅니다. 클라이언트가 해당 요청에 답하면(승인 또는 거부), 하네스는 응답에 따라 작업을 진행시키거나 차단합니다. 클라이언트가 응답할 때까지 작업은 보류됩니다.

따라서 일반적으로는 괜찮지만 때때로 위험한 작업(pnpm install로 새 의존성을 가져오는 작업이나 외부로 나가는 curl)에는 ask가 적합합니다. 안전한 명령을 처음부터 모두 열거하지 않아도 사람이 루프에 참여할 수 있습니다.

어댑터가 정책을 매핑하는 방식

정책은 이식 가능합니다. 각 하네스 어댑터는 동일한 allow / ask / deny 설명을 자체 네이티브 권한 시스템으로 변환합니다.

  • Grok Build 하네스는 이를 grok CLI의 권한 플래그에 매핑합니다.
  • Claude Code 하네스는 이를 Claude Code의 권한 규칙(허용/ask/거부 도구 및 명령 규칙)에 매핑합니다.
  • Codex 하네스는 이를 Codex의 승인 및 샌드박스 설정에 매핑합니다.
  • 다른 하네스는 자신이 제공하는 네이티브 제어 수단에 매핑합니다.

하네스가 특정 규칙을 표현할 수 없으면 실행에 실패하는 대신 기능을 축소하며, 지원되지 않는 규칙은 오류를 발생시키지 않고 경고와 함께 건너뜁니다. 매핑은 어댑터의 역할이므로 정책을 한 번만 작성하면 어떤 provider 또는 하네스가 샌드박스를 실행하든 일관되게 동작합니다.

default: 'allow'인 거부 전용 목록은 Grok Build와 Codex에서 허용적으로 유지됩니다. 이러한 하네스는 자동 승인을 유지하며 commands.deny를 적용하지 않습니다. 격리는 외부 샌드박스가 담당합니다. 명령 수준의 거부가 필요하면 Claude Code를 사용합니다.

일부 provider는 루트가 아닌 사용자로 실행되므로 setup의 패키지 설치에 sudo가 필요합니다. 이러한 provider에서 sudo *를 거부하지 않습니다. 목록은 Providers를, 설정 명령 작성 방법은 Workspace를 참조합니다.

연결하기

정책은 그 자체로는 아무 작업도 하지 않으며, 샌드박스에 연결할 때 적용됩니다. defineSandboxpolicy로 전달하면 해당 샌드박스를 사용하는 모든 실행을 보호합니다. 여기에는 workspace 설정 명령과 에이전트에 연결된 모든 호스트 tools가 포함됩니다.

import { defineSandboxPolicy, defineSandbox, defineWorkspace, githubRepo } from '@tanstack/ai-sandbox'
import { dockerSandbox } from '@tanstack/ai-sandbox-docker'

const policy = defineSandboxPolicy({
commands: {
allow: ['pnpm test', 'pnpm typecheck', 'git diff'],
ask: ['pnpm install', 'curl *'],
deny: ['sudo *', 'rm -rf *'],
},
capabilities: { fileWrite: 'allow', network: 'ask' },
default: 'ask',
})

const sandbox = defineSandbox({
id: 'repo-agent',
provider: dockerSandbox({ image: 'node:22' }),
workspace: defineWorkspace({
source: githubRepo({ repo: 'owner/app' }),
setup: ['corepack enable', 'pnpm install'],
}),
policy,
})

다음 단계

  • Providers, defineSandbox를 통해 정책을 연결하는 방법입니다.
  • Workspace, 정책이 보호하는 설정 명령과 스크립트입니다.
  • Tools, 에이전트에 연결된 호스트 도구가 동일한 정책으로 실행되는 방식입니다.
  • Lifecycle, 보호된 샌드박스가 재개되고 종료되는 방식입니다.