當 AI 程式開發助手開始擁有執行指令、修改檔案、甚至安裝套件的能力時,「安全性」就不再只是附加選項,而是必須嚴肅面對的核心議題。Claude Code 作為 Anthropic 推出的終端 AI 程式開發工具,提供了原生的沙箱(Sandbox)機制,讓開發者可以在享受自動化便利的同時,確保系統不會因為 AI 的操作而遭受意外損害。這篇文章將從基本觀念出發,逐步介紹如何設定與啟用 Claude Code Sandbox,並深入探討透過 Docker 建立更強隔離環境的方法。
為什麼需要 Sandbox?
在沒有沙箱的情況下使用 Claude Code,每當 AI 試圖執行一條 shell 指令時,你都必須手動點擊「批准」。這個設計雖然安全,但帶來了三個實際問題:
- 批准疲勞(Approval Fatigue) 反覆點擊「允許」會讓你逐漸降低警覺,最終可能不經思考就放行了危險操作。
- 生產力下降 持續被打斷的工作流程,讓開發效率大打折扣。
- 自主性受限 Claude Code 無法真正獨立完成複雜的多步驟任務,每一步都需要你介入。
Sandbox 的核心思路非常直覺:與其在每次操作時詢問你,不如先劃定一個安全邊界,在邊界內的操作自動放行,只有試圖越界時才發出警告。
Claude Code 原生沙箱的運作方式
Claude Code 的原生沙箱透過作業系統層級的機制來強制執行安全邊界,而非單純依賴 AI 的「自我約束」。它主要從兩個維度進行隔離:
檔案系統隔離
沙箱對檔案存取的預設規則如下:
- 寫入權限:僅限當前工作目錄及其子目錄
- 讀取權限:預設可讀取整台電腦,但特定敏感目錄會被封鎖
- 越界存取:任何對工作目錄以外的寫入嘗試,都需要你明確授權
你可以透過 settings.json 精確控制這些規則:
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"],
"denyRead": ["~/.ssh", "~/.aws", ".env"],
"allowRead": ["."]
}
}
}
上面這個設定的意思是:
- 除了工作目錄外,額外允許寫入
~/.kube和/tmp/build - 明確禁止讀取 SSH 金鑰、AWS 憑證和環境變數檔案
- 允許讀取當前目錄
網路隔離
沙箱同樣控制 Claude Code 所有子進程的網路存取:
- 網域限制:僅允許連線到經過核准的網域
- 使用者確認:新的網域請求會觸發權限提示
- 全面覆蓋:限制適用於所有由 Bash 指令衍生的腳本、程式和子進程
作業系統層級的強制執行
不同平台使用不同的底層技術來實現沙箱:
| 平台 | 底層技術 | 說明 |
|---|---|---|
| macOS | Seatbelt(sandbox-exec) | Apple 內建的沙箱框架 |
| Linux | Bubblewrap | 輕量級的命名空間隔離工具 |
| WSL2 | Bubblewrap | 與 Linux 相同機制 |
這代表即使 AI 被 prompt injection 攻擊誘導去執行惡意指令,作業系統本身會在核心層面攔截越界操作——這不是軟體層的限制,而是 OS 級別的硬性隔離。
如何啟用與設定 Claude Code Sandbox
前置準備
macOS:不需要額外安裝任何東西,Seatbelt 已內建於系統中。
Linux(Ubuntu/Debian):
sudo apt install bubblewrap socat
Linux(Fedora):
sudo dnf install bubblewrap socat
如果你使用 Ubuntu 並啟用了 AppArmor,還需要為 bwrap 建立 profile:
sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
include if exists <local/bwrap>
}
EOF
sudo systemctl reload apparmor
啟用沙箱
啟用沙箱的方式極為簡單——在 Claude Code 的會話中輸入斜線指令:
/sandbox
Claude Code 會自動偵測你的作業系統,確認必要的依賴是否已安裝,然後啟用對應的沙箱機制。
沙箱模式
啟用沙箱後,Claude Code 的 Bash 工具會進入「自動允許」模式:在沙箱邊界內的指令自動執行,無需你逐一批准。但請注意以下幾點:
rm、rmdir等破壞性指令即使在沙箱內,仍然需要確認- 嘗試存取
/根目錄等敏感路徑時會被攔截並通知你 - 你可以選擇拒絕、一次性允許、或永久更新設定
允許特定路徑的寫入
許多 CLI 工具(如 kubectl、terraform、npm)需要存取工作目錄以外的路徑。你可以透過 allowWrite 精確授權:
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"]
}
}
}
路徑解析規則:
./path→ 相對於專案根目錄~/path→ 相對於使用者家目錄/path→ 絕對路徑
排除特定指令
某些工具可能與沙箱不相容。例如 docker 本身就需要存取系統資源,可以透過 excludedCommands 讓它跳過沙箱:
{
"sandbox": {
"excludedCommands": ["docker *"]
}
}
allowUnsandboxedCommands 與 failIfUnavailable 設定
這兩個設定都與「沙箱不可用時的行為」有關,建議一起規劃。
allowUnsandboxedCommands 控制的是:當某條指令在沙箱內執行失敗時,是否允許在沙箱外部重新嘗試。
- 設為
true時,Claude Code 會回退到標準的權限流程,提示你是否允許在沙箱外執行 - 設為
false時,任何無法在沙箱內執行的指令都會直接失敗,不會嘗試在沙箱外部執行
failIfUnavailable 控制的是:如果沙箱本身無法啟用(例如缺少 bubblewrap 依賴),Claude Code 應該直接報錯還是靜默降級為無沙箱模式。
- 設為
true時,沙箱無法使用就直接報錯,拒絕繼續執行 - 設為
false(預設)時,沙箱無法使用會靜默退回一般模式
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"failIfUnavailable": true
}
}
在安全性要求較高的環境中,建議將兩者分別設為 false 和 true——確保沙箱必須可用,且所有指令都必須在沙箱保護範圍內運行,完全杜絕繞過隔離的可能性。
allowedDomains 網域白名單設定
沙箱的網路隔離透過 allowedDomains 來控制 Bash 指令及其子進程可以連線的網域。只有明確列入白名單的網域才能被存取:
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": [
"github.com",
"*.github.com",
"registry.npmjs.org",
"*.googleapis.com",
"docs.anthropic.com"
]
}
}
}
幾個設定要點:
- 使用萬用字元
*來匹配子網域,例如*.github.com涵蓋api.github.com、raw.githubusercontent.com等 - 套件管理器(npm、pip 等)通常需要連線到對應的 registry,務必將其加入白名單
- 如果啟用了
allowManagedDomainsOnly,未在白名單中的網域會被直接封鎖,而非彈出確認提示
搭配 deniedDomains 可以在較寬鬆的白名單中精確排除特定網域:
{
"sandbox": {
"network": {
"allowedDomains": ["*.example.com"],
"deniedDomains": ["internal.example.com"]
}
}
}
沙箱與權限系統的關係
Claude Code 有兩套安全機制,它們是互補而非替代的關係:
| 機制 | 涵蓋範圍 | 執行層級 |
|---|---|---|
| 權限系統(Permissions) | 所有工具:Bash、Read、Edit、WebFetch、MCP 等 | 工具執行前的門禁檢查 |
| 沙箱(Sandbox) | 僅限 Bash 指令及其子進程 | 作業系統層級的強制執行 |
簡單來說,權限系統決定 Claude Code 能不能用某個工具,沙箱決定 Bash 工具能觸及多大的範圍。兩者搭配使用,才能構成完整的縱深防禦。
Permissions 權限設定範例
權限系統透過 permissions 區塊來定義 allow(允許)和 deny(拒絕)規則。每條規則的格式為 工具名稱(匹配模式),支援萬用字元。以下是一個實際的設定範例:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"WebFetch(domain:docs.claude.com)",
"WebSearch"
],
"deny": [
"Read(.env)",
"Read(**/*.pem)",
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git push -f *)"
]
}
}
這段設定的效果:
允許清單(allow)
Bash(npm run *)自動放行所有npm run開頭的指令(如npm run dev、npm run build),不需要逐次確認WebFetch(domain:docs.claude.com)允許 Claude Code 抓取docs.claude.com網域的內容WebSearch允許 Claude Code 執行網路搜尋
拒絕清單(deny)
Read(.env)禁止讀取環境變數檔案,防止 API Key 等敏感資訊外洩Read(**/*.pem)禁止讀取所有.pem憑證檔案,**匹配任意深度的目錄層級Bash(rm -rf *)禁止執行遞迴強制刪除指令Bash(git push --force *)和Bash(git push -f *)禁止強制推送,保護遠端倉庫的提交歷史
deny 規則的優先權高於 allow。即使某條指令匹配了允許規則,只要同時匹配了拒絕規則,該操作就會被阻擋。
完整的安全設定範例
將沙箱與權限系統結合,一個完整的 .claude/settings.json 設定可能長這樣:
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"failIfUnavailable": false,
"network": {
"allowedDomains": [
"github.com",
"*.github.com",
"registry.npmjs.org"
]
}
},
"permissions": {
"allow": [
"Bash(npm run *)",
"WebFetch(domain:docs.claude.com)",
"WebSearch"
],
"deny": [
"Read(.env)",
"Read(**/*.pem)",
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git push -f *)"
]
}
}
這個設定檔應放在專案根目錄的 .claude/settings.json,讓團隊成員共享相同的安全策略。
Claude Code in Docker Sandboxes
原生沙箱已經提供了不錯的隔離效果,但如果你需要更徹底的環境隔離——例如不想讓 AI 的操作對宿主機產生任何影響、需要一個乾淨且可重現的運行環境、或者想讓 AI 自由安裝系統套件而不汙染本機——那 Docker Sandbox 就是你的最佳選擇。
基本觀念
Docker Sandbox 的思路是:把 Claude Code 整個放進一個容器化的 microVM 中執行。這個 microVM 擁有自己的核心和記憶體空間,提供比標準容器更強的安全邊界。
相較於原生沙箱,Docker Sandbox 的主要優勢:
- 核心級隔離:使用獨立的核心和記憶體空間,而非僅靠命名空間限制
- 完全自主:AI 可以安裝系統套件、管理自己的 Docker 容器,而不影響宿主機
- 環境一致性:確保不同機器和團隊成員之間的開發環境完全一致
- 可拋棄性:每次啟動都是乾淨環境,用完即棄
前置需求
在使用 Docker Sandbox 前,你需要:
- 安裝 Docker Desktop(建議 4.58 以上版本以獲得 microVM 支援)
- 設定好
ANTHROPIC_API_KEY環境變數,或準備透過 OAuth 登入
快速上手
Docker 提供了 sbx(Sandbox CLI)指令,讓你一行啟動隔離環境:
# 在當前專案目錄啟動 Claude Code Docker Sandbox
sbx run claude .
這條指令會:
- 建立一個隔離的 microVM 容器
- 將當前目錄掛載到容器內
- 啟動 Claude Code 並自動套用
--dangerously-skip-permissions旗標
因為環境完全隔離,使用 --dangerously-skip-permissions 在這裡是合理且安全的——AI 最壞的情況也只是破壞容器內部的環境,而你的宿主機不受影響。
傳遞任務指令
你可以直接在啟動時傳遞工作指令:
sbx run claude -- "重構 login 函式並加入錯誤處理"
認證設定
首次啟動時,Docker Sandbox 會提示你登入 Anthropic 帳號。如果你偏好使用 API Key,可以透過 sandbox 的 secret 管理機制來設定:
# 全域設定 API Key
sbx secret set -g anthropic
或者在執行前直接設定環境變數:
export ANTHROPIC_API_KEY=your-api-key-here
sbx run claude .
自訂 Docker Image
如果你的專案需要特定的系統依賴或工具鏈,可以基於官方 base image 建立自訂映像:
FROM docker/sandbox-templates:claude-code
# 安裝專案需要的系統依賴
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
postgresql-client \
redis-tools
# 預安裝常用的全域工具
RUN npm install -g typescript ts-node
# 設定工作目錄
WORKDIR /workspace
建構並使用這個映像:
docker build -t my-claude-sandbox .
sbx run my-claude-sandbox .
手動容器化方式
如果你不想使用 sbx CLI,也可以完全手動建立 Docker 環境:
FROM node:20-slim
# 安裝 Claude Code
RUN npm install -g @anthropic-ai/claude-code
# 建立非 root 使用者
RUN useradd -m -s /bin/bash claude
USER claude
WORKDIR /workspace
ENTRYPOINT ["claude"]
執行時掛載必要的資料夾:
docker run -it --rm \
-v $(pwd):/workspace \
-v ~/.claude:/home/claude/.claude \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
my-claude-manual
安全性最佳實踐
使用 Docker Sandbox 時,以下幾點值得留意:
檔案掛載:
# ✅ 正確:僅掛載專案目錄
-v $(pwd):/workspace
# ❌ 危險:不要掛載整個家目錄
-v ~/:/home/claude/host
# ❌ 危險:不要掛載 SSH 金鑰
-v ~/.ssh:/home/claude/.ssh
# ❌ 危險:不要掛載 Docker socket
-v /var/run/docker.sock:/var/run/docker.sock
網路控制:
- 預設拒絕所有對外連線
- 僅以白名單方式允許必要的網域(如套件倉庫、API 端點)
- 避免暴露 Unix socket(特別是 Docker socket)
資源限制:
# 限制 CPU 和記憶體使用量
docker run -it --rm \
--cpus=2 \
--memory=4g \
-v $(pwd):/workspace \
my-claude-sandbox
安全限制與注意事項
即使啟用了沙箱,也要清楚了解它的限制邊界:
原生沙箱的限制
- 網路過濾的局限 內建的代理不會對 TLS 加密流量進行檢查,僅限制可連線的網域。如果你允許了
github.com,沙箱無法阻止利用 domain fronting 技術的攻擊。 - Unix Socket 的風險
allowUnixSockets設定可能無意間授予對 Docker socket 等強大系統服務的存取權限。 - 過度寬鬆的寫入權限 如果允許寫入
$PATH中的目錄或 shell 設定檔(.bashrc、.zshrc),可能導致權限提升攻擊。 - 沙箱不涵蓋的範圍 Read、Edit、Write 等內建檔案工具直接使用權限系統而非沙箱;Computer Use 功能則是在你的實際桌面上操作。
Docker Sandbox 的限制
- 效能開銷 microVM 的啟動和運行有一定的資源消耗
- 網路連通性 容器內的網路設定可能影響某些開發工作流
- 狀態不持久 容器銷毀後,所有未掛載到外部 volume 的變更都會遺失
最佳實踐總結
- 從嚴開始 以最小權限啟動,根據實際需求逐步放寬
- 監控違規日誌 定期檢視沙箱攔截記錄,了解 Claude Code 的實際需求
- 環境分離 開發、測試、生產環境使用不同的沙箱規則
- 搭配權限系統 沙箱與權限系統並用,構建縱深防禦
- 測試設定 確認沙箱規則不會阻擋正常的開發工作流
Claude Code Sandbox 的設計哲學非常務實:它不試圖封鎖一切,而是畫出清晰的安全邊界,讓 AI 在邊界內自由發揮。理解這個邊界在哪裡、什麼在邊界之內、什麼在邊界之外——這才是有效使用沙箱的關鍵。