上一篇討論了怎樣判斷一個動作應不應該執行。這一篇把問題交給操作系統:即使 Agent 已經提出了越界動作,怎樣讓執行環境直接拒絕它?
對於 Coding Agent,限制不能只停在工具名稱或提示詞裏。它會啓動 Shell,Shell 再運行 Git、Python、測試程序和子進程。真正的邊界需要覆蓋這些程序訪問文件和網絡的過程。
本文以 OpenAI 於 2026 年 5 月發佈的《Building a safe, effective sandbox to enable Codex on Windows》為案例,按進程、文件權限、網絡身份和啓動架構展開。當前官方文檔已列出 MXC 等實現,下面研究的是原文中的 Restricted Token、專用用户與 Firewall 組合,不把它當作當前唯一方案。
仍用一個假設任務貫穿説明:Agent 修復項目中的 CSV 解析問題,並運行本地測試。它需要讀項目、修改源碼和啓動開發工具,但不應隨意修改項目外文件,或向外部發送資料。以下權限例子用於解釋機制,不會修改當前電腦的 ACL、賬號或防火牆。
一、Sandbox 約束的是哪些執行對象h2
Sandbox 是受約束的執行環境,不是讓模型“更謹慎”的另一份提示詞。要建立這種環境,先要找到動作真正落地的位置。
1. Process Tree:從工具入口覆蓋到子進程h3
模型提出一個執行請求,Harness 在本機啓動程序,程序再訪問文件、創建進程或連接服務。操作系統看到的是進程和訪問請求,不是“這次推理的意圖”。
因此,限制的對象不應只有 Agent 的主程序。假設它啓動 Shell,Shell 再啓動 Python,Python 又運行測試子進程,如果只有最上面的程序受限,真正處理數據的程序仍然可能擁有過大的權限。
進程樹是執行邊界的覆蓋範圍,而不是後台實現細節。 一次命令改用不同的解釋器,不能因此獲得原先沒有的寫入或聯網能力。
這裏也要區分 Agent 主程序與它執行的命令。主程序負責會話、模型交互和調度;受限工具進程負責實際工作。兩者不一定使用同一個身份或擁有相同權限。
2. 隔離方案:原生進程、AppContainer 與 VM 的取捨h3
Windows 有多種安全原語,但“存在隔離機制”不等於“直接適合任意開發工作流”。原文比較過 AppContainer、Windows Sandbox VM 和 MIC 完整性級別,最終選擇組合其他機制。來源:OpenAI 設計案例
AppContainer 更適合預先明確能力的應用;Coding Agent 卻需要驅動多種現成工具。VM 能提供較強環境隔離,但要處理工具準備、真實工作區訪問和宿主機銜接。MIC 可以限制低完整性進程寫入更高完整性的對象,但改變工作區標籤,也會改變其他低完整性進程訪問它的條件。
這些不是對某種機制“不安全”的簡單評價,而是不同安全模型與產品需要之間的匹配問題。只給某個 Sandbox 身份增加定向權限,與改變整個目錄的通用信任級別,影響範圍並不相同。
對 CSV 修復任務來説,設計目標是讓已有工具正常運行,同時限制它們的真實訪問。關鍵不在於隔離功能的名稱,而在於:能夠準確約束哪些動作,又需要改變宿主環境的哪些條件。
二、Windows 怎樣判斷文件寫入權限h2
文件限制需要把“進程以誰的身份運行”和“對象允許誰訪問”連接起來。Windows 中的 SID、Token 與 ACL 分別承擔不同角色。
3. SID 與 ACL:身份標識和對象權限h3
SID(Security Identifier)是 Windows 安全主體的標識。用户、組等可以有 SID;它不是模型生成的訪問理由,也不是路徑字符串。
ACL 是訪問控制項的集合。其中 DACL 決定哪些主體被允許或拒絕訪問對象,條目會描述對應主體及讀、寫等權利。進程訪問文件時,系統依據 Token 中的身份信息與對象權限進行檢查。具體語義見 Microsoft 的 ACL 文檔。
可以把三者的關係理解為:
- SID: 權限規則在識別誰。
- Token: 當前進程攜帶什麼身份與權限信息。
- DACL: 目標對象允許或拒絕哪些訪問。
合成 SID 則提供了一種定向標記:它可以出現在訪問控制規則中,而不必對應一個真實登錄用户。這樣能表達 Sandbox 特有的權限,不必把整個工作區變成“任何低權限程序都能寫”的目錄。
但“創建了 SID”本身沒有隔離效果。只有把它接入對象權限和進程的訪問檢查,身份標記才成為可執行的約束。
4. Write-restricted Token:對寫入增加一層檢查h3
Restricted Token 可以減少權限,或加入 restricting SIDs。系統進行相應訪問檢查時,既檢查通常的身份權限,也檢查限制列表;兩邊都通過才允許訪問。WRITE_RESTRICTED 則讓 restricting SIDs 的額外檢查用於寫訪問。見 Microsoft 的 CreateRestrictedToken 文檔。
對寫入請求,可以用下面的關係理解,而不是把額外 SID 當成新的管理員權限:
允许写入 = 通常的身份权限检查通过 AND restricting SID 检查通过假設一套教學權限只允許在項目源碼目錄寫入,項目外目錄沒有通過第二項檢查的授權:
| 寫入目標 | 通常的身份檢查 | 限制檢查 | 結果 |
|---|---|---|---|
| 項目源碼文件 | 通過 | 通過 | 可以寫入 |
| 用户可寫的另一個目錄 | 通過 | 不通過 | 拒絕寫入 |
| 普通身份無權修改的系統文件 | 不通過 | 無論如何 | 不能寫入 |
這解釋了為什麼“開發者能改這個文件”不等於“受限工具進程也能改”。額外檢查是在縮小能力,而不是繞過原來的權限。
實際結果仍取決於完整的 SID 列表和對象 ACL。如果某個廣泛主體已有過寬的授權,不能只看合成 SID 的配置就斷言邊界正確。當前官方文檔也提示,Everyone 可寫目錄可能影響保護效果。
另一個區別同樣重要:限制寫入不等於限制讀取。 在 WRITE_RESTRICTED 下,不能僅憑這項額外檢查就推導“項目外文件全部不可讀”。機密性需要另外核對讀取權限和數據出口。
三、網絡限制為什麼需要獨立身份h2
文件系統能阻止越界寫入,並不意味着資料無法發送出去。網絡訪問需要自己的強制機制,也需要準確識別受限進程。
5. Network Enforcement:環境約定與系統強制h3
讓常用工具使用一個不可用代理,能夠阻止部分聯網;讓命令搜索路徑優先命中禁用腳本,也能影響某些工具行為。但這些辦法依賴程序遵守約定。
一個程序可能不讀取代理變量,直接使用網絡接口。它不必懷有攻擊意圖,也可能因為自己的實現方式沒有采用這些設置。工具恰好無法聯網,與系統不允許它聯網,是兩種保證。
這也是為什麼網絡限制不能只靠 Shell 包裝。與提示詞相比,環境變量更靠近執行,但仍不是所有程序都必須經過的檢查點。
同樣,僅針對 Agent 主程序設置規則,不能覆蓋它啓動的其他工具;把某個常用解釋器整體禁網,又可能影響用户平常的開發。需要的是識別這次受限工作,而不是粗略禁止整個機器上的某個程序名稱。
6. Principal 與 Firewall:區分受限工作和用户日常操作h3
Principal 可以理解為系統識別並施加權限的安全主體。合成 SID 可以幫助文件訪問檢查,但不等於它在所有策略系統裏都能直接作為獨立用户使用。
原文從當前用户的受限 Token,演進到專用的 Online / Offline 用户,並把網絡規則施加到 Offline 身份。目的就是讓規則覆蓋這類受限命令,而不影響開發者所有同名程序。來源:原文的網絡與身份設計
例如,同一台機器上的兩個 Python 進程,一個屬於開發者的正常工作,另一個屬於離線 Sandbox。按身份區分之後,才能針對後者限制出站訪問,而不是把所有 Python 一起禁網。
Online 與 Offline 也不是“完全放權”和“完全隔離”的同義詞。是否聯網是一項策略,文件寫入是否受限又是另一項策略;改變網絡條件,不應被理解為自動取消所有文件約束。
專用用户在這裏首先是本機執行身份,不是模型賬號,也不自動代表對雲服務的授權。遠程服務仍會依據各自的憑證和權限判斷操作。
四、初始化與命令執行怎樣連接起來h2
當文件規則、網絡規則和專用身份分屬不同機制,就需要一個明確啓動過程,把它們應用到真實命令,而不是隻保存為配置。
7. Setup 與 Runner:初始化權限和受限執行h3
初始化階段負責準備賬號和系統策略,運行階段負責在這些條件下啓動命令。二者的權限需求不同。
原文將需要管理員權限的準備工作放入獨立 Setup 程序,再由普通用户 Harness 啓動專用用户身份下的 Runner,Runner 創建受限 Token 後啓動工具。這個拆分解決了跨用户啓動與受限 Token 創建之間的銜接。來源:原文的啓動架構
為什麼不能由 Harness 一步完成?直接使用另一個用户的 Token 啓動受限進程,會遇到 Windows 的權限要求。先讓 Runner 以目標用户身份運行,再使用自身 Token 的受限版本創建工具進程,就把最後一步放到了目標身份一側。微軟的 Restricted Tokens 文檔也説明了使用自身受限 Token 創建進程時的權限條件。
理解這條鏈時,要分清兩件事:管理員初始化是在建立約束,不是在給每次 Agent 命令提供管理員權限。 Runner 也不是讓模型獲得一個高權限 Shell,而是把最終工具進程放進受限安全上下文。
這條鏈的價值在於職責分離:Setup 建立系統條件,Harness 組織動作,Runner 負責受限啓動,工具實際完成任務。初始化成功不等於每個命令都已受限,還要檢查最終進程是否真的使用了正確 Token、身份與策略。
8. 兼容性與剩餘風險:讀取、宿主環境和邊界覆蓋h3
換成專用用户以後,原本能讀取的開發工具、項目路徑和用户配置,可能因為身份變化而不可訪問。為了可用性補充讀取權限,又需要確認沒有無意擴大敏感資料的暴露範圍。
這説明兼容性不是與安全無關的體驗細節。邊界過窄會讓正常開發失敗;邊界過寬會讓隔離失去意義。需要把缺失能力定位到具體資源,而不是遇到一次失敗就取消整個 Sandbox。
ACL 方案還會改變真實宿主文件的權限狀態。配置可寫目錄、處理繼承或遷移項目時,需要考慮已有規則是否仍然正確。它不是一個與宿主機無關、銷燬後自動清除一切影響的臨時空間。
最後,進程約束也有覆蓋範圍。一個在邊界外運行的高權限連接器,不會僅因為它由同一個 Agent 使用,就自動受 Shell Sandbox 保護;一個已經獲得遠程服務憑證的工具,也需要單獨檢查它能操作什麼。
因此,評價 Hard Containment 應當具體到:限制哪些進程,檢查哪些訪問,使用什麼身份,以及是否存在其他執行入口。模型解釋可以改變動作選擇,但不應改變這些資源規則;規則本身的正確性和覆蓋範圍,則仍然需要工程驗證。
幾個關鍵問題,串起身份、權限與執行邊界h2
為什麼只給 Agent 主程序加限制還不夠?
實際文件和網絡操作常由 Shell、解釋器或測試子進程完成。邊界需要覆蓋受限工作產生的進程樹,而不是隻覆蓋會話入口的程序名稱。
SID、Token 與 ACL 分別負責什麼?
SID 標識主體,Token 攜帶進程的安全上下文,ACL 描述對象允許或拒絕的訪問。三者要在操作系統檢查中配合,單獨創建一個身份標記不會自動形成 Sandbox。
Write-restricted Token 為什麼能限制用户原本可寫的目錄?
寫入不僅要通過通常的身份檢查,還要通過 restricting SID 檢查。用户可寫只説明第一項可能通過,不能替代第二項。實際授權仍要核對完整 Token 與 ACL。
限制寫入是否意味着項目外文件不可讀?
不是。WRITE_RESTRICTED 的額外檢查針對寫訪問,讀取範圍需要另外確認。只保護數據不被修改,不能自動保護數據不被讀取或發送。
把代理指向不可用地址,為什麼不是強網絡隔離?
因為程序可以不採用代理設置,直接進行網絡訪問。真正的強制策略需要在程序無法憑自身選擇繞開的檢查點執行,並準確覆蓋受限進程。
為什麼引入專用用户,而不是隻靠合成 SID?
不同策略機制識別身份的方式不同。原文用合成 SID 參與文件檢查,再用專用 Principal 將網絡規則關聯到受限工作,從而區別於開發者的普通進程。
管理員初始化是否意味着 Agent 命令以管理員運行?
不意味着。初始化用較高權限準備賬號和策略,日常工具則以受限身份執行。兩者分離,正是為了不把配置邊界所需的權限交給任務命令。
Sandbox 能保證項目修改正確嗎?
不能。它限制的是操作能力和影響範圍。允許目錄內仍可能出現錯誤修改,因此測試、Review 與恢復機制仍然有必要。