05 - 權限模式與安全

04-互動介面與快捷鍵 | 00-Index | 下一篇 → 06-CLAUDE-md與記憶系統

⚠️ 這章是全套教學裡最該讀懂的一章。 你的 vault 會直接 push main 觸發網站重建,刷題網站有 2000 題醫學內容——權限設錯的代價是實質的。


六種權限模式

當 Claude 要改檔案、跑指令、或發網路請求時,它會停下來問你。權限模式決定它多常停。

模式不用問就能做的事適合
default(介面上叫 Manual只有讀取剛開始、敏感工作
acceptEdits讀取、改檔案、常見檔案系統指令(mkdir touch mv cp rm rmdir sed你會事後 review 的迭代
plan讀取(+ auto mode 可用時,classifier 核准的指令)改動前先探索
auto幾乎全部,但有背景安全檢查長任務、減少打斷
dontAsk只有你事先核准的工具鎖死的 CI / 腳本
bypassPermissions全部只能在隔離容器 / VM

📌 default 這個值在 CLI 介面上顯示為 Manualmanual 是可接受的別名(claude --permission-mode manual 也行)。設定檔和 hook / SDK 用的值仍然是 default


怎麼切

Session 中:按 Shift+Tab 循環 defaultacceptEditsplan。狀態列會顯示:

  • ⏸ manual mode on(灰色)
  • ⏵⏵ accept edits on
  • ⏸ plan mode on
  • ⏵⏵ auto mode on
  • ⏵⏵ don't ask on
  • ⏵⏵ bypass permissions on

⚠️ 不是每個模式都在預設循環裡:

  • auto:帳號符合條件時才出現
  • bypassPermissions:要用 --permission-mode bypassPermissions / --dangerously-skip-permissions / --allow-dangerously-skip-permissions 啟動過才會進循環
  • dontAsk永遠不在循環裡,只能用 --permission-mode dontAsk

啟動時

claude --permission-mode plan

設成預設~/.claude/settings.json):

{ "permissions": { "defaultMode": "plan" } }

Plan mode(你最該養成習慣的那個)

Plan mode 叫 Claude 研究並提出計畫,但不動你的原始碼。它會讀檔案、跑指令探索、寫出計畫,然後停下來問你。

進入:Shift+Tab,或單次 prompt 前綴 /plan

計畫做好後它會問你怎麼繼續:

  • Yes, and use auto mode — 核准並進 auto mode(auto 不可用時顯示為 “Yes, auto-accept edits”)
  • Yes, manually approve edits — 核准,但每個編輯都要你點頭
  • No, refine with Ultraplan on Claude Code on the web — 丟到網頁做瀏覽器版審閱
  • No, keep planning — 繼續留在 plan mode,告訴它要改什麼

💡 Ctrl+G 可以把計畫開在你的文字編輯器裡直接改,再讓 Claude 照改過的計畫做。這招在「它的計畫 80% 對、但有兩步不能接受」時特別有用。

核准計畫也會自動用計畫內容幫 session 命名(除非你已經用 --name/rename 設過)。


Auto mode(有背景 classifier 把關)

Auto mode 讓 Claude 不用停下來問,但有另一個 classifier 模型在每個動作執行前審查,擋掉:超出你要求範圍的、指向不認識的基礎設施的、看起來是被讀到的惡意內容驅動的動作。

預設會擋的(節選跟你有關的)

  • 下載並執行程式碼(curl | bash
  • 把敏感資料送到外部端點
  • 正式環境部署與 migration
  • 大規模刪除
  • git reset --hardgit checkout -- .git restore .git clean -fdgit stash drop/clear(會丟掉未 commit 的變更)
  • force push
  • git commit --amend 於「不是這個 session 建立的 commit」或「已經 push 過的 commit」
  • 把 secret 送出 repo 的 commit / push
  • 印出活的憑證或 token 到 transcript 或檔案
  • 對 Claude Code 自己的 transcript(~/.claude/projects/ 底下的 .jsonl)寫入

預設允許的

  • 工作目錄內的本機檔案操作
  • 安裝 lock file / manifest 裡宣告的相依
  • .env 並把憑證送給對應的 API
  • 唯讀 HTTP 請求
  • push 到你正在工作的那個 repo 的任何分支(含預設分支)——但名字看起來像部署目標的分支(productiongh-pages)會被個別判斷

你在對話裡講的界線也算數 ⭐

classifier 把你在對話中說出的界線當成阻擋訊號。你說「不要 push」或「等我 review 再部署」,即使預設規則允許,它也會擋下相符的動作。界線會一直有效直到你在後續訊息裡解除。

⚠️ 但這不是硬保證:界線不是存成規則,classifier 每次都從 transcript 重讀。如果 /compact 把那則訊息壓掉了,界線就沒了。 要硬保證請用 deny rule。

什麼時候會退回問你

classifier 連續擋 3 次、或累計擋 20 次,auto mode 就會暫停、恢復詢問。這個閾值不可設定。


bypassPermissions:什麼時候都不要在你的機器上用 ⚠️

官方警告:只在隔離環境使用——容器、VM、沒有網路的 dev container。

它連 protected paths 的寫入都放行。而且:

bypassPermissions 對 prompt injection 或非預期動作沒有任何保護

Linux / macOS 上以 root 或 sudo 執行時,Claude Code 會拒絕用這個模式啟動。

👉 你的機器上有醫學筆記、理財對帳單資料、兩個會自動部署的 repo。這個模式對你沒有正當使用情境。


Protected paths(受保護路徑)

有一小組路徑的寫入永遠不會被自動核准(除了 bypassPermissions):

模式對 protected path 的寫入
defaultacceptEdits詢問
plan詢問
auto交給 classifier
dontAsk拒絕
bypassPermissions允許

受保護目錄.git.config/git.vscode.idea.husky.cargo.devcontainer.yarn.mvn.claude.claude/worktrees 除外)

受保護檔案.gitconfig.gitmodules、各種 shell rc(.bashrc.zshrc.profile.envrc…)、.npmrc.yarnrcbunfig.toml.bazelrc.pre-commit-config.yamllefthook.*gradle-wrapper.properties.devcontainer.json.ripgreprcpyrightconfig.json.mcp.json.claude.json

⚠️ settings.json 裡的 permissions.allow 規則不能預先核准 protected path 的寫入——安全檢查跑在 allow 規則之前。


權限規則(allow / ask / deny)

模式設的是基準,規則疊在上面。用 /permissions 管理,或寫在 settings.json

{
  "permissions": {
    "defaultMode": "plan",
    "allow": [
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(python3 tools/validate.py)",
      "Read"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Bash(git push --force *)",
      "Bash(rm -rf *)",
      "Edit(.quartzsite/**)"
    ]
  }
}

規則語法重點:

  • 尾巴的 * 是前綴比對,而且空格很重要Bash(git diff *) 比對任何以 git diff 開頭的指令;Bash(git diff*) 會連 git diff-index 一起中。
  • deny 規則和明確的 ask 規則在每個模式都生效,包含 bypassPermissions
  • allow 規則在 bypassPermissions 下沒意義(反正全都允許了)。
  • 進入 auto mode 時,會授予任意程式碼執行的寬鬆 allow 規則會被丟掉Bash(*)Bash(python*) 這種、套件管理器 run 指令、Agent allow 規則。窄的規則如 Bash(npm test) 保留;離開 auto mode 時丟掉的會還原。

👉 給你兩個 repo 的建議 deny 規則

Obsidian-med-note/.claude/settings.json

{
  "permissions": {
    "deny": [
      "Edit(.quartzsite/**)",
      "Bash(git push --force *)",
      "Bash(git push -f *)"
    ],
    "ask": [
      "Bash(git push *)"
    ]
  }
}

理由直接對應 CLAUDE.md §6「不要動 .quartzsite/」和 §5「rebase 衝突要停手、絕不覆蓋使用者筆記」。規則是硬的,CLAUDE.md 是軟的——把最不能出錯的那兩條做成規則。


用 hook 做更硬的控制

規則是路徑 / 指令比對。要更複雜的判斷(例如「不准改今天使用者正在編輯的那篇筆記」),用 PreToolUse hook——它是 shell 指令,可以擋下工具呼叫。見 09-Hooks自動化

🔑 記住這個層級CLAUDE.md(軟:上下文)< 權限規則(硬:路徑比對)< hook(硬:任意邏輯)


實務建議:三段式工作流

1. plan mode  →  讓它研究、提計畫(不動檔案)
2. 看計畫,必要時 Ctrl+G 直接改
3. 核准 → acceptEdits 讓它做完
4. git diff 檢查 → 自己 commit(或叫它 commit)

不要一開始就 auto mode。 auto mode 適合「你已經信任這個方向、只是不想一直被打斷」的階段,不適合探索期。


🔗 相關筆記


最後更新:2026-08-04