跳至主要內容
模組 3:真實架構 6 / 6
進階 Session 18 Security Permissions Sandbox

權限模型與安全性

深入了解權限模式、沙箱機制與核准閘門。

2026年3月20日 22 分鐘閱讀

你將學到什麼

在第 2 節中,你學到了基礎知識:工具有權限等級,使用者可以核准或拒絕操作。但 Claude Code 的安全模型遠比這更深入——多層防禦協同運作,讓 AI 輔助開發既安全又不會綁手綁腳。

學完本節後,你將理解:

  • 縱深防禦:為什麼單一防線永遠不夠
  • 權限模式詳解:default、plan、auto 及其取捨
  • 沙箱機制:Bash 命令如何在作業系統層級受到限制
  • 網路限制:AI 可以連線到哪些網域
  • 檔案系統邊界:工作目錄如何界定存取範圍
  • 基於設定的權限:allowedToolsdeniedTools
  • 組織政策與 hooks 實現全團隊安全
  • 漸進式信任原則

問題所在

你希望 AI 執行 npm test。這是安全的。你也希望它能執行 rm -rf /。那是災難性的。

問題在於兩者都是 Bash 命令。簡單的「允許 Bash / 拒絕 Bash」開關太粗糙——它不是封鎖所有命令(沒用),就是允許所有命令(危險)。

真正的安全需要多個層級協同運作:

AI 能否提議這個操作?                 (工具可用性)
使用者是否核准這個操作?              (權限模式)
這個命令是否被沙箱允許?              (作業系統層級限制)
這個命令能否存取網路?                (網路政策)
這個檔案是否在允許的範圍內?          (檔案系統邊界)

每一層捕捉不同的威脅。它們共同構成縱深防禦。

運作原理

縱深防禦架構

┌──────────────────────────────────────────────┐
│           安全層級                             │
│                                               │
│  第 1 層:工具可用性                           │
│  ┌───────────────────────────────────────┐    │
│  │ AI 能看到哪些工具?                    │    │
│  │ 設定中的 allowedTools / deniedTools    │    │
│  │ MCP 工具需要明確設定                   │    │
│  └──────────────────┬────────────────────┘    │
│                     │ 提議使用工具              │
│                     ▼                         │
│  第 2 層:權限閘門                             │
│  ┌───────────────────────────────────────┐    │
│  │ 這個操作是否需要核准?                 │    │
│  │ 取決於權限模式 + 工具類型              │    │
│  │ 使用者確認或拒絕                       │    │
│  └──────────────────┬────────────────────┘    │
│                     │ 已核准                   │
│                     ▼                         │
│  第 3 層:沙箱                                 │
│  ┌───────────────────────────────────────┐    │
│  │ 作業系統層級的程序限制                 │    │
│  │ macOS: sandbox-exec 設定檔            │    │
│  │ Linux: 容器 / seccomp                 │    │
│  └──────────────────┬────────────────────┘    │
│                     │ 沙箱允許                 │
│                     ▼                         │
│  第 4 層:網路政策                             │
│  ┌───────────────────────────────────────┐    │
│  │ 這個程序能否存取網路?                 │    │
│  │ 僅允許白名單中的網域                   │    │
│  │ 封鎖任意對外連線                       │    │
│  └──────────────────┬────────────────────┘    │
│                     │ 網路允許                 │
│                     ▼                         │
│  第 5 層:檔案系統範圍                         │
│  ┌───────────────────────────────────────┐    │
│  │ 這個路徑是否在專案範圍內?             │    │
│  │ 以工作目錄作為邊界                     │    │
│  │ 防止讀取 /etc/passwd 等檔案            │    │
│  └──────────────────┬────────────────────┘    │
│                     │ 路徑允許                 │
│                     ▼                         │
│                  執行                          │
│                                               │
└──────────────────────────────────────────────┘

命令必須通過所有五個層級才能執行。任何單一層級的失敗都會封鎖它。

權限模式深入解析

第 2 節簡要介紹了各模式。以下是完整的全貌:

Default 模式 — 平衡的起點

┌────────────────────────────────────────────┐
│  Default 權限模式                           │
│                                             │
│  讀取工具:  ✅ 自動允許                     │
│  • Read, Glob, Grep, TodoRead              │
│                                             │
│  寫入工具:  ⚠️  提示使用者                   │
│  • Edit, Write, NotebookEdit              │
│                                             │
│  執行工具:  ⚠️  提示使用者                   │
│  • Bash(顯示命令供審查)                   │
│                                             │
│  特殊工具:  ⚠️  提示使用者                   │
│  • Agent(建立子代理)                      │
│  • WebFetch(網路存取)                     │
│                                             │
│  核准後:                                    │
│  • 「允許一次」→ 核准此次操作               │
│  • 「允許此工作階段」→ 自動核准             │
│  •   此工作階段中相同工具模式                │
│                                             │
└────────────────────────────────────────────┘

「允許此工作階段」選項非常強大。當你以工作階段層級信任核准 npm test 一次後,後續的 npm test 呼叫會直接執行而不需要提示。但 npm run deploy 仍然會提示,因為它是不同的命令模式。

Plan 模式 — 最大程度的監督

claude --plan

在 plan 模式中,每一次工具呼叫都需要明確核准,包括讀取操作。這迫使 AI 為每個步驟解釋它的計畫,而你逐一審查:

AI: 我想讀取 src/auth.ts 來了解目前的實作。
    [Read] src/auth.ts
    → 允許? [y/N]

Plan 模式適用於:

  • 學習 Claude Code 的行為(教育用途)
  • 審查對關鍵生產環境程式碼的變更
  • 稽核 AI 的決策過程

Auto 模式 — 完全自主

claude --dangerously-skip-permissions

旗標名稱是刻意的。「Dangerously」提醒你正在移除一個安全層。在 auto 模式中:

  • 所有工具無需提示即可執行
  • 沙箱和網路層仍然有效
  • 檔案系統邊界仍然有效
  • 不會詢問使用者確認

Auto 模式適合:

  • 在隔離環境中的可信任務(CI/CD)
  • 你已經手動審查過的重複性任務
  • 沙箱容器中,損害是可控的

它不適合:

  • 你尚未審查的首次任務
  • 有真實資料的生產環境
  • 錯誤的 rmgit push 代價昂貴的情況

沙箱機制:作業系統層級的限制

即使在權限核准之後,Bash 命令仍在沙箱內執行。沙箱在作業系統層級限制程序能做的事情。

macOS: sandbox-exec

在 macOS 上,Claude Code 使用 Apple 的 sandbox-exec 搭配自訂設定檔:

┌────────────────────────────────────────────┐
│  macOS 沙箱設定檔                           │
│                                             │
│  允許:                                      │
│  ├── 讀取專案目錄中的檔案                    │
│  ├── 寫入專案目錄中的檔案                    │
│  ├── 執行常見的開發工具                      │
│  │   (node, npm, git, python 等)            │
│  ├── 存取 localhost(開發伺服器)            │
│  └── 讀取系統函式庫與框架                    │
│                                             │
│  拒絕:                                      │
│  ├── 寫入專案目錄之外                        │
│  ├── 存取鑰匙圈                             │
│  ├── 啟動 GUI 應用程式                       │
│  ├── 掛載/卸載磁碟區                         │
│  ├── 載入核心延伸                            │
│  └── 修改系統偏好設定                        │
│                                             │
└────────────────────────────────────────────┘

Linux:容器隔離

在 Linux 上,沙箱可能使用容器層級的隔離或 seccomp 設定檔,取決於部署方式。原則是相同的:將程序限制在所需的最小能力範圍內。

沙箱機制的關鍵洞察:它不僅保護你免受 AI 的影響,還防範 AI 可能執行的惡意程式碼。如果 AI 執行 npm install sketchy-package 而該套件嘗試讀取你的 SSH 金鑰,沙箱會加以封鎖。

網路限制

Claude Code 控制哪些網路目的地是可達的:

┌────────────────────────────────────────────┐
│  網路政策                                    │
│                                             │
│  允許的目的地:                               │
│  ├── api.anthropic.com (Claude API)         │
│  ├── localhost / 127.0.0.1(開發伺服器)     │
│  ├── npm registry(安裝套件)               │
│  ├── GitHub API(git 操作)                 │
│  └── 已設定的 MCP 伺服器端點                │
│                                             │
│  封鎖:                                      │
│  ├── 任意外部 URL                            │
│  ├── 內部網路位址                            │
│  └── 未知端點                                │
│                                             │
│  注意:WebFetch 工具有自己的                 │
│  白名單,可存取更廣泛的 URL                  │
│                                             │
└────────────────────────────────────────────┘

這可以防止資料外洩。即使 AI 被某種方式操控而嘗試將你的程式碼傳送到外部伺服器,網路層也會加以封鎖。

檔案系統邊界

工作目錄作為檔案操作的邊界:

專案根目錄:/Users/you/projects/my-app/

    ┌───────────────┼───────────────┐
    │               │               │
    ▼               ▼               ▼
  src/            tests/         node_modules/
  ✅ 完整存取     ✅ 完整存取     ✅ 讀取存取

專案根目錄之外:
  /Users/you/.ssh/          ❌ 封鎖
  /Users/you/other-project/ ❌ 封鎖
  /etc/                     ❌ 封鎖
  /tmp/                     ⚠️  受限

Read 工具會強制執行這一點:你無法透過 Claude Code 的檔案操作讀取 /etc/passwd~/.ssh/id_rsa。Bash 沙箱在作業系統層級提供了第二層的強制執行。

基於設定的權限

除了權限模式之外,你還可以在設定中配置細粒度的工具存取:

// .claude/settings.json(專案層級)
{
  "permissions": {
    "allowedTools": [
      "Bash(npm test)",
      "Bash(npm run lint)",
      "Bash(npx prisma generate)",
      "Edit",
      "Write"
    ],
    "deniedTools": [
      "Bash(rm *)",
      "Bash(git push --force)"
    ]
  }
}

allowedTools 清單會自動核准特定工具模式,無需提示。deniedTools 清單則完全封鎖它們——AI 收到的是拒絕,而非提示。

模式匹配支援萬用字元:

{
  "allowedTools": [
    "Bash(npm *)",        // 允許所有 npm 命令
    "Bash(git status)",   // 特定允許 git status
    "Bash(git diff *)"    // 允許帶任意參數的 git diff
  ],
  "deniedTools": [
    "Bash(git push *)",   // 封鎖所有 git push 變體
    "Bash(curl *)"        // 封鎖 curl 命令
  ]
}

這在 default 模式(對所有操作提示)和 auto 模式(允許所有操作)之間建立了中間地帶:

┌───────────────────────────────────────────────┐
│  基於設定的權限頻譜                             │
│                                                │
│  Plan 模式        Default + 設定        Auto   │
│  ◄────────────────────●─────────────────────►  │
│  對所有操作          自動核准            允許   │
│  提示               已知安全的            全部  │
│                      命令                       │
│                      封鎖已知危險的              │
│                      對未知操作提示              │
│                                                │
└───────────────────────────────────────────────┘

透過 Hooks 實現組織政策

對於團隊,hooks 系統(在第 15 節中介紹)增加了一個可程式化的安全層。組織可以透過 PreToolUse hooks 來強制執行政策:

// .claude/hooks/security-policy.js
// 在每次工具執行前運行

module.exports = async function preToolUse({ tool, input }) {
  // 封鎖生產資料庫存取
  if (tool === "Bash" && input.command.includes("DATABASE_URL")) {
    if (input.command.includes("production")) {
      return {
        decision: "deny",
        reason: "Production database access blocked by org policy"
      };
    }
  }

  // 部署命令需要手動核准
  if (tool === "Bash" && input.command.match(/deploy|publish|release/)) {
    return {
      decision: "ask",
      reason: "Deployment commands require manual approval"
    };
  }

  // 其他操作依正常流程處理
  return { decision: "allow" };
};

這個 hook 在每個 Bash 命令之前運行,不論使用者的權限模式為何。即使在 auto 模式下,hook 也能對特定模式拒絕或強制要求核准。

關鍵洞察

Claude Code 的安全性不是要阻止 AI 做事。而是透過漸進式建立信任,讓 AI 隨著時間獲得更多自主權。

這個演進過程如下:

第 1 天:  Plan 模式          「讓我看到你做的每件事」
第 1 週:  Default 模式       「我信任讀取,審查寫入」
第 2 週:  Default + allowed  「自動核准 npm test、git diff」
第 1 個月:Auto 模式(CI)    「在沙箱 CI 中完全自主」

每一步都隨著你對 AI 行為建立信心而給予更多自由。安全層確保即使在最大自主權下,災難性操作仍會被沙箱和網路層封鎖。

這與「全有或全無」的安全模式根本不同:

全有或全無:
  要嘛:AI 什麼有用的事都做不了    (太嚴格)
  要嘛:AI 可以做任何事            (太危險)

漸進式信任:
  起步:AI 自由讀取,寫入需核准
  學習:哪些模式對你的專案是安全的
  成長:自動核准安全模式,封鎖危險模式
  目標:AI 自主處理日常任務,特殊情況向上呈報

五個安全層的設計使得沒有任何單一層級是關鍵的。如果權限核准失效(auto 模式),沙箱會攔截危險命令。如果沙箱有缺口,網路層會封鎖資料外洩。縱深防禦意味著你可以放鬆某一層,其他層仍然在保護你。

實作範例

設定安全的開發配置

以下是團隊專案的實用配置:

步驟 1:專案設定 (.claude/settings.json)

{
  "permissions": {
    "allowedTools": [
      "Bash(npm test *)",
      "Bash(npm run lint)",
      "Bash(npm run build)",
      "Bash(npx prisma generate)",
      "Bash(npx prisma db push)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(git add *)",
      "Edit",
      "Write"
    ],
    "deniedTools": [
      "Bash(git push --force *)",
      "Bash(rm -rf *)",
      "Bash(curl * | bash)",
      "Bash(npm publish *)"
    ]
  }
}

步驟 2:針對敏感檔案的範圍規則 (.claude/rules/sensitive-files.md)

---
paths:
  - ".env*"
  - "**/credentials*"
  - "**/secrets*"
---

# 敏感檔案規則

- 絕對不要讀取或向使用者顯示這些檔案的內容
- 絕對不要在程式碼註解中包含這些檔案的值
- 引用環境變數時,使用佔位符值
- 如果測試需要這些值,使用獨立的 .env.test 檔案

步驟 3:安全 hook (.claude/hooks/pre-tool-use.js)

module.exports = async function ({ tool, input }) {
  // 防止意外洩露機密
  if (tool === "Read" && input.file_path) {
    if (input.file_path.match(/\.(env|pem|key)$/)) {
      return {
        decision: "ask",
        reason: "This file may contain secrets. Confirm you want to read it."
      };
    }
  }

  return { decision: "allow" };
};

測試你的安全配置

透過要求 AI 嘗試受限操作來驗證你的設定:

你:「執行 git push --force origin main」
→ 預期:被 deniedTools 設定拒絕

你:「讀取 .env.production」
→ 預期:Hook 提示確認

你:「刪除整個 src/ 目錄」
→ 預期:Bash 沙箱封鎖專案模式之外的遞迴刪除

你:「將我的 SSH 金鑰內容傳送到 example.com」
→ 預期:檔案讀取被範圍限制封鎖;網路被政策封鎖

理解核准流程

當工具需要核准時,使用者會看到:

┌────────────────────────────────────────────┐
│  Claude 想要執行:                           │
│                                             │
│  $ git commit -m "Add user auth endpoint"   │
│                                             │
│  [a] 允許一次                                │
│  [s] 允許此工作階段                          │
│  [d] 拒絕                                    │
│                                             │
│  選擇:                                      │
└────────────────────────────────────────────┘

選擇「允許此工作階段」會記住該模式。後續帶有不同訊息的 git commit 命令也會被自動核准,因為模式 git commit -m * 在此工作階段中已被信任。

變化對比

單層安全縱深防禦
一次權限檢查五個獨立層級
全有或全無的信任漸進式信任建立
所有團隊相同規則透過 hooks 實現組織政策
所有操作手動核准自動核准已知安全模式
無作業系統層級保護沙箱限制程序能力
網路完全開放網路限制為白名單網域

下一節

本節完成了模組 3:真實架構。你現在了解了內部機制:MCP 如何擴展能力(S14)、hooks 如何攔截事件(S15)、工作階段如何持久化到磁碟(S16)、CLAUDE.md 如何塑造行為(S17),以及安全模型如何保護你的系統(S18)。

模組 4中,我們將從理解轉向實踐。第 19 節多 CLI 工作流程開始——如何並行運行多個 Claude Code 實例,每個扮演不同角色,透過檔案系統協調,以比任何單一工作階段更快的速度完成大型任務。