沙箱管理器:把權限檔案編譯成一行命令
工作區可寫,網絡收緊。同一條 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 會不會改口。