跳轉到主要內容
這個單元解決什麼問題settings.json 是 Claude Code 的行為控制面,管轄工具權限(allow / ask / deny)、環境變數、hooks 掛載與模型選擇;settings.local.json 是不進版控的個人覆寫層,放本機密鑰路徑或個人偏好。分清兩者的用途邊界與合併優先序,你才不會把私鑰路徑推上 git,也不會困惑於為什麼某條 deny 規則明明寫了卻沒生效。這個單元給你可貼用的設定片段與一條驗證規則是否真的生效的路徑。

學習目標

  • 能說出 settings.json 可設定的四大面向(permissions / env / hooks / model),並各舉一個實際鍵值範例。
  • 能分清 settings.json(團隊共享、提交版控)與 settings.local.json(個人覆寫、gitignore)的用途邊界。
  • 能描述使用者級(~/.claude/settings.json)、專案級(.claude/settings.json)、local(.claude/settings.local.json)與 managed 企業層的合併優先序。
  • 能設定 deny list 保護 ~/.ssh**/.env 等敏感路徑,並驗證規則是否實際生效。
  • 能說出六種 permission 模式(defaultacceptEditsplanautodontAskbypassPermissions)的放行範圍差異,並依任務選對模式。

1. settings.json 能做什麼:四大面向

settings.json 是 JSON 格式的結構化設定檔,Claude Code 啟動時讀取它來決定自己的行為。它的頂層鍵很多(截至 2026-05 官方 reference 列出近百個,從 cleanupPeriodDaysstatusLineoutputStyle)[1],但你日常會動到的集中在四個面向:
  • permissions:工具權限規則(allow / ask / deny 三個陣列),第 4 節詳談。這是 settings.json 最重要的面向。
  • env:注入到每個 session 的環境變數。
  • hooks:在生命週期事件(PreToolUse / PostToolUse / Stop 等)掛載自訂指令,機制細節見 04-6
  • model:指定預設模型,接受別名("sonnet" / "opus" / "haiku")或完整 model ID;完整可用清單依你的 provider(Anthropic API、Bedrock、Vertex AI)而定,settings 文件本身不列舉(截至 2026-05)[1]。
一個四面向都用到的最小範例:
{
  "model": "opus",
  "env": {
    "ANTHROPIC_LOG": "info"
  },
  "permissions": {
    "deny": ["Read(~/.ssh/**)", "Read(.env)"],
    "ask": ["Bash(git push:*)"]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{ "type": "command", "command": ".claude/hooks/format.sh" }]
      }
    ]
  }
}
settings.json 是策略,CLAUDE.md 是規則分工的根據很明確:權限規則由 Claude Code 強制執行,不是由模型執行;你的 prompt 或 CLAUDE.md 塑形「Claude 會嘗試做什麼」,但不改變「Claude Code 允許什麼」[2]。換句話說 settings.json策略(machine-enforced,模型繞不過),CLAUDE.md規則(給模型讀的自然語言指引,模型可能不照做)。要防住一個危險動作,寫在 CLAUDE.md 裡求模型別做是不夠的,要用 permissions.deny

2. settings.local.json:不進版控的個人覆寫層

settings.local.jsonsettings.json 同放在 .claude/ 目錄下,結構完全相同,差別只有一個:它不該進版控。官方把它定位為 gitignored 的 local scope [1]。 典型用途是「只在你這台機器有效、且不該分享給團隊」的設定:
  • 指向本機密鑰路徑或個人帳號的環境變數。
  • 你個人想加、但不強加給團隊的額外 deny 規則。
  • 只在你機器上有意義的 hooks(例如呼叫你本機才有的工具)。
分工判準很簡單:會想讓團隊每個人都套用的,寫 settings.json(進版控);只屬於你這台機器的,寫 settings.local.json(不進版控)。
別讓 settings.local.json 漏進 gitClaude Code 首次建立 settings.local.json 時通常會把它加進專案 .gitignore,但你不該假設它一定生效。動手做第 2 題給你一條 git ls-files 的驗證指令。一旦這個檔案連同裡面的密鑰路徑被 commit、再 push,資訊就外洩了,而 git 歷史很難乾淨地抹除。

3. 合併優先序:四層加企業 managed 層

同一個設定出現在多個 scope 時,Claude Code 依優先序套用。官方的優先序如下(由高到低)[1]:
1

Managed(企業層,最高)

不可被任何其他層覆寫,連 command line 參數都壓不過。
2

Command line arguments

當次 session 的臨時覆寫。
3

Local(.claude/settings.local.json)

覆寫 project 與 user。
4

Project(.claude/settings.json)

覆寫 user。
5

User(~/.claude/settings.json,最低)

其他層都沒指定時才生效。
各 scope 的檔案位置(截至 2026-05)[1]:
Scope位置
ManagedmacOS /Library/Application Support/ClaudeCode/、Linux/WSL /etc/claude-code/、Windows C:\Program Files\ClaudeCode\(或經 plist / registry)
User~/.claude/settings.json
Project.claude/settings.json
Local.claude/settings.local.json(gitignored)
permissions 是合併,不是覆寫大多數設定遵循「後讀層覆寫前讀層」的 override 語意,但 permissions 是例外:權限規則跨 scope 合併(merge),不是替換 [1](這是 02-1 講的「合併 vs 覆寫」的具體案例)。更關鍵的是 deny 的不可逆性:任一層 deny 了某個動作,其他任何層都無法 allow 回來;deny 規則跨所有 scope 先於 allow 評估,所以 user 層的 deny 會擋掉 project 層的 allow [2]。這修正一個常見誤解:以為 local 或 project 層的 allow 能解開上層的 deny,做不到。要解開只能移除那條 deny。

4. permissions 實戰:規則語法與基礎 deny list

權限規則的格式是 ToolTool(specifier),評估順序是 deny → ask → allow,第一條命中的勝出,所以 deny 永遠優先 [2]。一個細節值得記:裸工具名(如 Bash)當 deny 規則會把整個工具從模型的 context 移除,模型根本看不到;帶 specifier 的(如 Bash(rm *))則保留工具、只擋匹配的呼叫 [2]。 各工具的 specifier 語法(截至 2026-05)[2]:
  • BashBash(npm run build) 精確匹配;Bash(npm run *) 前綴匹配;* 可出現在任意位置(Bash(* install) 匹配任何以 install 結尾的)。注意空格決定詞界:Bash(ls *) 匹配 ls -la 但不匹配 lsof,而 Bash(ls*) 兩者都匹配。:* 後綴等同尾部 *。複合指令(&&||;| 分隔)的每一段都必須各自被規則匹配才放行。
  • Read / Edit:走 gitignore 規範,四種 path 錨點要分清楚:
Pattern意義範例
//path檔案系統絕對路徑Read(//Users/alice/secrets/**)
~/pathhome 目錄Read(~/.ssh/**)
/path相對專案根(不是絕對路徑)Edit(/src/**/*.ts)
path./path相對當前目錄Read(.env)
最容易出錯的地方:/Users/alice/file 不是絕對路徑,它相對專案根;絕對路徑要寫 //Users/alice/file(兩條斜線)[2]。bare 檔名走 gitignore 語意,Read(.env) 等同 Read(**/.env),匹配任意深度的 .env
  • WebFetchWebFetch(domain:example.com)
  • MCPmcp__server(整個 server)、mcp__server__*mcp__server__tool(單一工具)。
  • AgentAgent(Explore) 控制可用的子代理。
一份可貼用的基礎 deny list(Windows 友善)你在 Windows + PowerShell 環境,路徑與 shell 有兩個專屬細節:Claude Code 把路徑正規化為 POSIX 形式(C:\Users\alice/c/Users/alice),所以跨磁碟匹配 .env 要寫 //**/.env;PowerShell 規則用 PowerShell(...) 前綴,形狀與 Bash 相同 [2]。
{
  "permissions": {
    "deny": [
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(//**/.env)",
      "Read(**/.env)",
      "Read(**/*.pem)",
      "Bash(curl:*)",
      "Bash(rm -rf:*)",
      "PowerShell(Remove-Item *)"
    ],
    "ask": [
      "Bash(git push:*)",
      "PowerShell(git push *)"
    ]
  }
}
留意這份只擋讀檔與危險指令,把不可逆的 git push 設為 ask,其餘走預設。這正是 03-3 最小授權原則的具體落地。
關於用權限規則限制網路:官方明確警告 Bash(curl http://github.com/ *) 這種想用參數約束 curl 的寫法很脆弱(換 protocol、加 redirect、用變數都能繞過)。更可靠的做法是 deny 掉 curl / wget 等 Bash 網路工具,改用 WebFetch(domain:...) 白名單;或用 PreToolUse hook 驗證 URL;真正的 OS 層阻擋則要靠 sandbox [2]。permissions 與 sandbox 是互補兩層:permissions 擋「Claude 嘗試存取」,sandbox 在 OS 層擋「即使 prompt injection 繞過了 Claude 的判斷」(見 01-6)。

互動式規則評估器

下面的評估器讓你直接試:加規則、輸入工具呼叫,看 deny → ask → allow 優先序怎麼裁定。命中的規則會高亮顯示。

5. permission 模式:六種授權階梯

第 4 節的規則是「逐條」授權,permission 模式則是「整體基調」:它設定每個工具呼叫預設要不要停下來問你。模式定 baseline,第 4 節的 allow / ask / deny 規則疊在上面微調。Claude Code 截至 2026-06 有六種模式,依「不問就放行的範圍」由緊到鬆排成一條階梯 [5]:
模式不問就放行適用場景
default只有讀取起步、敏感工作,逐個動作審
acceptEdits讀取+檔案編輯+常見檔案系統指令(mkdir / touch / rm / rmdir / mv / cp / sed你會事後用 git diff 審的程式碼迭代
plan只有讀取(只研究、提計畫、不改檔)動手前先摸清 codebase
auto幾乎全部,但每個動作先過背景安全分類器長任務、減少 prompt 疲勞
dontAsk只有預先 allow 的工具與唯讀 Bash 指令(其餘該問的一律拒)鎖死的 CI 與腳本
bypassPermissions全部,連安全檢查都關只在隔離容器 / VM
三個不變量先記住,它們在所有模式都成立 [5]:
  • deny 與顯式 ask 規則在每個模式都生效,連 bypassPermissions 也擋得住(allow 規則在 bypass 則無意義,因為一切已放行)。要硬擋一個動作,寫 deny,不要靠選模式。
  • protected paths 寫入除了 bypassPermissions 外永不自動放行.git.claude(除 .claude/worktrees)、.vscode.idea.npmrc.mcp.json.claude.json、各種 shell rc(.bashrc / .zshrc 等)這類路徑即使你下了 acceptEdits、或在 settings 設了 Edit(.claude/**) 的 allow,也照樣攔(完整清單見官方 protected paths 節 [5]);這道安全檢查跑在 allow 規則之前 [5]。
  • 模式只是 baseline,第 4 節的規則永遠疊在上面,不是二選一。

怎麼切換

三條路 [5]:
  • session 內:按 Shift+Tab 循環 default → acceptEdits → planauto / bypassPermissions / dontAsk 不在預設循環裡,要另外開(auto 帳號達標才出現、dontAsk 永不進循環只能用旗標啟動)。
  • 啟動時claude --permission-mode plan(或其他模式名)。
  • 設成預設settings.jsonpermissions.defaultMode
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

三個模式的雷區

autodontAskbypassPermissions 各有一個容易誤判的點,分開講。 auto(需 v2.1.83+)不是「自動 yes」,是「分類器擋高風險、其餘放行」。一個獨立的分類器模型在每個動作執行前審,擋掉超出你請求範圍、打未知基礎設施、或疑似被惡意內容操縱的動作;curl | bash、production 部署、force push 到 main、對既有檔案的不可逆刪除都預設擋下 [5]。兩個你必須知道的行為:你在對話裡講的邊界(「先別 push」「等我看過再部署」)會被分類器當成 block 訊號,但邊界只存在 transcript 裡,context 壓縮掉那句話邊界就失效,要硬保證得改用 deny 規則。另外 defaultMode: "auto" 寫在專案層或 local 層會被忽略(v2.1.142+),免得一個 repo 自己給自己開 auto,要設只能放 ~/.claude/settings.json [5]。 dontAsk 是「全自動拒絕」,不是「全自動放行」。名字容易讀反:它把所有原本該問的呼叫一律拒掉,只有命中你 permissions.allow 的工具與唯讀 Bash 指令能跑,連 ask 規則都直接拒而非詢問 [5]。它是給「你已經精確定義好 Claude 能做什麼」的 CI 用的,預先沒 allow 的事一律不做。 bypassPermissions 把安全檢查也關了,只該在隔離環境用。它連 protected paths 寫入都放行(v2.1.126 起),等於拿掉所有兜底;只有顯式 ask 規則與 rm -rf / / rm -rf ~ 這種對檔案系統根 / home 的刪除仍會擋(最後的 circuit breaker)[5]。Linux / macOS 上以 root 或 sudo 跑會直接拒絕啟動。官方對它的定位很明確:它對 prompt injection 零防護,要「少問又有兜底」應該用 auto 而非 bypass [5]。--dangerously-skip-permissions 就是它,名字已經告訴你該多小心。
同一個任務,選哪個模式你要 Claude 把一個模組重構成多檔,過程會大量改檔,但你想保留審查權:
  • default:每次寫檔都停下來問,安全但你會被打斷上百次。
  • acceptEdits:改檔不問,跑完你一次 git diff 審完;working directory 外的寫入、protected paths、其他 Bash 指令仍會問。多數「我會事後審」的情境選這個
  • bypassPermissions:連 protected paths 都不擋。除非你在丟棄式容器裡,否則這是拿可重現性與安全換省事,代價不對等。
判準:願意事後審 diff(不需逐步)就 acceptEdits;要逐步審就 default;要長時間無人值守又想保留兜底就 auto(且在隔離或低風險倉庫);bypass 只在「即使被 injection 接管也炸不到我」的環境。這正是 03-3 最小授權原則在模式層的落地。
管理層可以鎖死高風險模式企業 managed settings 能用 permissions.disableBypassPermissionsMode: "disable" 鎖掉 bypass、permissions.disableAutoMode: "disable" 鎖掉 auto [5]。團隊環境若你發現某模式切不過去,先看是不是被 managed 層擋了,它壓得過 CLI 旗標。

6. 與 claude.json 的分工

一句話分清:settings.json策略(你編輯的行為設定),claude.json狀態(Claude Code 自己維護的工具內部狀態,例如各專案的歷史與信任記錄)。你不該手動編輯 claude.json,它不是給人寫的。它的正確路徑、內容格式與該不該動它,見 02-4

工具對照

「專案級的行為設定檔」這個概念各家都有,但成熟度與粒度差異大(截至 2026-05,精確格式以各官方文件為準):
概念Anthropic Claude(主範本)OpenAI (Codex)Google (Gemini CLI)GitHub CopilotCursor
專案級行為設定檔.claude/settings.json [1].codex/config.toml(專案根往下、closest wins)+專案指令 AGENTS.md [3].gemini/settings.json [4].github/copilot-instructions.md(偏指令,非權限).cursor/rules/*.mdc + GUI 設定
個人覆寫(不進版控).claude/settings.local.json [1]需確認原始出處需確認原始出處需確認原始出處需確認原始出處
使用者全域設定檔~/.claude/settings.json [1]~/.codex/config.toml [3]~/.gemini/settings.json [4]VS Code user settingsUser Rules(GUI)
工具權限控制(allow / deny)permissions.allow / deny / ask 陣列 [2]config.toml 的 approval_policy / sandbox_mode [3]settings.json 含 tool permissions [4]無對等的細粒度工具權限設定需確認原始出處
hooks 掛載點hooks.PreToolUse / PostToolUse / Stop [1]需確認原始出處(無直接對應)需確認原始出處無直接對應無直接對應
對照表只給座標,不給細節各 cell 的精確機制與路徑屬快變動事實,無法確認者標「需確認原始出處」,以各官方文件為準。細粒度、machine-enforced 的工具權限(而非自然語言指令)目前以 Claude Code 的 permissions 與 Codex 的 sandbox / approval policy 最成熟;Copilot 與 Cursor 的專案級檔案偏「指令 / 規則」性質,靠模型遵循,不是強制邊界。

動手做

1

加基礎 deny list 並驗證它真的生效

把上面那份基礎 deny list 加進你專案的 .claude/settings.json,然後做兩件事確認它生效,而不是只是寫了:執行 /permissions(Claude Code 內),這個 UI 會列出合併後的所有規則以及每條來自哪個 settings 檔,你能直接看到 deny 規則有沒有進到最終策略 [2]。實際試探:要求 Claude 讀取一個被 deny 的路徑(例如 ~/.ssh/ 下的檔案),確認它被攔下而不是讀出內容。記得驗證的是合併後的最終策略,不是單一層的設定檔。
2

建 settings.local.json 放個人變數並確認不進版控

建立 .claude/settings.local.json,放一個只屬於你機器的 env 變數,然後驗證它被 gitignore:
git ls-files .claude/settings.local.json   # 應回傳空白(代表未被追蹤)
若回傳了檔名,代表它已被 git 追蹤,要立刻 git rm --cached .claude/settings.local.json 並把對應模式加進 .gitignore

常見誤區

反模式清單
  • 以為 local 或 project 的 allow 能解開上層的 deny:解不開。任一層 deny 即擋,deny 跨所有 scope 先於 allow 評估 [2]。要放行只能移除那條 deny,不是在更高優先層加 allow。
  • 把 deny list 當唯一安全防線:deny 規則只作用於 Claude 的內建檔案工具與它識別得出的 Bash 檔案指令(cathead 等),擋不住一個 Python / Node 腳本自己開檔讀取。要 OS 層阻擋所有 process,得開 sandbox [2]。
  • 在 env 明文存放密鑰env 會注入每個 session,把 API key 明文放進去等於把它留在設定檔裡。改用 apiKeyHelper / awsCredentialExport 這類 helper script 動態產生,或指向 secret manager,不要明文。
  • 手動編輯 claude.json:那是 Claude Code 自己維護的狀態檔,不是策略檔(見 02-4)。要改行為,改 settings.json
  • 把 settings.local.json 當成「優先序最高」:它確實覆寫 project 與 user,但壓不過 managed 企業層與 deny 規則,而且它和 settings.json疊加關係,不是取代。
  • 把選模式當成擋危險動作的手段:模式只設 baseline,deny 才是硬牆,且在每個模式(含 bypassPermissions)都生效。bypassPermissions 連 protected paths 都放行,靠它省事等於拿掉兜底;要少問又安全用 auto(第 5 節)。

自我檢核

通過本單元的標準
  1. 你能不能用一句話說清楚 settings.json(策略,machine-enforced)與 CLAUDE.md(規則,模型可能不照做)的分工?要擋一個危險動作,你會寫在哪個檔?
  2. 你的專案 .gitignore 是否已排除 settings.local.jsongit ls-files .claude/settings.local.json 回傳的是空白嗎?
  3. 給你一條 Read(/Users/alice/secret) 規則,它擋的是絕對路徑還是專案根下的路徑?要擋絕對路徑該怎麼寫?
  4. 你現在生效的 deny 規則,是看單一設定檔得知,還是用 /permissions 看合併後的最終策略確認的?
  5. user 層寫了 allow、project 層寫了同一動作的 deny,最後這個動作會被允許還是擋下?
  6. dontAsk 模式把該問的動作自動放行還是自動拒絕?bypassPermissionsauto 的根本差別在哪?

來源與延伸閱讀

事實主張依官方文件,快變動項標註截至 2026-05(permission 模式一節截至 2026-06)。
  • [1] Anthropic, “Claude Code settings,” Claude Code Docs. (settings.json 頂層鍵 reference;四層加 managed 的優先序 Managed → CLI args → Local → Project → User;permissions 跨 scope 合併而非覆寫;model 鍵接受別名與完整 ID) https://code.claude.com/docs/en/settings (截至 2026-05)
  • [2] Anthropic, “Configure permissions,” Claude Code Docs. (規則語法 Tool(specifier);評估序 deny → ask → allow first-match-wins;任一層 deny 不可被其他層 allow;Read / Edit 的 gitignore 四種 path 錨點與 Windows POSIX 正規化;權限由 Claude Code 強制而非模型;/permissions 檢視合併規則;permissions 與 sandbox 互補) https://code.claude.com/docs/en/permissions (截至 2026-05)
  • [3] OpenAI, “Codex configuration,” OpenAI Developers Docs. (user 全域 ~/.codex/config.toml 與專案 .codex/config.toml(專案根往下、closest wins);approval_policy / sandbox_modeAGENTS.md 為 Codex 的專案指令、等價於 CLAUDE.md) https://developers.openai.com/codex/config-reference (截至 2026-05)
  • [4] Google, “Gemini CLI configuration,” Gemini CLI Docs. (user ~/.gemini/settings.json 與專案 .gemini/settings.json,project 覆寫 user;settings.json 控制 tool permissions、MCP server、workspace 等) https://geminicli.com/docs/reference/configuration/ (截至 2026-05)
  • [5] Anthropic, “Choose a permission mode,” Claude Code Docs. (六模式 default / acceptEdits / plan / auto / dontAsk / bypassPermissions 的放行範圍;Shift+Tab 循環與 --permission-mode 旗標、permissions.defaultMode;deny 與顯式 ask 在所有模式生效;protected paths 除 bypass 外不自動放行;auto 背景分類器、需 v2.1.83+、對話邊界隨 context 壓縮失效、defaultMode: auto 於專案/local 層被忽略;dontAsk 自動拒絕;bypassPermissions 關安全檢查、root/sudo 拒啟、disableBypassPermissionsModedisableAutoMode managed 鎖) https://code.claude.com/docs/en/permission-modes (截至 2026-06)
  • 銜接:02-1 設定層級與「合併 vs 覆寫」的通用模型、02-4 claude.json 狀態檔的定位、01-6 權限邊界在 harness 設計中的位置、03-3 最小授權與供應鏈風險、04-6 用 hook 擴充權限評估與確定性把關。