沙箱管理器:把權限檔案編譯成一行命令
工作區可寫,網路收緊。同一條 git status,Mac 套上 sandbox-exec,Linux 套上 helper,Windows 可能原樣出門。差別出在編譯器。
environment_context。
還沒渲染。
- 讀入 PermissionProfile 三態models.rs L411
- 疊上 additional permissionspolicy_transforms.rs L525
- Auto 則跑 should_require_platform_sandboxpolicy_transforms.rs L541
- select_initial 再問 get_platform_sandboxmanager.rs L62
- None 則原樣傳出 argvmanager.rs L366
- macOS 前置 /usr/bin/sandbox-execmanager.rs L401
- Linux 序列化檔案給 helperlandlock.rs L23
- Windows 第一拍不改 argvmanager.rs L447
- 同一份檔案渲染進 environment_contextenvironment_context.rs L96
同一份倉庫,三臺機器,模型發出同一條 git status。配置裡寫的是同一份權限檔案:工作區可寫,網路收緊。
排障的人會以為沙箱沒生效。日誌裡檔案還在,模型上下文裡那份 environment_context 也還在。只是平臺這一層沒有把檔案編譯成包裝命令。Windows 上開關關著,編譯器交出原 argv,策略層還在。
SandboxManager 先問要不要,再問有沒有。should_sandbox 只返回一個布林。Forbid 恆假,Require 恆真,Auto 看檔案形狀。有託管網路要求,必須上。網路收緊時,除了呼叫方自己管檔案系統,都要上。網路放開且檔案系統不受限,才跳過。
出處:codex-rs/sandboxing/src/manager.rs 第 310 至 329 行 · codex-rs/sandboxing/src/policy_transforms.rs 第 541 至 561 行
然後 get_platform_sandbox 按作業系統給型別。macOS 給 Seatbelt,Linux 給 seccomp helper。Windows 多一個開關,關著就是空。空的意思是這臺主機沒有可派發的實現。
出處:codex-rs/sandboxing/src/manager.rs 第 62 至 76 行
select_initial 先問前者,再把後者的空收成 SandboxType::None。檔案說需要,主機給不出,型別仍是 None。
出處:codex-rs/sandboxing/src/manager.rs 第 293 至 306 行
配置裡的意圖和主機上的後端,本來就會分手。產品文案、狀態列、模型說明如果都去讀配置裡希望啟用的那一側,排障會從這裡開始歪。兩個函式,一個返回布林,一個返回可選的後端名。換語言重寫也用得上。
權限如果寫成兩份,改了一邊忘了另一邊,模型就會按舊邊界規劃下一步。模型看見沒有外層沙箱,和 Windows 關沙箱時落到 None,應該是同一份意圖的兩個出口。
PermissionProfile 三個變體寫的是誰負責建外層沙箱。Managed 由 Codex 自己拼包裝命令。Disabled 不要外層。External 檔案系統由呼叫方負責,網路仍可能歸 Codex 管。
出處:codex-rs/protocol/src/models.rs 第 411 至 425 行
transform 按型別分派。None 原樣傳出使用者 argv,連本機 cwd 都不準備,因為未沙箱的請求可能帶著外機路徑。macOS 只信任 /usr/bin/sandbox-exec,策略走 -p,路徑走 -D,使用者命令放在 -- 後面。Linux 把整份檔案序列化進 --permission-profile,helper 缺失直接報錯,不會按無沙箱降級。Windows 第一拍只校驗,argv 不動;包裝器就是當前 exe,套殼推遲到 transform_for_direct_spawn。
出處:codex-rs/sandboxing/src/manager.rs 第 365 至 459 行 · codex-rs/sandboxing/src/seatbelt.rs 第 52 至 56 行 · codex-rs/sandboxing/src/landlock.rs 第 15 至 23 行 · codex-rs/sandboxing/src/manager.rs 第 484 至 518 行
同一份檔案由 FileSystemContext 收成內部列舉,渲染進 environment_context。Disabled 寫成 type="disabled" 加 unrestricted 檔案系統。模型可見文字擋不住越權,只減少無效嘗試。
出處:codex-rs/core/src/context/environment_context.rs 第 96 至 116 行
執行時事實只應有一份。隔離發生在子行程入口,編排層繼續拿路徑和檔案,到執行邊界才真正生效。平臺方言會變,這份同時餵給包裝命令和模型的檔案形狀用得上。
單條命令還可以再帶一份 overlay。如果人批的時候用並集,一次誤批就能把請求裡沒有的路徑寫進會話授權。
合併走並集:任一側開啟網路,結果就是開網;檔案系統條目首尾相接去重。求交走另一套:網路必須兩側都開才留下;檔案系統只保留落在請求範圍內的已批條目。求交結果為空,會話不記帳,基座檔案繼續生效。空集的含義是這次額外開口沒留下任何加寬。命令還能不能跑,要看後面的策略和沙箱。
出處:codex-rs/sandboxing/src/policy_transforms.rs 第 90 至 142 行 · codex-rs/sandboxing/src/policy_transforms.rs 第 144 至 214 行 · codex-rs/core/src/session/mod.rs 第 2833 至 2846 行
加寬和批准是兩件事。並集讓這條命令多開一條路徑這件事說得清。求交保證人批下來的不寬過請求。空集表示開口失敗,不要解釋成改成最嚴,也不要解釋成整條命令禁止。
DeepSeek Harness:缺後端就拒絕執行
DSH 也切在子行程入口。confine 按當前主機選 runner,再把政策編成 runner 參數,使用者命令放在 -- 後面。檔案詞彙只有三個檔案模式,danger-full-access 不進包裝。
缺後端時 fail closed,不退回原 argv。文案寫明 refusing to run the command unconfined。Codex 在 Unix helper 缺失時同樣不跑;Windows 關沙箱時把給不出實現收成 None,交給後面的策略層。
Grok:一次 apply,鎖住當前行程
Grok 也有一個叫 SandboxManager 的型別,職責是 apply() 再 install()。註釋寫明:作用物件是當前行程,不可逆。編譯產物是 CapabilitySet,不包每條命令的 argv。
平臺不支援,或 apply 失敗,都打警告、記 apply_failed,然後繼續跑。後面的工具呼叫共享同一份 capability。Grok 不用為每條命令再編 argv,也沒法在同一行程裡給兩條命令兩套邊界。
出處:packages/sandbox/sandbox-local/src/index.ts 第 316 至 333 行 · crates/codegen/xai-grok-sandbox/src/lib.rs 第 117 至 136 行
四條返回,三組輸入
開啟 should_require_platform_sandbox,用紙畫出四條返回。然後對下面三組給出預測:Disabled 檔案加託管網路;根可寫加一條 deny、網路 Enabled;External 檔案、網路 Restricted。
進階一問:同一份 Disabled 檔案,工具宣告 Require,Windows 檔位仍關著。型別會是什麼,模型看見的 XML 會不會改口。