chainlesschain 0.162.182 → 0.162.184
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DzZ5_xoj.js → AIOps-DzAl5fGx.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DeLXddIg.js → ActionButton-DAHtMGeC.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-rvDCmet1.js → Analytics-BHQaexv5.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Yt6QVDnp.js → AppLayout-Phz_pD0n.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-BS112K5L.js → Artifacts-DHt47kCA.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-0wJuQrNu.js → Audit--Y_8FULl.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-B90PMgbn.js → BackgroundAgents-N1zchH7D.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-TkgMglQQ.js → Backup-B_BoyN30.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CQVS9p1l.js → BaseInput-Gl4uQHcT.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-YTjQHoC7.js → Chat-Cg-eIyAZ.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BzeUi3JH.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-5bwaOabq.js → Checkbox-D0MGR2wA.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BFmNQ_Xe.js → Codegen-BdObJEFn.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BT_u4Dzp.js → Col--ghxXT3z.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CJP52u5b.js → Community-BUFeXOqz.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BpzhJE9i.js → Compact-DhQO2_Mr.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Cg7rfslp.js → Compliance-3HoTqKYd.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-JisxL6Yy.js → Cowork-B3zmO4VW.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Bu7Ug_MC.js → Cron-CJDrZOcc.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CvuqoLdj.js → Crosschain-SMl15obd.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C2u9G8Pu.js → DID-CgTrTWrl.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BFt5Yv3d.js → Dashboard-dXFKaKol.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DIaT9Wxq.js → Dropdown-qQHEhCvI.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-D_A601Y4.js → EmailListRenderer-C_ej0MWH.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard--IyQ8I8w.js → FamilyGuardDashboard-D6ajoE7I.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BihWHxuY.js → Federation-Cio2y49h.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BB8dOXc_.js → FormItemContext-ClJz1cYp.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DQYhj1HH.js → GenericCardRenderer-Dr_8Maca.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B-2QZxGf.js → Git-CevLwp5u.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CusSb-nG.js → Governance-CW9YyQUY.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BAjmvPPL.js → Inference-CQqeAyER.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DoNYWKYq.js → KnowledgeGraph-cuGVxHrw.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-B8fKWD-n.js → Logs-DIuHri5d.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BlJm1J7E.js → MarkdownRenderer-R91Qw5JA.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CyOscbSL.js → Marketplace-CY1VhFGx.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Ex6Om5da.js → McpTools-BBAbi1vt.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CDcD8l8r.js → Memory-BWYGHxJA.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-xfBqoFDg.js → MobileBridge-CPIFkW7A.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BwObMMA2.js → MobileProjects-DQyWxCho.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CIWd36OV.js → Mtc-Bo3GnQbx.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CPX0ouuA.js → MtcAudit-C8-c4rSW.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BDJsIUuW.js → Multisig-ChqMTtoq.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DEkbuD3N.js → NLProgramming-C48TyhvI.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DJpHRhH1.js → Notes-zogUFWxp.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C1UZ-Qd5.js → NotificationSettings-v-K9XpSB.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-P94JGGNz.js +1 -0
- package/src/assets/web-panel/assets/{Organization-Bbhj0fac.js → Organization-Boi1dQfR.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-1H04x3kx.js → Overflow-DM5YWwgA.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CDpPe3et.js → P2P-C57LKpKK.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-MUX0Bpvw.js → PdhVaultBrowser-BFkPqu6Q.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-A07-0Ci1.js → Permissions-D6fB9YSp.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DhhDWxAZ.js → PersonalDataHub-Bp7EefEo.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-CyfbJfe-.js → Pipeline-BVln3hZf.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CNFps3ED.js → Privacy-Bf8P3nF6.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit--T-u3Dr5.js → ProjectInit-DM6wA2E2.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DJmrK2fC.js → ProjectSettings-CGbc5Iho.js} +2 -2
- package/src/assets/web-panel/assets/Projects-D0p9EOxm.js +1 -0
- package/src/assets/web-panel/assets/{Providers-DLzzbOZd.js → Providers-B2kJcxS6.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CexOomKS.js → QrScannerModal-Cxu7dXYy.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-QklGi19_.js → QuickAsk-DTlrTPms.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bb9kwSw8.js → Recommend-Cm3X-cCj.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DZuVNNN5.js → RemoteSession-DNb2kjvt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Dr5cLP0N.js → Reputation-CZUFFjc1.js} +1 -1
- package/src/assets/web-panel/assets/{Row-oCQHYv5t.js → Row-DAPgloxA.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-IFDEykIR.js → RssFeed-dsx9S793.js} +2 -2
- package/src/assets/web-panel/assets/{Search-CspVIxDc.js → Search-DnnC8kz-.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Bm66o_DH.js → Security-VuZknRMK.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DvanNqXl.js → Services-B3XNX8Vx.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CHjEe9_O.js → Skeleton-Dl1nVtCj.js} +1 -1
- package/src/assets/web-panel/assets/Skills-CY09CZ_W.js +1 -0
- package/src/assets/web-panel/assets/{Sla-DxZm1491.js → Sla-HzU56n1z.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DWxEEclC.js → SpeechSettings-CRle7Jl2.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-FIvOFw5p.js → SyncSettings-DWadz7Sl.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CNVTDGg8.js +1 -0
- package/src/assets/web-panel/assets/{Templates-CaNjzV_t.js → Templates-BBAgvrlM.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DjlP6TmH.js → Tenant-BsbbvGN8.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-uscpZI4q.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-DoZ8y7y8.js → TimelineRenderer-mTyjNE6r.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-390cg2TC.js → Tokens-Bz97oBgs.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CLrtCj5_.js → Trigger-BTRKC140.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DpESfSPn.js → Trust-B4A_KuyX.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CN6279O0.js → UkeySign-DES9TmLU.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DPtAUlSe.js → VideoEditing-ClXs7Qxp.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-nKOMV_1n.js → Wallet-IzZqFz-7.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-HuXlSOc4.js → WebAuthn-BtOP04g_.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CUfFjARi.js → WorkflowEditor-_0cqnopY.js} +1 -1
- package/src/assets/web-panel/assets/{chat-6Eq0PcZJ.js → chat-ax7193uU.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BP_Sf6Iy.js → colors-Bu4WGJah.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BufMKIh5.js → compact-item-BX1dlTW0.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BBMXxWSW.js → createContext-CktA_Dj7.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-x877iKKS.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-fUK_tRO2.js → hasIn-D5wd817l.js} +1 -1
- package/src/assets/web-panel/assets/{index-t8N1tSeX.js → index-5PYYkr8S.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLpIs_P_.js → index-A4uBPQCz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVsqvI4M.js → index-BAtBNfkr.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bkg4ZePE.js → index-BLLsUNDc.js} +1 -1
- package/src/assets/web-panel/assets/{index-cpEli44X.js → index-BQtoRyTO.js} +1 -1
- package/src/assets/web-panel/assets/{index-wKTLbKyc.js → index-BRfXoRuh.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7Etk0Te.js → index-Bad2CYeH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwSf5pnf.js → index-BcGdL3sG.js} +1 -1
- package/src/assets/web-panel/assets/{index-3FuwBewR.js → index-C3HmzCLt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHy6yNiF.js → index-C8DkWyNr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgiECHu2.js → index-C8tLR2TG.js} +1 -1
- package/src/assets/web-panel/assets/{index-C44atv4k.js → index-CP8ELJBc.js} +1 -1
- package/src/assets/web-panel/assets/{index-CW_G-MXw.js → index-CUForzsG.js} +1 -1
- package/src/assets/web-panel/assets/{index-pum7HYBA.js → index-CYRE0NJA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BWKoBU8R.js → index-CeVZaJSC.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4_MuGkd.js → index-CfzxR61U.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dyngbd29.js → index-Ci3y1ZAv.js} +19 -19
- package/src/assets/web-panel/assets/{index-fzaMtSJ8.js → index-CjEJjl5C.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cp8vhyZy.js → index-Cv7bVWJ5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPdUNk1i.js → index-D-o4Rwjk.js} +1 -1
- package/src/assets/web-panel/assets/index-D7pfPouB.js +1 -0
- package/src/assets/web-panel/assets/{index-CeASi4fr.js → index-D9op8poE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DASluSqY.js → index-DF1TysIF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DocdRcbd.js → index-DYo9S5OT.js} +1 -1
- package/src/assets/web-panel/assets/{index-2A5ph8b2.js → index-D_cycOET.js} +1 -1
- package/src/assets/web-panel/assets/{index-wV6iGdpY.js → index-Db3CpWTr.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMLHv389.js → index-DkD1K-fF.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9WYSn4m.js → index-DmPJ6T6F.js} +1 -1
- package/src/assets/web-panel/assets/{index-uCbEN7cY.js → index-DmVUeWUk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmkMXwnR.js → index-Dzdr0zDf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZ6Yt17L.js → index-PBLzwYnu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE2DdTP2.js → index-bFCaM7Eq.js} +1 -1
- package/src/assets/web-panel/assets/index-e4i-VLBd.js +1 -0
- package/src/assets/web-panel/assets/{index-GwdRUZ-x.js → index-h3KJZr95.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2vS66eI.js → index-iHcPtQ2e.js} +1 -1
- package/src/assets/web-panel/assets/{index-6GmBa4Kg.js → index-jzlzm4VK.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9vU25ij.js → index-o14NNnxw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGjmILDm.js → index-tYPSfGbd.js} +1 -1
- package/src/assets/web-panel/assets/{index-LvCBfTLo.js → index-ytp2H5Zx.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-V5Fo95FM.js → initDefaultProps-D2Iut83B.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BYWU0hUT.js → motion-BuaJVdK9.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cr1M-J2h.js → move-CaEuM92y.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BysQKi2N.js → mtc-parser-wuKNBwys.js} +1 -1
- package/src/assets/web-panel/assets/{omit-D1zHU8GC.js → omit-7a3eklaq.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CUArxtfi.js → pickAttrs-Dn4z7KvJ.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-ChoYEys0.js → placementArrow-DVn_qT4-.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BQRs3Mo7.js → responsiveObserve-Dodz1OMQ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-B8zbsCkg.js → slide-CxoGskbp.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C2U8Gs6h.js → statusUtils-DBh_epQH.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Dd8MgL_V.js → styleChecker-RXQ4gG5P.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-hknqY5NH.js → useFlexGapSupport-1Wxm0HEG.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CLTAmcfw.js → useFs-CI_ySNxJ.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-ByegHbiB.js → usePersonalDataHub-C6973rZP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DqlAy5DP.js → vnode-CalynwKr.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DiXiztQn.js → zoom-CM1cd-Q0.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +74 -1
- package/src/commands/agent.js +9 -0
- package/src/commands/background-session.js +60 -1
- package/src/commands/batch.js +160 -5
- package/src/commands/plugin.js +318 -43
- package/src/commands/session.js +44 -1
- package/src/commands/team.js +212 -6
- package/src/data/changelog.json +26 -0
- package/src/harness/jsonl-session-store.js +59 -6
- package/src/harness/mcp-client.js +65 -43
- package/src/lib/agent-batch.js +4 -1
- package/src/lib/agent-team/team-runner.js +19 -1
- package/src/lib/agent-team/team-worktree.js +3 -0
- package/src/lib/async-hook-supervisor.cjs +82 -10
- package/src/lib/async-hook-supervisor.js +50 -4
- package/src/lib/background-agent-supervisor.js +49 -0
- package/src/lib/collaboration-run-store.js +362 -0
- package/src/lib/hook-runner.cjs +98 -17
- package/src/lib/hook-runner.js +77 -6
- package/src/lib/hook-shell-command.cjs +148 -0
- package/src/lib/hooks-v2-runtime.js +188 -77
- package/src/lib/jsonl-session-store.js +2 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +18 -0
- package/src/lib/lsp/lsp-client.js +12 -1
- package/src/lib/plugin-monitor-supervisor.js +53 -16
- package/src/lib/plugin-runtime/bin.js +1 -1
- package/src/lib/plugin-runtime/install.js +465 -54
- package/src/lib/plugin-runtime/mcp.js +21 -2
- package/src/lib/plugin-runtime/monitors.js +19 -3
- package/src/lib/plugin-runtime/sandbox-policy.js +99 -0
- package/src/lib/plugin-runtime/scopes.js +13 -2
- package/src/lib/plugin-usage-attribution.js +44 -0
- package/src/lib/process-execution-broker/index.js +705 -13
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +1347 -0
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +1260 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +1831 -157
- package/src/lib/session-usage.js +278 -1
- package/src/lib/stream-retry.js +29 -0
- package/src/repl/agent-repl.js +38 -9
- package/src/runtime/agent-core.js +32 -4
- package/src/runtime/headless-runner.js +46 -1
- package/src/runtime/headless-stream.js +54 -3
- package/src/runtime/mcp-config.js +15 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-PR074hUN.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-GlJtqLjT.js +0 -1
- package/src/assets/web-panel/assets/Projects-Qx_MdX9k.js +0 -1
- package/src/assets/web-panel/assets/Skills-Cb8jWjMX.js +0 -1
- package/src/assets/web-panel/assets/Tasks-CyuLnDFR.js +0 -1
- package/src/assets/web-panel/assets/Terminal-DwzGMniO.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DgVKduH2.js +0 -1
- package/src/assets/web-panel/assets/index-DOZTSoS7.js +0 -1
- package/src/assets/web-panel/assets/index-DhpvjpqI.js +0 -1
|
@@ -38,7 +38,13 @@ import {
|
|
|
38
38
|
postSpawnSandbox as _postSpawnSandbox,
|
|
39
39
|
SANDBOX_BOUNDARIES,
|
|
40
40
|
} from "./platform-sandbox.js";
|
|
41
|
+
import {
|
|
42
|
+
admitLinuxGenericSandboxExecutionContract,
|
|
43
|
+
issueLinuxGenericSandboxExecutionContract,
|
|
44
|
+
LINUX_GENERIC_CONTRACT_KIND,
|
|
45
|
+
} from "./linux-generic-bwrap.js";
|
|
41
46
|
import { consumeIssuedPluginSandboxExecutionContract } from "../plugin-runtime/bin.js";
|
|
47
|
+
import runtimeProvenanceLedger from "../runtime-provenance-ledger.js";
|
|
42
48
|
import { credentialAgent } from "./credential-agent.js";
|
|
43
49
|
|
|
44
50
|
const SUPPORTED_SANDBOX_BOUNDARIES = new Set(Object.values(SANDBOX_BOUNDARIES));
|
|
@@ -50,7 +56,6 @@ const SUPPORTED_SANDBOX_PROFILES = new Set([
|
|
|
50
56
|
|
|
51
57
|
// 延迟导入避免循环依赖
|
|
52
58
|
let _traceCtx = null;
|
|
53
|
-
let _rpl = null;
|
|
54
59
|
let _hooksV2 = null;
|
|
55
60
|
const _ipcBus = null;
|
|
56
61
|
|
|
@@ -66,14 +71,7 @@ function getTraceCtx() {
|
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
function getRpl() {
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
_rpl = require("../runtime-provenance-ledger.js");
|
|
72
|
-
} catch {
|
|
73
|
-
_rpl = null;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return _rpl;
|
|
74
|
+
return runtimeProvenanceLedger;
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
function getHooksV2() {
|
|
@@ -271,6 +269,24 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
271
269
|
},
|
|
272
270
|
);
|
|
273
271
|
};
|
|
272
|
+
if (raw?.kind === LINUX_GENERIC_CONTRACT_KIND) {
|
|
273
|
+
const admitted = admitLinuxGenericSandboxExecutionContract(raw, {
|
|
274
|
+
origin: options.origin || "unknown",
|
|
275
|
+
command: launch?.command,
|
|
276
|
+
args: launch?.args,
|
|
277
|
+
cwd: options.cwd || process.cwd(),
|
|
278
|
+
shell: options.shell,
|
|
279
|
+
sync: launch?.sync === true,
|
|
280
|
+
stdio: options.stdio,
|
|
281
|
+
requiredBoundaries,
|
|
282
|
+
});
|
|
283
|
+
if (!admitted) {
|
|
284
|
+
return invalid(
|
|
285
|
+
"sandboxExecutionContract was not issued for this workspace launch provenance",
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
return admitted;
|
|
289
|
+
}
|
|
274
290
|
if (
|
|
275
291
|
!consumeIssuedPluginSandboxExecutionContract(raw, {
|
|
276
292
|
origin: options.origin,
|
|
@@ -315,6 +331,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
315
331
|
![
|
|
316
332
|
"strict-plugin-node-bin",
|
|
317
333
|
"strict-plugin-native-static-elf-bin",
|
|
334
|
+
"strict-plugin-native-elf-bin",
|
|
318
335
|
].includes(raw.kind)
|
|
319
336
|
) {
|
|
320
337
|
return invalid("unsupported sandboxExecutionContract kind or version");
|
|
@@ -407,6 +424,57 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
407
424
|
});
|
|
408
425
|
}
|
|
409
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Issue a private one-launch Linux workspace authority for trusted host
|
|
429
|
+
* call-sites. The writable root is a positional host value, never read from
|
|
430
|
+
* a manifest/spawn option. Unsupported platforms and mixed boundary sets
|
|
431
|
+
* return null so the normal fail-closed adapter path remains authoritative.
|
|
432
|
+
*/
|
|
433
|
+
issueLinuxWorkspaceSandboxExecutionContract(
|
|
434
|
+
command,
|
|
435
|
+
args = [],
|
|
436
|
+
options = {},
|
|
437
|
+
trustedWorkspaceRoot = process.cwd(),
|
|
438
|
+
{ sync = false } = {},
|
|
439
|
+
) {
|
|
440
|
+
const requiredBoundaries = [
|
|
441
|
+
...new Set([
|
|
442
|
+
...(options.requiredBoundaries || []),
|
|
443
|
+
...(options.sandboxPolicy?.requiredBoundaries || []),
|
|
444
|
+
]),
|
|
445
|
+
];
|
|
446
|
+
if (
|
|
447
|
+
process.platform !== "linux" ||
|
|
448
|
+
requiredBoundaries.length === 0 ||
|
|
449
|
+
(options.shell !== undefined &&
|
|
450
|
+
options.shell !== null &&
|
|
451
|
+
options.shell !== false) ||
|
|
452
|
+
requiredBoundaries.some(
|
|
453
|
+
(boundary) =>
|
|
454
|
+
boundary !== SANDBOX_BOUNDARIES.FILESYSTEM &&
|
|
455
|
+
boundary !== SANDBOX_BOUNDARIES.NETWORK,
|
|
456
|
+
)
|
|
457
|
+
) {
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
return issueLinuxGenericSandboxExecutionContract({
|
|
461
|
+
origin: options.origin || "unknown",
|
|
462
|
+
command,
|
|
463
|
+
args,
|
|
464
|
+
cwd: options.cwd || trustedWorkspaceRoot,
|
|
465
|
+
workspaceRoot: trustedWorkspaceRoot,
|
|
466
|
+
shell: options.shell,
|
|
467
|
+
sync,
|
|
468
|
+
stdio: options.stdio,
|
|
469
|
+
requiredBoundaries,
|
|
470
|
+
detached: options.detached,
|
|
471
|
+
uid: options.uid,
|
|
472
|
+
gid: options.gid,
|
|
473
|
+
argv0: options.argv0,
|
|
474
|
+
serialization: options.serialization,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
|
|
410
478
|
_stripPluginControlOptions(options) {
|
|
411
479
|
delete options.pluginId;
|
|
412
480
|
delete options.pluginVersion;
|
|
@@ -636,6 +704,9 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
636
704
|
);
|
|
637
705
|
}
|
|
638
706
|
let runtimeProbe = null;
|
|
707
|
+
let genericWorkspaceProbe = false;
|
|
708
|
+
let sanitizedFilesystemPolicy = null;
|
|
709
|
+
let sanitizedNetworkPolicy = null;
|
|
639
710
|
if (plan.runtimeProbe !== null && plan.runtimeProbe !== undefined) {
|
|
640
711
|
if (
|
|
641
712
|
typeof plan.runtimeProbe !== "object" ||
|
|
@@ -656,6 +727,12 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
656
727
|
"targetRuntime",
|
|
657
728
|
"contentSnapshotScope",
|
|
658
729
|
"contentSnapshotMechanism",
|
|
730
|
+
"pluginTreeContentSnapshotScope",
|
|
731
|
+
"pluginTreeContentSnapshotMechanism",
|
|
732
|
+
"pluginTreeSnapshotConsistency",
|
|
733
|
+
"initialDynamicLoadClosureScope",
|
|
734
|
+
"initialDynamicLoadClosureMechanism",
|
|
735
|
+
"initialDynamicInterpreter",
|
|
659
736
|
]) {
|
|
660
737
|
if (
|
|
661
738
|
plan.runtimeProbe[field] !== undefined &&
|
|
@@ -668,7 +745,14 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
668
745
|
);
|
|
669
746
|
}
|
|
670
747
|
}
|
|
671
|
-
for (const field of [
|
|
748
|
+
for (const field of [
|
|
749
|
+
"contentSnapshot",
|
|
750
|
+
"handleAtomic",
|
|
751
|
+
"pluginTreeContentSnapshot",
|
|
752
|
+
"pluginTreeSnapshotContractBound",
|
|
753
|
+
"pluginTreeSnapshotAtomic",
|
|
754
|
+
"initialDynamicLoadClosureDescriptorBound",
|
|
755
|
+
]) {
|
|
672
756
|
if (
|
|
673
757
|
plan.runtimeProbe[field] !== undefined &&
|
|
674
758
|
typeof plan.runtimeProbe[field] !== "boolean"
|
|
@@ -679,6 +763,503 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
679
763
|
);
|
|
680
764
|
}
|
|
681
765
|
}
|
|
766
|
+
for (const field of [
|
|
767
|
+
"pluginTreeContentSnapshotFiles",
|
|
768
|
+
"pluginTreeContentSnapshotBytes",
|
|
769
|
+
"initialDynamicDependencyCount",
|
|
770
|
+
"initialDynamicRuntimeFileCount",
|
|
771
|
+
]) {
|
|
772
|
+
if (
|
|
773
|
+
plan.runtimeProbe[field] !== undefined &&
|
|
774
|
+
(!Number.isSafeInteger(plan.runtimeProbe[field]) ||
|
|
775
|
+
plan.runtimeProbe[field] < 0)
|
|
776
|
+
) {
|
|
777
|
+
throw this._sandboxError(
|
|
778
|
+
"invalid_sandbox_plan",
|
|
779
|
+
`Sandbox runtime probe ${field} must be a non-negative safe integer`,
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
if (
|
|
784
|
+
plan.runtimeProbe.pluginTreeContentSnapshotDigest !== undefined &&
|
|
785
|
+
(typeof plan.runtimeProbe.pluginTreeContentSnapshotDigest !==
|
|
786
|
+
"string" ||
|
|
787
|
+
!/^[a-f0-9]{64}$/.test(
|
|
788
|
+
plan.runtimeProbe.pluginTreeContentSnapshotDigest,
|
|
789
|
+
))
|
|
790
|
+
) {
|
|
791
|
+
throw this._sandboxError(
|
|
792
|
+
"invalid_sandbox_plan",
|
|
793
|
+
"Sandbox runtime probe pluginTreeContentSnapshotDigest must be a lowercase SHA-256 value",
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
if (
|
|
797
|
+
plan.runtimeProbe.initialDynamicLoadClosureDigest !== undefined &&
|
|
798
|
+
(typeof plan.runtimeProbe.initialDynamicLoadClosureDigest !==
|
|
799
|
+
"string" ||
|
|
800
|
+
!/^[a-f0-9]{64}$/.test(
|
|
801
|
+
plan.runtimeProbe.initialDynamicLoadClosureDigest,
|
|
802
|
+
))
|
|
803
|
+
) {
|
|
804
|
+
throw this._sandboxError(
|
|
805
|
+
"invalid_sandbox_plan",
|
|
806
|
+
"Sandbox runtime probe initialDynamicLoadClosureDigest must be a lowercase SHA-256 value",
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
const pluginTreeSnapshot =
|
|
810
|
+
plan.runtimeProbe.pluginTreeContentSnapshot === true;
|
|
811
|
+
const pluginTreeEvidenceFields = [
|
|
812
|
+
"pluginTreeContentSnapshotScope",
|
|
813
|
+
"pluginTreeContentSnapshotMechanism",
|
|
814
|
+
"pluginTreeContentSnapshotFiles",
|
|
815
|
+
"pluginTreeContentSnapshotBytes",
|
|
816
|
+
"pluginTreeContentSnapshotDigest",
|
|
817
|
+
"pluginTreeSnapshotConsistency",
|
|
818
|
+
"pluginTreeSnapshotContractBound",
|
|
819
|
+
"pluginTreeSnapshotAtomic",
|
|
820
|
+
];
|
|
821
|
+
if (
|
|
822
|
+
pluginTreeSnapshot &&
|
|
823
|
+
(plan.applied !== true ||
|
|
824
|
+
plan.platform !== "linux" ||
|
|
825
|
+
plan.enforcement !== "linux-bwrap" ||
|
|
826
|
+
backend !== "linux-bwrap" ||
|
|
827
|
+
candidateBackend !== null ||
|
|
828
|
+
policyAttested !== true ||
|
|
829
|
+
policyDigest === null ||
|
|
830
|
+
!guarantees.includes(SANDBOX_BOUNDARIES.FILESYSTEM) ||
|
|
831
|
+
!guarantees.includes(SANDBOX_BOUNDARIES.NETWORK) ||
|
|
832
|
+
plan.runtimeProbe.attempted !== true ||
|
|
833
|
+
plan.runtimeProbe.runnable !== true ||
|
|
834
|
+
plan.runtimeProbe.reason !== null ||
|
|
835
|
+
plan.runtimeProbe.kind !== "linux-bwrap-plugin-node-policy-v1" ||
|
|
836
|
+
plan.runtimeProbe.probeRuntime !== "node" ||
|
|
837
|
+
plan.runtimeProbe.targetRuntime !== "node" ||
|
|
838
|
+
plan.runtimeProbe.contentSnapshot !== true ||
|
|
839
|
+
plan.runtimeProbe.contentSnapshotScope !== "plugin-entry-source" ||
|
|
840
|
+
plan.runtimeProbe.contentSnapshotMechanism !==
|
|
841
|
+
"verified-o_tmpfile-copy-bwrap-ro-bind-data-v1" ||
|
|
842
|
+
plan.runtimeProbe.handleAtomic !== false ||
|
|
843
|
+
plan.runtimeProbe.supervisorDescriptorBound !== true ||
|
|
844
|
+
plan.runtimeProbe.pluginTreeContentSnapshotScope !==
|
|
845
|
+
"all-pinned-plugin-regular-files" ||
|
|
846
|
+
plan.runtimeProbe.pluginTreeContentSnapshotMechanism !==
|
|
847
|
+
"verified-o_tmpfile-copy-bwrap-ro-bind-data-v1" ||
|
|
848
|
+
!Number.isSafeInteger(
|
|
849
|
+
plan.runtimeProbe.pluginTreeContentSnapshotFiles,
|
|
850
|
+
) ||
|
|
851
|
+
plan.runtimeProbe.pluginTreeContentSnapshotFiles < 1 ||
|
|
852
|
+
plan.runtimeProbe.pluginTreeContentSnapshotFiles > 256 ||
|
|
853
|
+
!Number.isSafeInteger(
|
|
854
|
+
plan.runtimeProbe.pluginTreeContentSnapshotBytes,
|
|
855
|
+
) ||
|
|
856
|
+
plan.runtimeProbe.pluginTreeContentSnapshotBytes < 0 ||
|
|
857
|
+
plan.runtimeProbe.pluginTreeContentSnapshotBytes >
|
|
858
|
+
256 * 1024 * 1024 ||
|
|
859
|
+
!/^[a-f0-9]{64}$/.test(
|
|
860
|
+
plan.runtimeProbe.pluginTreeContentSnapshotDigest || "",
|
|
861
|
+
) ||
|
|
862
|
+
plan.runtimeProbe.pluginTreeSnapshotConsistency !==
|
|
863
|
+
"per-file-pin-to-launch" ||
|
|
864
|
+
plan.runtimeProbe.pluginTreeSnapshotContractBound !== false ||
|
|
865
|
+
plan.runtimeProbe.pluginTreeSnapshotAtomic !== false)
|
|
866
|
+
) {
|
|
867
|
+
throw this._sandboxError(
|
|
868
|
+
"invalid_sandbox_plan",
|
|
869
|
+
"Sandbox runtime probe plugin tree snapshot evidence must use the typed complete-tree contract",
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
if (
|
|
873
|
+
!pluginTreeSnapshot &&
|
|
874
|
+
pluginTreeEvidenceFields.some(
|
|
875
|
+
(field) => plan.runtimeProbe[field] !== undefined,
|
|
876
|
+
)
|
|
877
|
+
) {
|
|
878
|
+
throw this._sandboxError(
|
|
879
|
+
"invalid_sandbox_plan",
|
|
880
|
+
"Sandbox runtime probe plugin tree snapshot evidence requires pluginTreeContentSnapshot",
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
const supervisorStringFields = [
|
|
884
|
+
"supervisorBindingScope",
|
|
885
|
+
"supervisorDescriptorBindingMechanism",
|
|
886
|
+
"supervisorPid1ExecutableExposure",
|
|
887
|
+
];
|
|
888
|
+
const supervisorBooleanFields = [
|
|
889
|
+
"supervisorDescriptorBound",
|
|
890
|
+
"supervisorExecutablePinned",
|
|
891
|
+
"supervisorDescriptorContained",
|
|
892
|
+
"supervisorDescriptorConsumedBeforeTarget",
|
|
893
|
+
"supervisorStagingPathHidden",
|
|
894
|
+
"supervisorTemporaryCopyObscured",
|
|
895
|
+
];
|
|
896
|
+
for (const field of supervisorStringFields) {
|
|
897
|
+
if (
|
|
898
|
+
plan.runtimeProbe[field] !== undefined &&
|
|
899
|
+
(typeof plan.runtimeProbe[field] !== "string" ||
|
|
900
|
+
!plan.runtimeProbe[field])
|
|
901
|
+
) {
|
|
902
|
+
throw this._sandboxError(
|
|
903
|
+
"invalid_sandbox_plan",
|
|
904
|
+
`Sandbox runtime probe ${field} must be a non-empty string`,
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
for (const field of supervisorBooleanFields) {
|
|
909
|
+
if (
|
|
910
|
+
plan.runtimeProbe[field] !== undefined &&
|
|
911
|
+
typeof plan.runtimeProbe[field] !== "boolean"
|
|
912
|
+
) {
|
|
913
|
+
throw this._sandboxError(
|
|
914
|
+
"invalid_sandbox_plan",
|
|
915
|
+
`Sandbox runtime probe ${field} must be boolean`,
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
const supervisorIdentity = plan.runtimeProbe.supervisorExecutableIdentity;
|
|
920
|
+
if (supervisorIdentity !== undefined) {
|
|
921
|
+
const fileId = supervisorIdentity?.fileId;
|
|
922
|
+
if (
|
|
923
|
+
!supervisorIdentity ||
|
|
924
|
+
typeof supervisorIdentity !== "object" ||
|
|
925
|
+
Array.isArray(supervisorIdentity) ||
|
|
926
|
+
typeof supervisorIdentity.path !== "string" ||
|
|
927
|
+
!supervisorIdentity.path.startsWith("/") ||
|
|
928
|
+
!fileId ||
|
|
929
|
+
typeof fileId !== "object" ||
|
|
930
|
+
Array.isArray(fileId) ||
|
|
931
|
+
typeof fileId.dev !== "string" ||
|
|
932
|
+
!/^\d+$/.test(fileId.dev) ||
|
|
933
|
+
typeof fileId.ino !== "string" ||
|
|
934
|
+
!/^\d+$/.test(fileId.ino) ||
|
|
935
|
+
typeof supervisorIdentity.sha256 !== "string" ||
|
|
936
|
+
!/^[a-f0-9]{64}$/.test(supervisorIdentity.sha256) ||
|
|
937
|
+
!Number.isSafeInteger(supervisorIdentity.bytes) ||
|
|
938
|
+
supervisorIdentity.bytes <= 0 ||
|
|
939
|
+
supervisorIdentity.bytes > 256 * 1024 * 1024 ||
|
|
940
|
+
!Number.isFinite(supervisorIdentity.mtimeMs) ||
|
|
941
|
+
!Number.isSafeInteger(supervisorIdentity.mode) ||
|
|
942
|
+
supervisorIdentity.mode <= 0 ||
|
|
943
|
+
(supervisorIdentity.mode & 0o170000) !== 0o100000 ||
|
|
944
|
+
(supervisorIdentity.mode & 0o111) === 0 ||
|
|
945
|
+
(supervisorIdentity.mode & 0o022) !== 0 ||
|
|
946
|
+
!Number.isSafeInteger(supervisorIdentity.uid) ||
|
|
947
|
+
supervisorIdentity.uid !== 0 ||
|
|
948
|
+
!Number.isSafeInteger(supervisorIdentity.gid) ||
|
|
949
|
+
supervisorIdentity.gid < 0
|
|
950
|
+
) {
|
|
951
|
+
throw this._sandboxError(
|
|
952
|
+
"invalid_sandbox_plan",
|
|
953
|
+
"Sandbox runtime probe supervisorExecutableIdentity must use the typed executable identity contract",
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
const supervisorBound =
|
|
958
|
+
plan.runtimeProbe.supervisorDescriptorBound === true;
|
|
959
|
+
if (
|
|
960
|
+
supervisorBound &&
|
|
961
|
+
(plan.runtimeProbe.supervisorExecutablePinned !== true ||
|
|
962
|
+
supervisorIdentity === undefined ||
|
|
963
|
+
plan.runtimeProbe.supervisorBindingScope !==
|
|
964
|
+
"host-path-replacement" ||
|
|
965
|
+
plan.runtimeProbe.supervisorDescriptorBindingMechanism !==
|
|
966
|
+
"pinned-child-fd3-file-consume-run-overmount-v1" ||
|
|
967
|
+
plan.runtimeProbe.supervisorPid1ExecutableExposure !== "procfs")
|
|
968
|
+
) {
|
|
969
|
+
throw this._sandboxError(
|
|
970
|
+
"invalid_sandbox_plan",
|
|
971
|
+
"Sandbox runtime probe bound supervisor evidence must include its typed identity and binding contract",
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
for (const field of [
|
|
975
|
+
"supervisorDescriptorContained",
|
|
976
|
+
"supervisorDescriptorConsumedBeforeTarget",
|
|
977
|
+
"supervisorStagingPathHidden",
|
|
978
|
+
"supervisorTemporaryCopyObscured",
|
|
979
|
+
]) {
|
|
980
|
+
if (
|
|
981
|
+
(plan.runtimeProbe[field] === true &&
|
|
982
|
+
(!supervisorBound || plan.runtimeProbe.runnable !== true)) ||
|
|
983
|
+
(supervisorBound &&
|
|
984
|
+
plan.runtimeProbe[field] !== plan.runtimeProbe.runnable)
|
|
985
|
+
) {
|
|
986
|
+
throw this._sandboxError(
|
|
987
|
+
"invalid_sandbox_plan",
|
|
988
|
+
`Sandbox runtime probe ${field} requires a runnable bound supervisor`,
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
const initialDynamicLoadClosureBound =
|
|
993
|
+
plan.runtimeProbe.initialDynamicLoadClosureDescriptorBound === true;
|
|
994
|
+
const initialDynamicEvidenceFields = [
|
|
995
|
+
"initialDynamicLoadClosureScope",
|
|
996
|
+
"initialDynamicLoadClosureMechanism",
|
|
997
|
+
"initialDynamicInterpreter",
|
|
998
|
+
"initialDynamicDependencyCount",
|
|
999
|
+
"initialDynamicRuntimeFileCount",
|
|
1000
|
+
"initialDynamicLoadClosureDigest",
|
|
1001
|
+
];
|
|
1002
|
+
const initialDynamicInterpreter =
|
|
1003
|
+
plan.runtimeProbe.initialDynamicInterpreter;
|
|
1004
|
+
const initialDynamicDependencyCount =
|
|
1005
|
+
plan.runtimeProbe.initialDynamicDependencyCount;
|
|
1006
|
+
const initialDynamicRuntimeFileCount =
|
|
1007
|
+
plan.runtimeProbe.initialDynamicRuntimeFileCount;
|
|
1008
|
+
const successfulDynamicProbe =
|
|
1009
|
+
plan.applied === true &&
|
|
1010
|
+
plan.runtimeProbe.kind ===
|
|
1011
|
+
"linux-bwrap-plugin-native-dynamic-elf-policy-v1" &&
|
|
1012
|
+
plan.runtimeProbe.runnable === true;
|
|
1013
|
+
if (
|
|
1014
|
+
initialDynamicLoadClosureBound &&
|
|
1015
|
+
(plan.applied !== true ||
|
|
1016
|
+
plan.platform !== "linux" ||
|
|
1017
|
+
plan.enforcement !== "linux-bwrap" ||
|
|
1018
|
+
backend !== "linux-bwrap" ||
|
|
1019
|
+
candidateBackend !== null ||
|
|
1020
|
+
policyAttested !== true ||
|
|
1021
|
+
policyDigest === null ||
|
|
1022
|
+
!guarantees.includes(SANDBOX_BOUNDARIES.FILESYSTEM) ||
|
|
1023
|
+
!guarantees.includes(SANDBOX_BOUNDARIES.NETWORK) ||
|
|
1024
|
+
plan.runtimeProbe.attempted !== true ||
|
|
1025
|
+
plan.runtimeProbe.runnable !== true ||
|
|
1026
|
+
plan.runtimeProbe.reason !== null ||
|
|
1027
|
+
plan.runtimeProbe.kind !==
|
|
1028
|
+
"linux-bwrap-plugin-native-dynamic-elf-policy-v1" ||
|
|
1029
|
+
plan.runtimeProbe.probeRuntime !== "node" ||
|
|
1030
|
+
plan.runtimeProbe.targetRuntime !== "native-dynamic-elf" ||
|
|
1031
|
+
plan.runtimeProbe.contentSnapshot !== true ||
|
|
1032
|
+
plan.runtimeProbe.contentSnapshotScope !==
|
|
1033
|
+
"plugin-entry-executable" ||
|
|
1034
|
+
plan.runtimeProbe.contentSnapshotMechanism !==
|
|
1035
|
+
"verified-o_tmpfile-copy-bwrap-ro-bind-data-v1" ||
|
|
1036
|
+
plan.runtimeProbe.handleAtomic !== false ||
|
|
1037
|
+
!supervisorBound ||
|
|
1038
|
+
plan.runtimeProbe.initialDynamicLoadClosureScope !==
|
|
1039
|
+
"initial-pt_interp-and-direct-dt_needed-attested-system-set" ||
|
|
1040
|
+
plan.runtimeProbe.initialDynamicLoadClosureMechanism !==
|
|
1041
|
+
"parsed-elf-direct-system-set-to-attested-node-runtime-fds-v1" ||
|
|
1042
|
+
typeof initialDynamicInterpreter !== "string" ||
|
|
1043
|
+
!path.posix.isAbsolute(initialDynamicInterpreter) ||
|
|
1044
|
+
path.posix.normalize(initialDynamicInterpreter) !==
|
|
1045
|
+
initialDynamicInterpreter ||
|
|
1046
|
+
!["/lib/", "/lib64/", "/usr/lib/", "/usr/lib64/"].some((prefix) =>
|
|
1047
|
+
initialDynamicInterpreter.startsWith(prefix),
|
|
1048
|
+
) ||
|
|
1049
|
+
!Number.isSafeInteger(initialDynamicDependencyCount) ||
|
|
1050
|
+
initialDynamicDependencyCount < 0 ||
|
|
1051
|
+
initialDynamicDependencyCount > 128 ||
|
|
1052
|
+
!Number.isSafeInteger(initialDynamicRuntimeFileCount) ||
|
|
1053
|
+
initialDynamicRuntimeFileCount < 1 ||
|
|
1054
|
+
initialDynamicRuntimeFileCount > 129 ||
|
|
1055
|
+
initialDynamicRuntimeFileCount <
|
|
1056
|
+
Math.max(1, initialDynamicDependencyCount) ||
|
|
1057
|
+
initialDynamicRuntimeFileCount > initialDynamicDependencyCount + 1 ||
|
|
1058
|
+
!/^[a-f0-9]{64}$/.test(
|
|
1059
|
+
plan.runtimeProbe.initialDynamicLoadClosureDigest || "",
|
|
1060
|
+
))
|
|
1061
|
+
) {
|
|
1062
|
+
throw this._sandboxError(
|
|
1063
|
+
"invalid_sandbox_plan",
|
|
1064
|
+
"Sandbox runtime probe initial dynamic direct system set evidence must use the typed descriptor-bound contract",
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
if (
|
|
1068
|
+
!initialDynamicLoadClosureBound &&
|
|
1069
|
+
initialDynamicEvidenceFields.some(
|
|
1070
|
+
(field) => plan.runtimeProbe[field] !== undefined,
|
|
1071
|
+
)
|
|
1072
|
+
) {
|
|
1073
|
+
throw this._sandboxError(
|
|
1074
|
+
"invalid_sandbox_plan",
|
|
1075
|
+
"Sandbox runtime probe initial dynamic direct system set evidence requires initialDynamicLoadClosureDescriptorBound",
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
if (successfulDynamicProbe && !initialDynamicLoadClosureBound) {
|
|
1079
|
+
throw this._sandboxError(
|
|
1080
|
+
"invalid_sandbox_plan",
|
|
1081
|
+
"Sandbox runtime probe successful dynamic ELF evidence requires a descriptor-bound initial direct system set",
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
const genericWorkspaceEvidenceFields = [
|
|
1085
|
+
"contractDigest",
|
|
1086
|
+
"policyDigest",
|
|
1087
|
+
"mountTopologyDigest",
|
|
1088
|
+
"emptyRoot",
|
|
1089
|
+
"undeclaredRootReadOnly",
|
|
1090
|
+
"workspaceReadWrite",
|
|
1091
|
+
"workspaceMountTopologyAttested",
|
|
1092
|
+
"workspaceRootAliasAttested",
|
|
1093
|
+
"anonymousDevWritable",
|
|
1094
|
+
"systemReadOnly",
|
|
1095
|
+
"hostHomeHidden",
|
|
1096
|
+
"outsideMarkerHidden",
|
|
1097
|
+
"networkNamespace",
|
|
1098
|
+
"networkNamespaceChanged",
|
|
1099
|
+
"socketCreationDenied",
|
|
1100
|
+
"descriptorMounts",
|
|
1101
|
+
"mountTopologyAtomic",
|
|
1102
|
+
];
|
|
1103
|
+
for (const field of [
|
|
1104
|
+
"contractDigest",
|
|
1105
|
+
"policyDigest",
|
|
1106
|
+
"mountTopologyDigest",
|
|
1107
|
+
]) {
|
|
1108
|
+
if (
|
|
1109
|
+
plan.runtimeProbe[field] !== undefined &&
|
|
1110
|
+
(typeof plan.runtimeProbe[field] !== "string" ||
|
|
1111
|
+
!/^[a-f0-9]{64}$/.test(plan.runtimeProbe[field]))
|
|
1112
|
+
) {
|
|
1113
|
+
throw this._sandboxError(
|
|
1114
|
+
"invalid_sandbox_plan",
|
|
1115
|
+
`Sandbox runtime probe ${field} must be a lowercase SHA-256 value`,
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
for (const field of genericWorkspaceEvidenceFields.slice(3)) {
|
|
1120
|
+
if (
|
|
1121
|
+
plan.runtimeProbe[field] !== undefined &&
|
|
1122
|
+
typeof plan.runtimeProbe[field] !== "boolean"
|
|
1123
|
+
) {
|
|
1124
|
+
throw this._sandboxError(
|
|
1125
|
+
"invalid_sandbox_plan",
|
|
1126
|
+
`Sandbox runtime probe ${field} must be boolean`,
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
const genericWorkspaceKind =
|
|
1131
|
+
plan.runtimeProbe.kind === "linux-bwrap-generic-workspace-policy-v1";
|
|
1132
|
+
if (
|
|
1133
|
+
!genericWorkspaceKind &&
|
|
1134
|
+
genericWorkspaceEvidenceFields.some(
|
|
1135
|
+
(field) => plan.runtimeProbe[field] !== undefined,
|
|
1136
|
+
)
|
|
1137
|
+
) {
|
|
1138
|
+
throw this._sandboxError(
|
|
1139
|
+
"invalid_sandbox_plan",
|
|
1140
|
+
"Linux generic workspace evidence requires its typed runtime probe kind",
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1143
|
+
if (genericWorkspaceKind) {
|
|
1144
|
+
const filesystemPolicy = plan.filesystemPolicy;
|
|
1145
|
+
const networkPolicy = plan.networkPolicy;
|
|
1146
|
+
const workspaceRoot = filesystemPolicy?.workspaceRoot;
|
|
1147
|
+
const workingDirectory = filesystemPolicy?.workingDirectory;
|
|
1148
|
+
const workspaceRelative =
|
|
1149
|
+
typeof workspaceRoot === "string" &&
|
|
1150
|
+
typeof workingDirectory === "string"
|
|
1151
|
+
? path.posix.relative(workspaceRoot, workingDirectory)
|
|
1152
|
+
: "..";
|
|
1153
|
+
genericWorkspaceProbe =
|
|
1154
|
+
plan.applied === true &&
|
|
1155
|
+
plan.platform === "linux" &&
|
|
1156
|
+
plan.enforcement === "linux-bwrap-workspace" &&
|
|
1157
|
+
backend === "linux-bwrap-workspace" &&
|
|
1158
|
+
candidateBackend === null &&
|
|
1159
|
+
policyAttested === true &&
|
|
1160
|
+
policyDigest !== null &&
|
|
1161
|
+
plan.runtimeProbe.policyDigest === policyDigest &&
|
|
1162
|
+
/^[a-f0-9]{64}$/.test(plan.runtimeProbe.contractDigest || "") &&
|
|
1163
|
+
guarantees.includes(SANDBOX_BOUNDARIES.FILESYSTEM) &&
|
|
1164
|
+
guarantees.includes(SANDBOX_BOUNDARIES.NETWORK) &&
|
|
1165
|
+
plan.runtimeProbe.attempted === true &&
|
|
1166
|
+
plan.runtimeProbe.runnable === true &&
|
|
1167
|
+
plan.runtimeProbe.reason === null &&
|
|
1168
|
+
plan.runtimeProbe.probeRuntime === "posix-sh" &&
|
|
1169
|
+
plan.runtimeProbe.targetRuntime === "generic-command" &&
|
|
1170
|
+
plan.runtimeProbe.contentSnapshot === false &&
|
|
1171
|
+
plan.runtimeProbe.handleAtomic === false &&
|
|
1172
|
+
plan.runtimeProbe.mountTopologyAtomic === false &&
|
|
1173
|
+
plan.runtimeProbe.mountTopologyDigest ===
|
|
1174
|
+
filesystemPolicy?.mountTopologyDigest &&
|
|
1175
|
+
[
|
|
1176
|
+
"emptyRoot",
|
|
1177
|
+
"undeclaredRootReadOnly",
|
|
1178
|
+
"workspaceReadWrite",
|
|
1179
|
+
"workspaceMountTopologyAttested",
|
|
1180
|
+
"workspaceRootAliasAttested",
|
|
1181
|
+
"anonymousDevWritable",
|
|
1182
|
+
"systemReadOnly",
|
|
1183
|
+
"hostHomeHidden",
|
|
1184
|
+
"outsideMarkerHidden",
|
|
1185
|
+
"networkNamespace",
|
|
1186
|
+
"networkNamespaceChanged",
|
|
1187
|
+
"socketCreationDenied",
|
|
1188
|
+
"descriptorMounts",
|
|
1189
|
+
].every((field) => plan.runtimeProbe[field] === true) &&
|
|
1190
|
+
typeof workspaceRoot === "string" &&
|
|
1191
|
+
path.posix.isAbsolute(workspaceRoot) &&
|
|
1192
|
+
workspaceRoot !== "/" &&
|
|
1193
|
+
typeof workingDirectory === "string" &&
|
|
1194
|
+
path.posix.isAbsolute(workingDirectory) &&
|
|
1195
|
+
workspaceRelative !== ".." &&
|
|
1196
|
+
!workspaceRelative.startsWith("../") &&
|
|
1197
|
+
!path.posix.isAbsolute(workspaceRelative) &&
|
|
1198
|
+
filesystemPolicy.workspaceAccess === "read-write" &&
|
|
1199
|
+
filesystemPolicy.systemAccess === "read-only" &&
|
|
1200
|
+
filesystemPolicy.undeclaredRootAccess === "read-only" &&
|
|
1201
|
+
filesystemPolicy.hostRootMapped === false &&
|
|
1202
|
+
filesystemPolicy.hostHomeMapped === false &&
|
|
1203
|
+
filesystemPolicy.workspaceDescriptorBound === true &&
|
|
1204
|
+
filesystemPolicy.systemDescriptorBound === true &&
|
|
1205
|
+
filesystemPolicy.exactEtcFileDescriptors === true &&
|
|
1206
|
+
filesystemPolicy.workspaceRecursiveBind === true &&
|
|
1207
|
+
filesystemPolicy.workspaceMountTopology ===
|
|
1208
|
+
"no-strict-descendants-or-forbidden-root-aliases-at-attestation" &&
|
|
1209
|
+
filesystemPolicy.mountTopologySource === "proc-self-mountinfo" &&
|
|
1210
|
+
/^[a-f0-9]{64}$/.test(filesystemPolicy.mountTopologyDigest || "") &&
|
|
1211
|
+
filesystemPolicy.mountTopologyAtomic === false &&
|
|
1212
|
+
Array.isArray(filesystemPolicy.anonymousWritablePaths) &&
|
|
1213
|
+
filesystemPolicy.anonymousWritablePaths.length === 5 &&
|
|
1214
|
+
["/home/sandbox", "/dev", "/run", "/tmp", "/var/tmp"].every(
|
|
1215
|
+
(value, index) =>
|
|
1216
|
+
filesystemPolicy.anonymousWritablePaths[index] === value,
|
|
1217
|
+
) &&
|
|
1218
|
+
networkPolicy?.namespace === "new" &&
|
|
1219
|
+
networkPolicy?.namespaceIdentityChanged === true &&
|
|
1220
|
+
networkPolicy?.seccomp === "deny-network-creation" &&
|
|
1221
|
+
plan.command.startsWith("/proc/self/fd/") &&
|
|
1222
|
+
plan.options?.cwd === "/" &&
|
|
1223
|
+
plan.options?.shell === false &&
|
|
1224
|
+
Array.isArray(plan.options?.stdio) &&
|
|
1225
|
+
plan.args.includes("--bind-fd") &&
|
|
1226
|
+
plan.args.includes("--ro-bind-fd") &&
|
|
1227
|
+
plan.args.includes("--remount-ro") &&
|
|
1228
|
+
plan.args.includes("--unshare-net") &&
|
|
1229
|
+
plan.args.includes("--seccomp") &&
|
|
1230
|
+
!plan.args.includes("--ro-bind");
|
|
1231
|
+
if (!genericWorkspaceProbe) {
|
|
1232
|
+
throw this._sandboxError(
|
|
1233
|
+
"invalid_sandbox_plan",
|
|
1234
|
+
"Linux generic workspace evidence must use the typed descriptor-bound empty-root contract",
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
sanitizedFilesystemPolicy = Object.freeze({
|
|
1238
|
+
workspaceRoot,
|
|
1239
|
+
workingDirectory,
|
|
1240
|
+
workspaceAccess: filesystemPolicy.workspaceAccess,
|
|
1241
|
+
systemAccess: filesystemPolicy.systemAccess,
|
|
1242
|
+
undeclaredRootAccess: filesystemPolicy.undeclaredRootAccess,
|
|
1243
|
+
anonymousWritablePaths: Object.freeze([
|
|
1244
|
+
...filesystemPolicy.anonymousWritablePaths,
|
|
1245
|
+
]),
|
|
1246
|
+
hostRootMapped: filesystemPolicy.hostRootMapped,
|
|
1247
|
+
hostHomeMapped: filesystemPolicy.hostHomeMapped,
|
|
1248
|
+
workspaceDescriptorBound: filesystemPolicy.workspaceDescriptorBound,
|
|
1249
|
+
systemDescriptorBound: filesystemPolicy.systemDescriptorBound,
|
|
1250
|
+
exactEtcFileDescriptors: filesystemPolicy.exactEtcFileDescriptors,
|
|
1251
|
+
workspaceRecursiveBind: filesystemPolicy.workspaceRecursiveBind,
|
|
1252
|
+
workspaceMountTopology: filesystemPolicy.workspaceMountTopology,
|
|
1253
|
+
mountTopologySource: filesystemPolicy.mountTopologySource,
|
|
1254
|
+
mountTopologyDigest: filesystemPolicy.mountTopologyDigest,
|
|
1255
|
+
mountTopologyAtomic: filesystemPolicy.mountTopologyAtomic,
|
|
1256
|
+
});
|
|
1257
|
+
sanitizedNetworkPolicy = Object.freeze({
|
|
1258
|
+
namespace: networkPolicy.namespace,
|
|
1259
|
+
namespaceIdentityChanged: networkPolicy.namespaceIdentityChanged,
|
|
1260
|
+
seccomp: networkPolicy.seccomp,
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
682
1263
|
runtimeProbe = {
|
|
683
1264
|
kind: plan.runtimeProbe.kind,
|
|
684
1265
|
attempted: plan.runtimeProbe.attempted,
|
|
@@ -708,6 +1289,56 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
708
1289
|
}
|
|
709
1290
|
: {}),
|
|
710
1291
|
};
|
|
1292
|
+
for (const field of [
|
|
1293
|
+
"pluginTreeContentSnapshot",
|
|
1294
|
+
...pluginTreeEvidenceFields,
|
|
1295
|
+
]) {
|
|
1296
|
+
if (plan.runtimeProbe[field] !== undefined) {
|
|
1297
|
+
runtimeProbe[field] = plan.runtimeProbe[field];
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
for (const field of [
|
|
1301
|
+
...supervisorStringFields,
|
|
1302
|
+
...supervisorBooleanFields,
|
|
1303
|
+
]) {
|
|
1304
|
+
if (plan.runtimeProbe[field] !== undefined) {
|
|
1305
|
+
runtimeProbe[field] = plan.runtimeProbe[field];
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
for (const field of [
|
|
1309
|
+
"initialDynamicLoadClosureDescriptorBound",
|
|
1310
|
+
...initialDynamicEvidenceFields,
|
|
1311
|
+
]) {
|
|
1312
|
+
if (plan.runtimeProbe[field] !== undefined) {
|
|
1313
|
+
runtimeProbe[field] = plan.runtimeProbe[field];
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
for (const field of genericWorkspaceEvidenceFields) {
|
|
1317
|
+
if (plan.runtimeProbe[field] !== undefined) {
|
|
1318
|
+
runtimeProbe[field] = plan.runtimeProbe[field];
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
if (supervisorIdentity !== undefined) {
|
|
1322
|
+
runtimeProbe.supervisorExecutableIdentity = {
|
|
1323
|
+
path: supervisorIdentity.path,
|
|
1324
|
+
fileId: {
|
|
1325
|
+
dev: supervisorIdentity.fileId.dev,
|
|
1326
|
+
ino: supervisorIdentity.fileId.ino,
|
|
1327
|
+
},
|
|
1328
|
+
sha256: supervisorIdentity.sha256,
|
|
1329
|
+
bytes: supervisorIdentity.bytes,
|
|
1330
|
+
mtimeMs: supervisorIdentity.mtimeMs,
|
|
1331
|
+
mode: supervisorIdentity.mode,
|
|
1332
|
+
uid: supervisorIdentity.uid,
|
|
1333
|
+
gid: supervisorIdentity.gid,
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
if (backend === "linux-bwrap-workspace" && !genericWorkspaceProbe) {
|
|
1338
|
+
throw this._sandboxError(
|
|
1339
|
+
"invalid_sandbox_plan",
|
|
1340
|
+
"Applied Linux generic workspace plans require typed runtime evidence",
|
|
1341
|
+
);
|
|
711
1342
|
}
|
|
712
1343
|
const postSpawn = plan.postSpawn || { required: false, mode: "none" };
|
|
713
1344
|
if (
|
|
@@ -730,6 +1361,12 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
730
1361
|
policyAttested,
|
|
731
1362
|
policyDigest,
|
|
732
1363
|
runtimeProbe,
|
|
1364
|
+
...(sanitizedFilesystemPolicy
|
|
1365
|
+
? {
|
|
1366
|
+
filesystemPolicy: sanitizedFilesystemPolicy,
|
|
1367
|
+
networkPolicy: sanitizedNetworkPolicy,
|
|
1368
|
+
}
|
|
1369
|
+
: {}),
|
|
733
1370
|
postSpawn: { ...postSpawn },
|
|
734
1371
|
};
|
|
735
1372
|
}
|
|
@@ -884,6 +1521,39 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
884
1521
|
auditEntry.sandboxPolicyAttested =
|
|
885
1522
|
typeof plan?.policyAttested === "boolean" ? plan.policyAttested : null;
|
|
886
1523
|
auditEntry.sandboxPolicyDigest = plan?.policyDigest || null;
|
|
1524
|
+
const genericPolicy =
|
|
1525
|
+
applied === true && plan?.backend === "linux-bwrap-workspace";
|
|
1526
|
+
auditEntry.sandboxFilesystemPolicy = genericPolicy
|
|
1527
|
+
? {
|
|
1528
|
+
workspaceRoot: plan.filesystemPolicy.workspaceRoot,
|
|
1529
|
+
workingDirectory: plan.filesystemPolicy.workingDirectory,
|
|
1530
|
+
workspaceAccess: plan.filesystemPolicy.workspaceAccess,
|
|
1531
|
+
systemAccess: plan.filesystemPolicy.systemAccess,
|
|
1532
|
+
undeclaredRootAccess: plan.filesystemPolicy.undeclaredRootAccess,
|
|
1533
|
+
anonymousWritablePaths: [
|
|
1534
|
+
...plan.filesystemPolicy.anonymousWritablePaths,
|
|
1535
|
+
],
|
|
1536
|
+
hostRootMapped: plan.filesystemPolicy.hostRootMapped,
|
|
1537
|
+
hostHomeMapped: plan.filesystemPolicy.hostHomeMapped,
|
|
1538
|
+
workspaceDescriptorBound:
|
|
1539
|
+
plan.filesystemPolicy.workspaceDescriptorBound,
|
|
1540
|
+
systemDescriptorBound: plan.filesystemPolicy.systemDescriptorBound,
|
|
1541
|
+
exactEtcFileDescriptors:
|
|
1542
|
+
plan.filesystemPolicy.exactEtcFileDescriptors,
|
|
1543
|
+
workspaceRecursiveBind: plan.filesystemPolicy.workspaceRecursiveBind,
|
|
1544
|
+
workspaceMountTopology: plan.filesystemPolicy.workspaceMountTopology,
|
|
1545
|
+
mountTopologySource: plan.filesystemPolicy.mountTopologySource,
|
|
1546
|
+
mountTopologyDigest: plan.filesystemPolicy.mountTopologyDigest,
|
|
1547
|
+
mountTopologyAtomic: plan.filesystemPolicy.mountTopologyAtomic,
|
|
1548
|
+
}
|
|
1549
|
+
: null;
|
|
1550
|
+
auditEntry.sandboxNetworkPolicy = genericPolicy
|
|
1551
|
+
? {
|
|
1552
|
+
namespace: plan.networkPolicy.namespace,
|
|
1553
|
+
namespaceIdentityChanged: plan.networkPolicy.namespaceIdentityChanged,
|
|
1554
|
+
seccomp: plan.networkPolicy.seccomp,
|
|
1555
|
+
}
|
|
1556
|
+
: null;
|
|
887
1557
|
auditEntry.sandboxCandidateReason = plan?.candidateBackend
|
|
888
1558
|
? plan?.reason || null
|
|
889
1559
|
: null;
|
|
@@ -1145,12 +1815,13 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
1145
1815
|
|
|
1146
1816
|
_writeRplEntry(auditEntry, status = "started", error = null) {
|
|
1147
1817
|
const rpl = getRpl();
|
|
1148
|
-
if (!rpl
|
|
1818
|
+
if (!rpl) return;
|
|
1149
1819
|
try {
|
|
1150
1820
|
const traceCtx = this._getTraceContext();
|
|
1151
|
-
rpl.
|
|
1821
|
+
if (typeof rpl.record !== "function") return;
|
|
1822
|
+
rpl.record(
|
|
1823
|
+
"process.execution",
|
|
1152
1824
|
{
|
|
1153
|
-
kind: "process.execution",
|
|
1154
1825
|
component: auditEntry.origin,
|
|
1155
1826
|
action: "spawn",
|
|
1156
1827
|
artifactId: auditEntry.executionId,
|
|
@@ -1171,6 +1842,15 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
1171
1842
|
policy: auditEntry.policy,
|
|
1172
1843
|
scope: auditEntry.scope,
|
|
1173
1844
|
},
|
|
1845
|
+
sandbox: {
|
|
1846
|
+
applied: auditEntry.sandboxed === true,
|
|
1847
|
+
backend: auditEntry.sandboxBackend || null,
|
|
1848
|
+
guarantees: [...(auditEntry.sandboxGuarantees || [])],
|
|
1849
|
+
policyAttested: auditEntry.sandboxPolicyAttested === true,
|
|
1850
|
+
policyDigest: auditEntry.sandboxPolicyDigest || null,
|
|
1851
|
+
filesystemPolicy: auditEntry.sandboxFilesystemPolicy || null,
|
|
1852
|
+
networkPolicy: auditEntry.sandboxNetworkPolicy || null,
|
|
1853
|
+
},
|
|
1174
1854
|
traceId:
|
|
1175
1855
|
traceCtx?.traceId || auditEntry.traceId || `trace-${Date.now()}`,
|
|
1176
1856
|
parentSpanId: traceCtx?.spanId || null,
|
|
@@ -1356,6 +2036,18 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
1356
2036
|
proc,
|
|
1357
2037
|
sandboxPlan.cleanup,
|
|
1358
2038
|
);
|
|
2039
|
+
if (
|
|
2040
|
+
sandboxPlan.applied === true &&
|
|
2041
|
+
sandboxPlan.backend === "linux-bwrap-workspace" &&
|
|
2042
|
+
sandboxPlan.postSpawn.required === false
|
|
2043
|
+
) {
|
|
2044
|
+
// child_process.spawn() has synchronously duplicated every stdio entry
|
|
2045
|
+
// into the launched bwrap process before returning. Generic workspace
|
|
2046
|
+
// plans do not need a parent-side post-spawn handle, so retaining their
|
|
2047
|
+
// pinned mount/seccomp descriptors until a long-lived MCP/LSP/monitor
|
|
2048
|
+
// exits would turn each child into an avoidable FD leak.
|
|
2049
|
+
cleanupSandbox();
|
|
2050
|
+
}
|
|
1359
2051
|
try {
|
|
1360
2052
|
this._runPostSpawnSandbox(proc, sandboxPlan, auditEntry);
|
|
1361
2053
|
auditEntry.pid = proc.pid;
|