iT邦幫忙

0

把 .env 排除就安全了?AI Agent 的 Context 邊界還有三個洞

  • 分享至 

  • xImage
  •  

假設團隊已經把 .env 加進 content exclusions,Coding Agent 確實讀不到它。接著 Agent 執行測試,測試程式卻把完整的 Authorization header 印到 stderr。模型沒有直接開過 .env,token 還是出現在 tool result 裡。

排除檔案,不等於排除資料。

這個差異在人操作 CLI 時就存在,只是 Agent 會把問題放大。它可以跨目錄工作、連續呼叫工具,再把結果整理成 patch、摘要或測試報告。團隊若只盯著「它讀了哪些檔案」,很容易漏掉資料從哪裡繞回 Context,以及最後被寫到哪裡。

GitHub 補上的是直接讀檔這一層

GitHub 在 2026 年 9 月宣布,Copilot app 與 Copilot CLI 已普遍支援 content exclusions。Copilot Business 與 Enterprise 的管理者可以在 enterprise、organization 或 repository 層級設定排除規則;符合規則的檔案不會被拿來當作 Agent Context。

這是一條清楚而且有用的 read policy。但官方承諾的範圍也很具體:excluded files 不作為 Context。它不該被自行擴寫成 DLP、subprocess sandbox,或「所有工具回傳都已過濾」。第三方 Agent、使用者手動貼上的內容,以及 shell 實際吐回什麼,也不能直接套用同一份保證。

VS Code 的 Agent 工作流已經能跨多個 workspace root 維持 session。工作範圍愈大,單靠 path exclusion 愈不夠。比較可靠的做法,是把 Agent 的 Context perimeter 拆成四個 surface:直接讀檔、工具回傳、輸出落點與動作核准。

其中,第一層已有現成的 content exclusion 可以用;後面三個洞,通常還得由團隊自己補。

洞一:Tool return 是另一條輸入管道

Agent 看不到 .env,不代表它看不到 .env 裡的值。下面這些輸出都可能把敏感資料帶回模型:

  • 測試失敗時印出的 request header;
  • stack trace 裡展開的連線字串;
  • env、診斷指令或 build script 的 stdout;
  • 測試報告內嵌的 payload 與 fixture 內容。

禁止讀檔抓不到這條路。我的做法會是替高風險指令加一層 wrapper:限制可傳入的參數,在 stdout 與 stderr 回到 Agent 前先遮罩,完整原始 log 則留在權限較嚴格的系統裡。Agent 多半只需要 exit code、失敗案例名稱與去識別化的錯誤摘要,不需要整包環境變數。

規則寫完還不算完成。刻意塞入一個假的 canary token,讓測試、build 與診斷流程都跑過一次,再檢查 tool result 有沒有出現它。這比看設定檔猜「應該擋到了」可靠得多。

洞二:Agent 寫出的東西也會擴散資料

Context perimeter 不能只管輸入。Agent 可能把讀到的內容寫進:

  • patch、commit message 或 PR 摘要;
  • snapshot、測試報告與 debug log;
  • 瀏覽器截圖、操作錄影或暫存檔;
  • 下次 session 會重新載入的記憶與交接文件。

這些產物不一定立刻離開電腦,卻可能在下一步進版控、被 CI 上傳,或進入另一個 Agent 的 Context。事故常發生在這裡:來源檔案守得很嚴,tmp/ 裡的輸出卻沒人管,最後又被某個 artifact upload step 打包送走。

每一種 Agent 任務都該先指定可寫入目錄、保留時間與版控規則。敏感工作流最好採預設拒絕,只開放少數輸出位置;準備提交前,再掃描 staged diff 與待上傳 artifact。這不是把責任推給 secret scanner,而是避免「能寫到任何地方」成為預設能力。

洞三:測試素材本身就可能過界

不少團隊把 production code 管得很嚴,卻把測試資料當成免費的 Context。真實資料庫 dump、客服附件、客戶截圖與原始照片,常被直接丟進 fixture,因為它們最容易重現問題。

測試真正需要的通常只是少數特徵,例如特定欄位組合、長字串、透明背景或某個長寬比。先把姓名、帳號、定位資訊及不必要的 metadata 拿掉,再重建一份只保留必要特徵的 fixture。若圖片測試只在意尺寸與版型,可以用在瀏覽器本機處理、來源圖片不必上傳的 Resize Image For 製作固定尺寸素材;但去識別化仍要在素材進入 Agent 工作流前另外完成,不能把「有縮圖」當成「已脫敏」。

這一層的判準很簡單:fixture 外洩時,能不能連回真實的人、客戶或正式系統?如果可以,它就不是測試資料,只是換了目錄的正式資料。

能讀和能做,要拆成兩份政策

Context 管的是 Agent 看得到什麼;action policy 管的是它能改什麼。兩者有關,卻不能共用一個模糊的「Agent 已授權」開關。

GitHub 近期讓 Copilot code review 可以送出 approval,管理者也能依層級與 repository file paths 控制這項能力。這剛好提供一個對照:某個 Agent 能看 PR diff,不代表它就該核准、合併、部署或修改 repository 設定。讀取範圍與動作權限需要不同的 owner、證據和升級流程。

例如文件修正可以允許 Agent 直接開 PR,但 production deployment 仍要求值班者核准;一般程式碼可執行測試,高風險 migration 則只能產生 dry-run 計畫。權限要跟著任務與影響範圍走,不要跟著「這個工具看起來很聰明」走。

把 Context perimeter 寫進 Repo Contract

下面不是 GitHub 官方 schema,而是一份可以放進 repository、交給團隊自行實作的最小契約:

surface: coding-agent
allowed_inputs:
  - src/**
  - tests/fixtures/sanitized/**
excluded_paths:
  - .env*
  - customer-data/**
redaction_rule:
  - mask authorization headers in stdout and stderr
  - block known canary tokens from tool results
write_targets:
  - tmp/agent-output/**
  - docs/agent-runs/**
approval_owner:
  merge: service-owner
  deploy: on-call-engineer
verification:
  - direct-read-denied
  - tool-output-redacted
  - write-target-contained
  - action-escalation-blocked

欄位名稱可以換,四種負面測試不要省:

  1. 直接要求 Agent 讀取排除路徑,確認它拿不到內容。
  2. 讓允許的指令間接印出 canary token,確認回傳前已遮罩。
  3. 指示 Agent 把產物寫到白名單外,確認系統拒絕。
  4. 讓低權限任務嘗試 merge 或 deploy,確認它只能提出核准請求。

測試結果還要記錄 Agent、client、版本與執行時間。否則下一次 CLI、IDE extension 或 policy 更新後,團隊很難知道舊結論還能不能用。

排除清單只是第一道門

Content exclusions 解決了一個明確問題:管理者可以阻止特定檔案直接進入 Copilot app 與 CLI 的 Agent Context。把它打開是合理的第一步,但別在設定頁看到綠色狀態就停下來。

完整的邊界必須回答四件事:Agent 能直接讀什麼,工具會回傳什麼,它能把結果寫去哪裡,以及哪些動作一定要找人核准。每一項都做過負面測試後,這份 policy 才從路徑清單變成可執行的工程契約。

參考資料


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言