● Overview κ°œμš”

Sandboxed Bash replaces the standard root-session bash tool with a sandboxed execution layer. Every shell command passes through a policy engine and a platform-specific isolation adapter before reaching the host. If no sandbox tool is available on the current platform, the system falls back to unsandboxed execution with explicit user approval.

μƒŒλ“œλ°•μŠ€ BashλŠ” ν‘œμ€€ root-session bash 도ꡬλ₯Ό μƒŒλ“œλ°•μŠ€ μ‹€ν–‰ λ ˆμ΄μ–΄λ‘œ κ΅μ²΄ν•©λ‹ˆλ‹€. λͺ¨λ“  μ…Έ λͺ…령은 ν˜ΈμŠ€νŠΈμ— λ„λ‹¬ν•˜κΈ° 전에 μ •μ±… μ—”μ§„κ³Ό ν”Œλž«νΌλ³„ 격리 μ–΄λŒ‘ν„°λ₯Ό κ±°μΉ©λ‹ˆλ‹€. ν˜„μž¬ ν”Œλž«νΌμ— μƒŒλ“œλ°•μŠ€ 도ꡬ가 μ—†μœΌλ©΄, λͺ…μ‹œμ μΈ μ‚¬μš©μž 승인과 ν•¨κ»˜ μƒŒλ“œλ°•μŠ€ μ—†λŠ” μ‹€ν–‰μœΌλ‘œ ν΄λ°±ν•©λ‹ˆλ‹€.

β–Ά How It Works μž‘λ™ 원리

Root sessions register a tool labeled "bash (sandboxed)". When the agent issues a bash command, the execution pipeline is:

Root μ„Έμ…˜μ€ "bash (sandboxed)"λΌλŠ” λ ˆμ΄λΈ”μ˜ 도ꡬλ₯Ό λ“±λ‘ν•©λ‹ˆλ‹€. μ—μ΄μ „νŠΈκ°€ bash λͺ…령을 λ°œν–‰ν•˜λ©΄ μ‹€ν–‰ νŒŒμ΄ν”„λΌμΈμ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

Command β†’ Policy Engine β†’ Platform Adapter (bwrap | sandbox-exec) β†’ Executionλͺ…λ Ή β†’ μ •μ±… μ—”μ§„ β†’ ν”Œλž«νΌ μ–΄λŒ‘ν„° (bwrap | sandbox-exec) β†’ μ‹€ν–‰

Bash is launched as:

BashλŠ” λ‹€μŒκ³Ό 같이 μ‹€ν–‰λ©λ‹ˆλ‹€:

bash -lc <command>

The policy engine evaluates platform capability, filesystem mode, and network mode to produce a sandbox decision. If the decision is sandboxed, the platform adapter wraps the command in the appropriate isolation mechanism. If the decision is unsandboxed, the approval flow determines whether execution is permitted.

μ •μ±… 엔진은 ν”Œλž«νΌ κΈ°λŠ₯, νŒŒμΌμ‹œμŠ€ν…œ λͺ¨λ“œ, λ„€νŠΈμ›Œν¬ λͺ¨λ“œλ₯Ό ν‰κ°€ν•˜μ—¬ μƒŒλ“œλ°•μŠ€ 결정을 λ‚΄λ¦½λ‹ˆλ‹€. 결정이 sandboxed이면 ν”Œλž«νΌ μ–΄λŒ‘ν„°κ°€ λͺ…령을 μ μ ˆν•œ 격리 λ©”μ»€λ‹ˆμ¦˜μœΌλ‘œ κ°μŒ‰λ‹ˆλ‹€. 결정이 unsandboxed이면 승인 흐름이 μ‹€ν–‰ ν—ˆμš© μ—¬λΆ€λ₯Ό κ²°μ •ν•©λ‹ˆλ‹€.

β–  Platform Adapters ν”Œλž«νΌ μ–΄λŒ‘ν„°

Each platform has a dedicated adapter that provides sandbox capability detection and launch construction:

각 ν”Œλž«νΌμ—λŠ” μƒŒλ“œλ°•μŠ€ κΈ°λŠ₯ 감지 및 μ‹€ν–‰ ꡬ성을 μ œκ³΅ν•˜λŠ” μ „μš© μ–΄λŒ‘ν„°κ°€ μžˆμŠ΅λ‹ˆλ‹€:

Platformν”Œλž«νΌ Commandλͺ…λ Ή Mechanismλ©”μ»€λ‹ˆμ¦˜
Linux bwrap bubblewrap namespace isolationbubblewrap λ„€μž„μŠ€νŽ˜μ΄μŠ€ 격리
macOS sandbox-exec Apple sandbox profileApple μƒŒλ“œλ°•μŠ€ ν”„λ‘œν•„

β˜… Linux (bwrap) Linux (bwrap)

The Linux adapter uses bubblewrap for namespace-level isolation. The full launch command:

Linux μ–΄λŒ‘ν„°λŠ” λ„€μž„μŠ€νŽ˜μ΄μŠ€ μˆ˜μ€€ 격리λ₯Ό μœ„ν•΄ bubblewrap을 μ‚¬μš©ν•©λ‹ˆλ‹€. 전체 μ‹€ν–‰ λͺ…λ Ή:

bwrap \
  --die-with-parent \
  --new-session \
  --ro-bind / / \
  --proc /proc \
  --dev /dev \
  --tmpfs /tmp \
  --bind <workspace> <workspace> \
  --chdir <cwd> \
  [--unshare-net] \
  -- <command>

Flags explained:

ν”Œλž˜κ·Έ μ„€λͺ…:

  • --die-with-parent β€” Kill the sandbox if the parent process dies. λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ˜λ©΄ μƒŒλ“œλ°•μŠ€λ₯Ό μ’…λ£Œν•©λ‹ˆλ‹€.
  • --new-session β€” Create a new process session. μƒˆ ν”„λ‘œμ„ΈμŠ€ μ„Έμ…˜μ„ μƒμ„±ν•©λ‹ˆλ‹€.
  • --ro-bind / / β€” Mount the root filesystem read-only. 루트 νŒŒμΌμ‹œμŠ€ν…œμ„ 읽기 μ „μš©μœΌλ‘œ λ§ˆμš΄νŠΈν•©λ‹ˆλ‹€.
  • --proc /proc β€” Mount a new proc filesystem. μƒˆ proc νŒŒμΌμ‹œμŠ€ν…œμ„ λ§ˆμš΄νŠΈν•©λ‹ˆλ‹€.
  • --dev /dev β€” Mount a minimal /dev. μ΅œμ†Œν•œμ˜ /devλ₯Ό λ§ˆμš΄νŠΈν•©λ‹ˆλ‹€.
  • --tmpfs /tmp β€” Mount a fresh tmpfs at /tmp. /tmp에 μƒˆ tmpfsλ₯Ό λ§ˆμš΄νŠΈν•©λ‹ˆλ‹€.
  • --bind <workspace> <workspace> β€” Bind-mount the workspace read-write. μ›Œν¬μŠ€νŽ˜μ΄μŠ€λ₯Ό 읽기-μ“°κΈ°λ‘œ λ°”μΈλ“œ λ§ˆμš΄νŠΈν•©λ‹ˆλ‹€.
  • --chdir <cwd> β€” Set working directory inside the sandbox. μƒŒλ“œλ°•μŠ€ λ‚΄ μž‘μ—… 디렉토리λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.
  • --unshare-net β€” Disable network access (when network mode is "off"). λ„€νŠΈμ›Œν¬ μ•‘μ„ΈμŠ€ λΉ„ν™œμ„±ν™” (λ„€νŠΈμ›Œν¬ λͺ¨λ“œκ°€ "off"일 λ•Œ).
Capability Check κΈ°λŠ₯ 확인

The adapter runs which bwrap to detect availability. If bwrap is not installed, the system falls back to unsandboxed execution with approval.

μ–΄λŒ‘ν„°λŠ” which bwrapλ₯Ό μ‹€ν–‰ν•˜μ—¬ μ‚¬μš© κ°€λŠ₯ μ—¬λΆ€λ₯Ό κ°μ§€ν•©λ‹ˆλ‹€. bwrap이 μ„€μΉ˜λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ©΄ 승인과 ν•¨κ»˜ μƒŒλ“œλ°•μŠ€ μ—†λŠ” μ‹€ν–‰μœΌλ‘œ ν΄λ°±ν•©λ‹ˆλ‹€.

β—† macOS (sandbox-exec) macOS (sandbox-exec)

The macOS adapter uses Apple's sandbox-exec with a dynamically generated SBPL profile. The profile is written to a temporary file and cleaned up after execution:

macOS μ–΄λŒ‘ν„°λŠ” λ™μ μœΌλ‘œ μƒμ„±λœ SBPL ν”„λ‘œν•„κ³Ό ν•¨κ»˜ Apple의 sandbox-execλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. ν”„λ‘œν•„μ€ μž„μ‹œ νŒŒμΌμ— 기둝되고 μ‹€ν–‰ ν›„ μ •λ¦¬λ©λ‹ˆλ‹€:

(version 1)
(deny default)
(import "system.sb")
(allow process*)
(allow sysctl-read)
(allow file-read*)
(allow file-write*
  (subpath "<workspace>")
  (subpath "/tmp")
  (subpath "<tmpdir>"))
(allow network*) # when network mode is "on"

Profile explained:

ν”„λ‘œν•„ μ„€λͺ…:

  • (deny default) β€” Deny all operations by default. 기본적으둜 λͺ¨λ“  μž‘μ—…μ„ κ±°λΆ€ν•©λ‹ˆλ‹€.
  • (import "system.sb") β€” Import macOS system sandbox defaults. macOS μ‹œμŠ€ν…œ μƒŒλ“œλ°•μŠ€ 기본값을 μž„ν¬νŠΈν•©λ‹ˆλ‹€.
  • (allow process*) β€” Allow process creation and signal operations. ν”„λ‘œμ„ΈμŠ€ 생성 및 μ‹œκ·Έλ„ μž‘μ—…μ„ ν—ˆμš©ν•©λ‹ˆλ‹€.
  • (allow sysctl-read) β€” Allow reading system information. μ‹œμŠ€ν…œ 정보 읽기λ₯Ό ν—ˆμš©ν•©λ‹ˆλ‹€.
  • (allow file-read*) β€” Allow reading any file. λͺ¨λ“  파일 읽기λ₯Ό ν—ˆμš©ν•©λ‹ˆλ‹€.
  • (allow file-write* ...) β€” Restrict writes to workspace, /tmp, and the system tmpdir. μ“°κΈ°λ₯Ό μ›Œν¬μŠ€νŽ˜μ΄μŠ€, /tmp, μ‹œμŠ€ν…œ tmpdir둜 μ œν•œν•©λ‹ˆλ‹€.
  • (allow network*) β€” Enable network access (only when network mode is "on"). λ„€νŠΈμ›Œν¬ μ•‘μ„ΈμŠ€ ν™œμ„±ν™” (λ„€νŠΈμ›Œν¬ λͺ¨λ“œκ°€ "on"일 λ•Œλ§Œ).
Capability Check κΈ°λŠ₯ 확인

The adapter runs which sandbox-exec to detect availability. If sandbox-exec is not available, the system falls back to unsandboxed execution with approval.

μ–΄λŒ‘ν„°λŠ” which sandbox-execλ₯Ό μ‹€ν–‰ν•˜μ—¬ μ‚¬μš© κ°€λŠ₯ μ—¬λΆ€λ₯Ό κ°μ§€ν•©λ‹ˆλ‹€. sandbox-exec을 μ‚¬μš©ν•  수 μ—†μœΌλ©΄ 승인과 ν•¨κ»˜ μƒŒλ“œλ°•μŠ€ μ—†λŠ” μ‹€ν–‰μœΌλ‘œ ν΄λ°±ν•©λ‹ˆλ‹€.

● Approval Flow 승인 흐름

When sandbox capability is unavailable or the policy engine decides unsandboxed execution is needed, the approval flow gates command execution. The mode is controlled via the PI_SANDBOX_APPROVAL_MODE environment variable:

μƒŒλ“œλ°•μŠ€ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μ—†κ±°λ‚˜ μ •μ±… 엔진이 μƒŒλ“œλ°•μŠ€ μ—†λŠ” 싀행이 ν•„μš”ν•˜λ‹€κ³  κ²°μ •ν•  λ•Œ, 승인 흐름이 λͺ…λ Ή 싀행을 μ œμ–΄ν•©λ‹ˆλ‹€. λͺ¨λ“œλŠ” PI_SANDBOX_APPROVAL_MODE ν™˜κ²½ λ³€μˆ˜λ‘œ μ œμ–΄λ©λ‹ˆλ‹€:

Modeλͺ¨λ“œ Behaviorλ™μž‘
ask Prompt the user for each unsandboxed command (default). μƒŒλ“œλ°•μŠ€ μ—†λŠ” 각 λͺ…령에 λŒ€ν•΄ μ‚¬μš©μžμ—κ²Œ ν”„λ‘¬ν”„νŠΈ (κΈ°λ³Έκ°’).
always Auto-approve all unsandboxed fallbacks. λͺ¨λ“  μƒŒλ“œλ°•μŠ€ μ—†λŠ” 폴백을 μžλ™ 승인.
deny Block all unsandboxed execution. λͺ¨λ“  μƒŒλ“œλ°•μŠ€ μ—†λŠ” 싀행을 차단.

Approval choices presented to the user:

μ‚¬μš©μžμ—κ²Œ μ œμ‹œλ˜λŠ” 승인 선택:

  • Deny β€” Block this command. κ±°λΆ€ β€” 이 λͺ…령을 μ°¨λ‹¨ν•©λ‹ˆλ‹€.
  • Allow once β€” Execute this command once, no caching. ν•œ 번 ν—ˆμš© β€” 이 λͺ…령을 ν•œ 번 μ‹€ν–‰, 캐싱 μ—†μŒ.
  • Allow for session β€” Cache approval for the session (6-hour TTL, persisted). μ„Έμ…˜ λ™μ•ˆ ν—ˆμš© β€” μ„Έμ…˜ λ™μ•ˆ 승인 μΊμ‹œ (6μ‹œκ°„ TTL, 영ꡬ μ €μž₯).
  • Always allow β€” Persist approval indefinitely. 항상 ν—ˆμš© β€” μŠΉμΈμ„ λ¬΄κΈ°ν•œ 영ꡬ μ €μž₯.

Approval scopes:

승인 λ²”μœ„:

  • once β€” Single execution, no persistence. 단일 μ‹€ν–‰, μ˜μ†μ„± μ—†μŒ.
  • session β€” Cached for the session with a configurable TTL (default 6 hours, PI_SANDBOX_SESSION_APPROVAL_TTL_MS). ꡬ성 κ°€λŠ₯ν•œ TTL둜 μ„Έμ…˜ λ™μ•ˆ μΊμ‹œλ¨ (κΈ°λ³Έ 6μ‹œκ°„, PI_SANDBOX_SESSION_APPROVAL_TTL_MS).
  • always β€” Persisted to disk and never expires. λ””μŠ€ν¬μ— 영ꡬ μ €μž₯되며 λ§Œλ£Œλ˜μ§€ μ•ŠμŒ.

Approvals are persisted to ~/.pi/agent/sandbox-approvals.json using a versioned format (v2) that supports both scope types and expiration timestamps.

μŠΉμΈμ€ 두 λ²”μœ„ μœ ν˜•κ³Ό 만료 νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό λͺ¨λ‘ μ§€μ›ν•˜λŠ” 버전 관리 ν˜•μ‹(v2)을 μ‚¬μš©ν•˜μ—¬ ~/.pi/agent/sandbox-approvals.json에 영ꡬ μ €μž₯λ©λ‹ˆλ‹€.

β–Ά Sensitive Environment Detection λ―Όκ°ν•œ ν™˜κ²½ λ³€μˆ˜ 감지

The sandbox system detects files that may contain sensitive environment variables. A file is flagged as sensitive if its basename matches .env or starts with .env. (e.g., .env.local, .env.production).

μƒŒλ“œλ°•μŠ€ μ‹œμŠ€ν…œμ€ λ―Όκ°ν•œ ν™˜κ²½ λ³€μˆ˜λ₯Ό 포함할 수 μžˆλŠ” νŒŒμΌμ„ κ°μ§€ν•©λ‹ˆλ‹€. 파일의 λ² μ΄μŠ€λ„€μž„μ΄ .env와 μΌμΉ˜ν•˜κ±°λ‚˜ .env.둜 μ‹œμž‘ν•˜λ©΄(예: .env.local, .env.production) λ―Όκ°ν•œ κ²ƒμœΌλ‘œ ν‘œμ‹œλ©λ‹ˆλ‹€.

Blocking Behavior 차단 λ™μž‘

When PI_SANDBOX_APPROVAL_MODE=deny, reads of sensitive .env* files are blocked entirely.

PI_SANDBOX_APPROVAL_MODE=deny일 λ•Œ, λ―Όκ°ν•œ .env* 파일 읽기가 μ™„μ „νžˆ μ°¨λ‹¨λ©λ‹ˆλ‹€.

β–  Configuration μ„€μ •

Env Varν™˜κ²½ λ³€μˆ˜ Valuesκ°’ DefaultκΈ°λ³Έκ°’ Descriptionμ„€λͺ…
PI_SANDBOX_APPROVAL_MODE ask, always, deny ask Approval behavior for unsandboxed fallback execution. μƒŒλ“œλ°•μŠ€ μ—†λŠ” 폴백 싀행에 λŒ€ν•œ 승인 λ™μž‘.

β˜… Edge Cases μ—£μ§€ μΌ€μ΄μŠ€

No Sandbox Tool Available μƒŒλ“œλ°•μŠ€ 도ꡬ μ—†μŒ

If neither bwrap nor sandbox-exec is present (or the platform is unsupported), the system falls back to unsandboxed execution. The approval prompt is presented to the user unless PI_SANDBOX_APPROVAL_MODE=always or =deny overrides it.

bwrapμ΄λ‚˜ sandbox-exec이 μ—†κ±°λ‚˜ ν”Œλž«νΌμ΄ μ§€μ›λ˜μ§€ μ•ŠλŠ” 경우, μ‹œμŠ€ν…œμ€ μƒŒλ“œλ°•μŠ€ μ—†λŠ” μ‹€ν–‰μœΌλ‘œ ν΄λ°±ν•©λ‹ˆλ‹€. PI_SANDBOX_APPROVAL_MODE=always λ˜λŠ” =denyκ°€ μž¬μ •μ˜ν•˜μ§€ μ•ŠλŠ” ν•œ μ‚¬μš©μžμ—κ²Œ 승인 ν”„λ‘¬ν”„νŠΈκ°€ ν‘œμ‹œλ©λ‹ˆλ‹€.

Writable Roots μ“°κΈ° κ°€λŠ₯ 루트

In addition to the workspace root, the sandbox allows writes to the Pi agent directory and session directory. These are resolved from PI_CODING_AGENT_DIR and PI_CODING_AGENT_SESSION_DIR (defaulting to ~/.pi/agent and the session temp dir respectively).

μ›Œν¬μŠ€νŽ˜μ΄μŠ€ 루트 외에도 μƒŒλ“œλ°•μŠ€λŠ” Pi μ—μ΄μ „νŠΈ 디렉토리와 μ„Έμ…˜ 디렉토리에 μ“°κΈ°λ₯Ό ν—ˆμš©ν•©λ‹ˆλ‹€. 이듀은 PI_CODING_AGENT_DIRκ³Ό PI_CODING_AGENT_SESSION_DIRμ—μ„œ ν•΄κ²°λ©λ‹ˆλ‹€ (기본값은 각각 ~/.pi/agent와 μ„Έμ…˜ μž„μ‹œ 디렉토리).

Network Mode λ„€νŠΈμ›Œν¬ λͺ¨λ“œ

Network access is configurable per execution. When set to "off", Linux uses --unshare-net and macOS omits the (allow network*) clause from the SBPL profile. When set to "on", full network access is permitted within the sandbox.

λ„€νŠΈμ›Œν¬ μ•‘μ„ΈμŠ€λŠ” μ‹€ν–‰λ§ˆλ‹€ ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€. "off"둜 μ„€μ •ν•˜λ©΄ LinuxλŠ” --unshare-net을 μ‚¬μš©ν•˜κ³  macOSλŠ” SBPL ν”„λ‘œν•„μ—μ„œ (allow network*) μ ˆμ„ μƒλž΅ν•©λ‹ˆλ‹€. "on"으둜 μ„€μ •ν•˜λ©΄ μƒŒλ“œλ°•μŠ€ λ‚΄μ—μ„œ 전체 λ„€νŠΈμ›Œν¬ μ•‘μ„ΈμŠ€κ°€ ν—ˆμš©λ©λ‹ˆλ‹€.