你把 Claude Code 放進 sandbox,看到終端前面多了一個 (drop),是不是就能放心讓它執行所有命令?真正的 Drop Claude Code 安全實戰不能停在「有開 sandbox」:你得親手確認它能改專案、不能碰專案外檔案、看不到主機密鑰,而且網路只開到你原本批准的範圍。
這篇專為第一次替 Coding Agent 加隔離層的 Linux 使用者寫。你不需要先懂 kernel;我們會固定 Drop 與 gVisor 版本,建立只有假資料的一次性 Lab,再用同一組四關分別跑 native 與 gvisor。本機環境不是 Linux、也沒有 Drop/runsc,因此以下是依官方文件與原始碼整理的可重跑驗收流程,不把預期結果寫成 AlphaLab 親測。
先說結論:Sandbox 不是開關,而是四張通行證
一句話記住:Agent 安全邊界=看得見的掛載+帶得進去的環境變數+連得出去的網路+接觸 host kernel 的方式。
- native:Drop 用 user、mount、PID、IPC、cgroup 與 network namespaces 隔離,但 sandbox 內程式的 system call 最後仍由 host Linux kernel 處理。
- gVisor:保留 Drop 同一份掛載與網路設定,再插入一個 userspace application kernel;它縮小直接接觸 host kernel system-call surface 的範圍。
- 兩者都不是 microVM:gVisor 是 application kernel,不是硬體虛擬化;microVM 則另帶 guest kernel 與 hypervisor 邊界。
- 四關全過的意義:只證明這個版本、這份設定、這組測試的檔案/機密/環境變數/網路邊界符合預期;它不是完整漏洞掃描。

~/.ssh/id_rsa 不在視野裡。圖片/Drop 官方。Drop Claude Code 安全實戰:native 與 gVisor 差在哪?
把 native 想成「同一棟大樓裡,換了一套門禁與看不到其他房間的走廊」;gVisor 則在門禁後再放一位翻譯官。程式對 kernel 說的 system call,先由 gVisor Sentry 重新實作,再讓少量必要操作碰到 host。gVisor 官方安全模型也明確說明:映射進 sandbox 的檔案仍可依權限讀寫、網路仍可依政策連線;多一層 kernel 邊界不會收回你主動開的門。

這個角度也和站內的 Docker Sandboxes microVM 四道邊界不同:那篇檢查獨立 guest kernel 與 host bridge;本文檢查 Linux rootless namespaces,並用同一題 A/B 比較 gVisor。若你要先理解 Claude Code 自己的 permission mode 與 Bash Sandbox,先看 Claude Code Auto Mode 安全教學;外層 Drop 不會取代內層 deny/ask 規則。
開始前:只在 Linux 一次性環境做,先固定兩個版本
截至 2026 年 9 月 24 日,Drop 最新正式 release 是 v0.2.1,發布於 2026 年 8 月 24 日;官方 main branch 已經比它多出數十個 commit,所以不要把 latest 當成可重現版本。以下只下載 release artifact,並比對 GitHub API 公布的 SHA-256:
sudo apt-get update sudo apt-get install -y passt curl zstd ARCH=$(uname -m) case "$ARCH" in x86_64) FILE=drop-linux-amd64; SHA=e7398467402f20402db7734b6bab99bd1756297df8c9edd4872d53f55122b790 ;; aarch64) FILE=drop-linux-arm64; SHA=11e5f99ae4c6b952bdd41b14252598d05e516f1359fb9c2ebfdd6b70d50e2632 ;; *) echo "unsupported architecture: $ARCH"; exit 1 ;; esac curl -fL -o "/tmp/$FILE" \ "https://github.com/wrr/drop/releases/download/v0.2.1/$FILE" printf '%s %s\n' "$SHA" "/tmp/$FILE" | sha256sum -c - install -m 755 "/tmp/$FILE" "$HOME/.local/bin/drop" drop --version
checksum 必須顯示 OK,版本必須是 v0.2.1。Ubuntu 24 可能還需要官方文件列出的 AppArmor userns profile;Fedora 的 pasta 需要 SELinux policy。遇到 Permission denied 時,照 Drop 官方安裝頁處理,不要改成用 root 跑;Drop 原始碼會直接拒絕 effective UID 0。
gVisor 另外固定在 GitHub 於 2026 年 9 月 23 日 23:19 UTC 發布的 release-20260921.0。目前官方 tarball 除了 runsc,還包含同層的 gvisor-bin/ sidecars;只複製單一 runsc 已不是完整安裝。以下以 x86_64 為例,ARM64 把檔名改成 gvisor-aarch64.tar.zstd、SHA 改成 33c9a4022125ee45cbcd3c8ed431725ef9ca63bc379e38735f0b691172cd33b0:
GV=release-20260921.0 GFILE=gvisor-x86_64.tar.zstd GSHA=e3e7776afd36b08431c668a60f4271f9e9787ce0def960be680acb1681af3861 curl -fL -o "/tmp/$GFILE" \ "https://github.com/google/gvisor/releases/download/$GV/$GFILE" printf '%s %s\n' "$GSHA" "/tmp/$GFILE" | sha256sum -c - sudo tar --zstd -xf "/tmp/$GFILE" -C /usr/local/bin runsc --version | tee "$HOME/runsc-version.txt"
gVisor 官方安裝文件偏好 Debian APT,因為未來多檔案升級比較穩;上面用 point release tarball,是為了讓這次 Lab 的 bytes 可核對。正式長期使用時,請選一種更新機制,不要讓 APT 與手動 tar 互相覆蓋。
建立一次性 Lab:repo 可寫、.git 唯讀、HOME 隔離
先建立完全沒有真實憑證、客戶碼或 production 設定的測試區。Drop init 預設把當前目錄掛成可讀寫,但把其中的 .git 改成唯讀;原本的 HOME 會被隔離,每個 Drop environment 另有持久化 HOME。
LAB=$(mktemp -d) mkdir -p "$LAB/repo" "$LAB/outside" printf 'outside-canary\n' > "$LAB/outside/host-only.txt" cd "$LAB/repo" git init printf 'inside-canary\n' > README.md git add README.md git -c user.name=Lab -c user.email=lab@example.invalid commit -m init drop init claude-lab # 先看實際生成設定,再跑任何 Agent sed -n '1,240p' "$HOME/.config/drop/claude-lab.toml" sed -n '1,280p' "$HOME/.config/drop/base.toml"
檢查 mounts、blocked_paths、environ.exposed_vars 與 net.mode。尤其留意 ~/.gitconfig、shell rc、歷史檔與自訂 glob:唯讀只防修改,不會阻止讀取其中的 token。想完全不分享當前 repo,可重建成 drop init --no-cwd claude-lab,再只掛入需要的路徑。
接著在 Drop 裡安裝 Claude Code,讓 binary 與登入狀態落在 claude-lab 自己的 HOME,而不是主機 HOME。Anthropic 目前的 Claude Code 快速開始使用 native installer:
drop run -e claude-lab --runtime native bash # 以下在 (drop) shell 內執行 curl -fsSL https://claude.ai/install.sh | bash claude --version exit
先不要立刻用 --dangerously-skip-permissions。外層 sandbox 限制「碰得到什麼」,Claude Code 的 permission mode 控制「哪些 tool call 直接批准」;兩層回答不同問題。想把這個概念擴成可觀測的 Agent 執行層,可接著讀 AI Agent Harness 是什麼與 AI Agent Harness 實作。
Drop Claude Code 安全實戰四關:同一題跑 native 與 gVisor
先把 host 的假秘密放進環境,並在 host localhost 開一個只服務假檔案的測試 server。不要用真正的 SSH key 或 API key當 canary。
export DROP_TEST_SECRET='FAKE_ONLY_7f3a' printf 'host-local-service\n' > "$LAB/outside/index.html" python3 -m http.server 18765 --bind 127.0.0.1 \ --directory "$LAB/outside" >"$LAB/http.log" 2>&1 & HTTP_PID=$!

第一關:專案內可寫,專案外與 .git 不可寫
for RT in native gvisor; do
echo "=== $RT / filesystem ==="
drop run -e claude-lab --runtime "$RT" bash -lc '
printf ok > boundary-inside.txt
test "$(cat boundary-inside.txt)" = ok
if printf bad > .git/escape-test 2>/dev/null; then exit 41; fi
if printf bad > "'"$LAB"'/outside/escape-test" 2>/dev/null; then exit 42; fi
echo PASS-filesystem
'
done
通過標準不是「什麼都不能寫」,而是 boundary-inside.txt 真的出現在 repo,兩個越界寫入都失敗。若 repo 也不能寫,表示掛載太緊;若 .git 能寫,先停下來檢查 environment TOML,而不是把結果解釋成方便。
第二關:主機 ~/.ssh 不在 sandbox HOME
for RT in native gvisor; do
drop run -e claude-lab --runtime "$RT" bash -lc '
test ! -e "$HOME/.ssh"
echo "PASS-ssh-hidden HOME=$HOME"
'
done
如果這關失敗,最常見原因不是 kernel 逃逸,而是你在 mounts 主動暴露了路徑,或把整個 HOME 掛進去。先修配置。即使 SSH key 被隱藏,repo 內的 .env、測試 fixture 與 shell rc 仍要另行檢查。
第三關:未列入 allowlist 的秘密環境變數不會繼承
for RT in native gvisor; do
drop run -e claude-lab --runtime "$RT" bash -lc '
test -z "${DROP_TEST_SECRET:-}"
echo PASS-env-hidden
'
done
若假秘密出現,檢查 exposed_vars 是否有過寬的 glob。反過來,Claude Code 登入後存在 sandbox HOME 的憑證,Agent 本來就能代表該帳號發請求;「主機環境變數沒繼承」不等於外部帳號沒有權限。
第四關:localhost 預設拒絕,外網依 net.mode 決定
for RT in native gvisor; do
echo "=== $RT / network ==="
drop run -e claude-lab --runtime "$RT" bash -lc '
if curl -fsS --max-time 3 http://127.0.0.1:18765/; then exit 44; fi
curl -fsS --max-time 8 https://example.com/ >/dev/null
echo PASS-isolated-network
'
drop run -e claude-lab --runtime "$RT" --net off bash -lc '
if curl -fsS --max-time 3 https://example.com/; then exit 45; fi
echo PASS-network-off
'
done
isolated 的預期是外網可用、host localhost 不可用;off 則兩者都失敗。若開發 server 必須跨界,不要把整個 network namespace 拆掉;Drop 的 tcp_host_ports/--tcp-host 可以只放行指定 host port。出站流量是否真的跨界、遠端是否接受,是另一條證據鏈,可搭配 AI Coding Agent 出站流量稽核。
A/B 相容性與延遲:不要抄別人的倍數
gVisor 官方效能指南解釋,額外成本主要來自 Sentry 記憶體、system-call 攔截,以及檔案與網路子系統的實作差異;純 CPU 指令不會因為 gVisor 而被模擬。這不代表你的 npm install、測試或 dev server 一定慢多少。版本、kernel、檔案數量與 syscall 密度不同,百分比不能直接搬。
for RT in native gvisor; do
echo "=== $RT ==="
/usr/bin/time -f 'elapsed=%e sec maxrss=%M KB' \
drop run -e claude-lab --runtime "$RT" bash -lc '
node --version
git status --short
claude --version
YOUR_REAL_TEST_COMMAND
'
done
把 YOUR_REAL_TEST_COMMAND 換成專案真正的 lint、unit test 或 build,先跑一輪暖機,再各跑至少三次,保存版本與中位數。若 gVisor 只有某個步驟失敗,先把它標成 compatibility failure,保留錯誤訊息與最小重現;不要直接關掉整層。官方目前列出的 Drop 限制包括 terminal-only、有限 device、setuid 不可用,以及依賴巢狀 user namespace 的 Podman/Snap workflow 不受支援。
native、gVisor、microVM 怎麼選?

- 選 Drop native:你主要防誤刪、越界讀寫與 localhost 誤連,信任 host kernel,並把低摩擦與相容性擺在前面。
- 選 Drop gVisor:你會執行未知套件或 Agent 生成的 binary,希望減少 workload 直接接觸 host kernel 的攻擊面,也能接受先做 compatibility gate。
- 選 microVM:你的威脅模型包含刻意惡意 workload、多租戶、需要獨立標準 guest kernel,或必須在隔離環境裡再跑容器。站內 Agent Substrate 教學則適合要處理大量 Agent 休眠、排程與 sandbox 密度的人。
microVM 也不是自帶完整政策。以 Firecracker 官方 production 文件為例,網路過濾、Jailer、cgroup、patch 與資源限制仍由 operator 配置;換句話說,hypervisor boundary 很重要,但掛載、網路與 credential 通道照樣要驗收。
停手規則與清理程序
- 四關任何一關意外成功:不要啟動 Claude Code;先保存版本、TOML 與輸出,再縮小 mount/env/port。
- native 與 gVisor 結果不同:先分辨是預期的 compatibility difference,還是同一份配置產生了不同權限結果;後者要當阻擋項。
- 測試需要真實 secret:停。Lab 只用 fake canary;真正帳號另做最小權限與撤銷設計。
- Agent 要碰 production、發訊息或 merge:外層 sandbox 不能消除外部副作用,保留人工批准與可撤銷 credential。
# 回到 host shell kill "$HTTP_PID" 2>/dev/null || true drop rm claude-lab # 先確認只指向這次 mktemp 建立的 Lab,再人工刪除 printf 'review cleanup target: %s\n' "$LAB" find "$LAB" -maxdepth 3 -print
drop rm claude-lab 會移除該 environment 的持久 HOME;它不會替你刪掉主機上的 repo 與外部 Lab 目錄。保留四關輸出、drop --version、runsc --version 與 TOML 作為收據,再由你確認 $LAB 是本次一次性路徑後清理。
常見問題 FAQ
1. Drop 可以在 macOS 或原生 Windows 跑嗎?
目前這份 Drop 流程不行。它依賴 Linux user/mount/PID/network 等 namespaces;macOS 請改用適合該平台的 sandbox 或 microVM,Windows 則先判斷是否要在 WSL2 裡做獨立 Linux Lab。
2. gVisor 等於一台 VM 嗎?
不等於。gVisor 是 userspace application kernel;它攔截並實作 Linux-like system-call interface,但不是帶 guest kernel 的硬體虛擬機。
3. 四關都 PASS,就能執行惡意程式嗎?
不能這樣推論。四關是設定驗收,不是對未知漏洞、side channel、DoS 或 kernel/runtime escape 的完整證明。刻意惡意、多租戶或高價值 secret 的場景,應提高到獨立 VM/microVM 與更完整的監控、資源與 credential policy。
4. 為什麼 repo 可以寫,.git 卻應該唯讀?
讓 Agent 能工作,又不直接改寫歷史控制面。它仍能改 working tree;你在 host review diff 後再 commit。這不是備份,重要 repo 仍要有 remote 或 snapshot。
5. net.mode=off 時 Claude Code 還能用嗎?
正常互動通常無法完成。Claude Code 需要網路連到模型服務;off 適合純本機測試與驗收。實際使用多半要 isolated,再用 proxy、外部 firewall 或專用環境收斂出站。
6. 可以把 ~/.ssh 唯讀掛進去嗎?
技術上 mount 可以唯讀,但秘密仍會被讀到。若只是 Git 操作,優先使用用途受限、可撤銷的 credential 通道;不要把「不可修改」誤認成「不可外洩」。
7. gVisor 比 native 慢多少?
沒有一個可套用所有專案的倍數。syscall、檔案與網路密集工作通常更敏感;純 CPU 工作受影響較小。用你自己的 lint/test/build 做同版本 A/B,保存中位數與錯誤。
8. 可以直接讓 Claude Code bypass permissions 嗎?
先不要。先讓四關、diff review、備份與外部帳號權限各自通過,再決定哪些任務能提高自動化。Sandbox 限制主機能力,不會阻止 Agent 用已授權帳號做不可逆的外部動作。
給新手的 6 個重點
- 先固定 Drop、runsc、kernel 與 TOML,再談結果。
- native 與 gVisor 用同一組四關,才能比較 runtime 而不是比較設定。
- repo 可寫是工作需求;專案外、
.git、主機 HOME 與未授權 localhost 必須分開驗。 - 秘密環境變數沒繼承,不代表 sandbox 內登入的帳號沒有外部權限。
- 效能只量自己的真實 command,不抄不同版本的 benchmark 倍數。
- 看到任何意外放行就停手;先縮小能力,再啟動 Agent。
接著閱讀
左右滑動查看更多推薦
結語:先跑四關,再把 Claude Code 放進去
Drop 最有價值的地方,不是替「安全」打勾,而是把掛載、HOME、環境變數與網路變成你能看、能改、能重跑的設定。今天先建立 fake-only Lab,讓 native 與 gVisor 都跑完四關;明天換 kernel、Drop、runsc 或 TOML,就重跑一次。當你能用收據回答「Agent 到底碰得到什麼」,才考慮提高自主權。想把這套方法延伸到自己的 Agent 專案,可從 AlphaLab 的 AI 實戰課程開始,將隔離、評測與可復原流程一起設計。






