chainlesschain 0.163.0 → 0.163.2
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-CSy9BB6Z.js → AIOps-DnGsmsqJ.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CFyrEVfq.js → ActionButton-CrO6fcQ7.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-8419vb47.js → Analytics-DsBdOaP2.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CHu3Hkdx.js → AppLayout-DmQslKUB.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-DJnt57Fs.js → Artifacts-BvyrT_QQ.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CHMq9ajE.js → Audit-prndoLiC.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Cyfa4ub2.js → BackgroundAgents-DOTFyA55.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-ACXUrUv7.js → Backup-9zOnPp_8.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DjC-3qRE.js → BaseInput-C4PC6sAG.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-7_VDQ851.js → Chat-BBAF-W9v.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-B4zct0dY.js → ChatBubbleRenderer-CWhvvloO.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DxbDl_rk.js → Checkbox-BI9iculd.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BvZa5854.js → Codegen-3DP9BCKb.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CX5Ow2Zl.js → Col-df-2TnJX.js} +1 -1
- package/src/assets/web-panel/assets/{Community-wFun-jSg.js → Community-CHs8gG_A.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-C6vJDuSn.js → Compact-CDfF6q7V.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Cm4sBytH.js → Compliance-CthrDnO7.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DiEcMwE8.js → Cowork-HjIqsWJw.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-RbeexsSQ.js → Cron-BKc196fb.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BBsyCKOp.js → Crosschain-CJnjdc8W.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DE36g7Hz.js → DID-BHUy-8Q2.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CdfLSTz1.js → Dashboard-QDB7sKeY.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CyaT6SyW.js → Dropdown-DStcVK11.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Nv_66bkM.js → EmailListRenderer-BwSUskMJ.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Di-Sb-Ad.js → FamilyGuardDashboard-DgF_kurT.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-B3mdht-U.js → Federation-k8wvv-wN.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BeP93u4f.js → FormItemContext-C11qoq2r.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CETLayUr.js → GenericCardRenderer-BIIpr9kg.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Bsat6hgI.js → Git-BlA1exTe.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-YVmA7SwN.js → Governance-CYa1ZYM4.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DCa94nGl.js → Inference-6_kKVIt6.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CIKEU7T0.js → KnowledgeGraph-CB4AwxYy.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DUxP0MnS.js → Logs-xf7nHFAe.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-Bf3DEqP6.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-BU0X2lqu.js → Marketplace-aPg8e4Jt.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BSsg58nZ.js → McpTools-C-TNlVUf.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CjqNIXlO.js → Memory-DMTPIpGa.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DSsa4doG.js → MobileBridge-BxyvveRq.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-DyPCrAyQ.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-Du080G7t.js → Mtc-BdhqNXp6.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-JzQk-arw.js → MtcAudit-Cz-HFxzW.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-BMVT5Uln.js → Multisig-CIUaFNsx.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D_38QYjs.js → NLProgramming-CWe6-J17.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DvbdjNm5.js → Notes-vYAKeviU.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DVHCW6ii.js → NotificationSettings-DQL9-2d7.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DmMBFD3g.js → OrderTableRenderer-DnXj1jBn.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DC-9pAmP.js → Organization-B3spU8AN.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-BRxWq0Qq.js → Overflow-DgEwo7vm.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CUdzhyLH.js → P2P-hujMRH8X.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CwG21s9P.js → PdhVaultBrowser-C_qhdg9h.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-6bHd4zgK.js → Permissions-vp7LMcSf.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BXgTDCba.js → PersonalDataHub-Dxr5Hgnq.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-BFhKCBNj.js → Pipeline-DEPZqqH4.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Byz9IqUF.js → Privacy-DTpDiKPe.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B9LNoyoN.js → ProjectInit-jDJsRWmF.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DEj4eVdl.js → ProjectSettings-Dhor5RWH.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BAAvus06.js → Projects-08xUDZGt.js} +1 -1
- package/src/assets/web-panel/assets/Providers-BGs47s1a.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-CeDey0SJ.js → QrScannerModal-CjIw-wIb.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-exUvRIgX.js → QuickAsk-DX6jcqoi.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-4hJWmtSI.js → Recommend-DopXkhar.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BmYUpl0m.js → RemoteSession-BLvqJE9c.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-B_txYAyY.js → Reputation-DhRj2Me7.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BPtqOqGh.js → Row-DQ53vuPq.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CyWTxmq0.js → RssFeed-BslvwiBD.js} +3 -3
- package/src/assets/web-panel/assets/{Search-cItU1tmC.js → Search-DJKBDNKZ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-B0Z9_BUt.js → Security-COhpxHER.js} +4 -4
- package/src/assets/web-panel/assets/{Services-Dzpz2uFp.js → Services-dbulD6cI.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CBtoylP8.js → Skeleton-ciIVNfhC.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Cw9RJiVn.js → Skills-AiRTkTCk.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-D2vLfvgl.js → Sla-DDMcWYBc.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-I9dKbcOU.js → SpeechSettings-BPxWbpXO.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BOju53RT.js → SyncSettings-BoEOXCyg.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CEYFJwmr.js +1 -0
- package/src/assets/web-panel/assets/{Templates-C2ttpPql.js → Templates-UowY8Ixe.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-XQ6Qg8-Q.js → Tenant-DauSLQXN.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DYB9dUnS.js → Terminal-DBj7Jneq.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-gShtO4I8.js → TimelineRenderer-UMrPwoZC.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BvoJTCJg.js → Tokens-4ea96-bn.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BwYRTMY_.js → Trigger--ISCqt4b.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-C5rt6fCF.js → Trust-D4GVimRJ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DPBrHUgL.js → UkeySign-Ci-nXRQc.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BcxywO_K.js → VideoEditing-Cjk7mKPw.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CZvTpsPz.js → Wallet-BgOLOO3Z.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-LI_jAuOx.js → WebAuthn-CCX0K29i.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-B2a6bANB.js → WorkflowEditor-Ch3zgIsE.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B6DPMfRB.js → chat-DKOU_2Vb.js} +1 -1
- package/src/assets/web-panel/assets/{colors-IpLhw9T8.js → colors-6OVo4u3C.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BzodimsI.js → compact-item-BH78Hlsq.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DL2jaWH5.js → createContext-CFRpSbbC.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DEMblAIm.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-C4Geudre.js → hasIn-DNQhgcVi.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVFXYmUe.js → index--rq90rL9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaKKxqCI.js → index-7TC3S8SN.js} +1 -1
- package/src/assets/web-panel/assets/{index-BaTvPxY0.js → index-AuBhLqOm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcgoKNXN.js → index-BDSR7ecX.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3LzRvkw.js → index-BHa4WyTZ.js} +1 -1
- package/src/assets/web-panel/assets/index-BTvq-36D.js +1 -0
- package/src/assets/web-panel/assets/{index-DvEnrn8M.js → index-BYrnm5Ob.js} +1 -1
- package/src/assets/web-panel/assets/{index-F-SCUTee.js → index-B_Z-YoxX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAjyUjZl.js → index-BaVE6E8y.js} +25 -25
- package/src/assets/web-panel/assets/{index-CQPOCB4h.js → index-Bb6kDrUx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZtKnnTW.js → index-BepBTpa8.js} +1 -1
- package/src/assets/web-panel/assets/{index-BX4pKudW.js → index-BkN3iTTp.js} +1 -1
- package/src/assets/web-panel/assets/{index-COxGCo8v.js → index-BnnXQot_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeUnSSEP.js → index-BujsOZfc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlABpgCv.js → index-BxRy5LPR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQBPhJlk.js → index-CFPJ8yzF.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dl_QAtzq.js → index-CNuCHHQT.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbWRxWM2.js → index-CaYqY35Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGBRBg3D.js → index-CkNEMANR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvOzjf2F.js → index-CkqHgG-b.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHdD0Y7h.js → index-CrcLHN2F.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5Sn7CtW.js → index-Cu3L4r5l.js} +1 -1
- package/src/assets/web-panel/assets/{index-DnBybYhx.js → index-D3RtTT4K.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnwHp5Oi.js → index-D84id2Y4.js} +1 -1
- package/src/assets/web-panel/assets/{index-EjW1R_a7.js → index-DKN2noIF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_SxaIPI.js → index-DaDgdJYj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bi6Zkv5M.js → index-Du0rnksC.js} +1 -1
- package/src/assets/web-panel/assets/{index-CczBR6Du.js → index-DvHGtNnF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTlmw_cr.js → index-Eag8e_mA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DREx4gaS.js → index-HNGGVF6o.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRj6YKuI.js → index-Y9MJv28e.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZU7Y67X.js → index-bKm3TUDp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvKoSvko.js → index-caye7AOE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXQ2OtXt.js → index-cdf7fd7d.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMY1waPC.js → index-dDkoL4Pe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeZhISVl.js → index-hPY0fFrd.js} +1 -1
- package/src/assets/web-panel/assets/index-hUpvk6Jl.js +1 -0
- package/src/assets/web-panel/assets/{index-DoyIjk6r.js → index-nbfHl1oV.js} +1 -1
- package/src/assets/web-panel/assets/{index-B6w4fpSI.js → index-sm7W8AXy.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CW5mTl3w.js → initDefaultProps-BZ9w6jPL.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BtjIT9np.js → motion-BnwUiOho.js} +1 -1
- package/src/assets/web-panel/assets/{move-DZv4fZAV.js → move-ByUKJnNm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BwCix1O-.js → mtc-parser-V7yK1KEl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BW72HDUD.js → omit-BEXBBt4j.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DBW2jcMc.js → pickAttrs-qDm_46Gi.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-D3YmWlIS.js → placementArrow-BIbhEo_0.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CL4-a-9Q.js → responsiveObserve-NbPbDgA_.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Cw9zIbXQ.js → slide-BnUWglZ0.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-mMLVioo-.js → statusUtils-BX8_wZI5.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BK8857AH.js → styleChecker-BV4OycQX.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-C1iSaJij.js → useFlexGapSupport-Od_H5llY.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D3riGOaP.js → useFs-BWI-PyiX.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-Bwqvmz4X.js → usePersonalDataHub-BqMuhG3g.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Byk4zzkf.js → vnode-DNd23z6f.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D7INFTp2.js → zoom-Cjaxnm7l.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/mcp.js +29 -1
- package/src/commands/pack.js +4 -4
- package/src/data/changelog.json +27 -1
- package/src/harness/mcp-client.js +15 -2
- package/src/harness/prompt-compressor.js +22 -4
- package/src/lib/cowork-mcp-tools.js +1 -0
- package/src/lib/cowork-task-templates.js +1 -0
- package/src/lib/mcp-stdio-executable-identity.js +75 -11
- package/src/lib/mcp-stdio-execution-authority.js +5 -0
- package/src/lib/packer/index.js +1 -1
- package/src/lib/packer/native-prebuild-collector.js +3 -3
- package/src/lib/packer/pack-update-checker.js +2 -2
- package/src/lib/packer/pkg-config-generator.js +12 -11
- package/src/lib/packer/web-panel-builder.js +6 -3
- package/src/lib/process-execution-broker/index.js +321 -23
- package/src/lib/process-execution-broker/platform-sandbox.js +494 -21
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +5 -4
- package/src/lib/session-tail.js +56 -24
- package/src/lib/skill-mcp.js +10 -0
- package/src/runtime/mcp-config.js +3 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-Mw5o3e7M.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DLl1qzid.js +0 -1
- package/src/assets/web-panel/assets/Providers-Bu_pQsk6.js +0 -1
- package/src/assets/web-panel/assets/Tasks-C3LBy_7x.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CZB0EDsa.js +0 -1
- package/src/assets/web-panel/assets/index-CI7k8Sk9.js +0 -1
- package/src/assets/web-panel/assets/index-DPTHBSR8.js +0 -1
|
@@ -169,7 +169,14 @@ const LINUX_EXECUTABLE_SNAPSHOT_SOURCE_MODE = 0o500;
|
|
|
169
169
|
const LINUX_MCP_CAPSULE_BACKEND = "linux-fd-code-snapshot";
|
|
170
170
|
const LINUX_MCP_RUNTIME_SNAPSHOT_SCOPE = "mcp-node-runtime-executable";
|
|
171
171
|
const LINUX_MCP_CAPSULE_SNAPSHOT_MECHANISM =
|
|
172
|
-
"verified-o_tmpfile-copy-inherited-fd-
|
|
172
|
+
"verified-o_tmpfile-copy-inherited-fd-module-compile-v1";
|
|
173
|
+
const MACOS_MCP_CAPSULE_BACKEND = "macos-fd-code-snapshot";
|
|
174
|
+
export const MCP_STDIO_FD_ENTRY_BOOTSTRAP =
|
|
175
|
+
'const fs=require("node:fs");const Module=require("node:module");const filename="/chainlesschain/mcp-capsule.cjs";const source=fs.readFileSync(4,"utf8");process.argv.splice(1,0,filename);const target=new Module(filename,module);target.filename=filename;target.paths=[];target._compile(source,filename);';
|
|
176
|
+
export const MCP_STDIO_FD_ENTRY_BOOTSTRAP_SHA256 = crypto
|
|
177
|
+
.createHash("sha256")
|
|
178
|
+
.update(MCP_STDIO_FD_ENTRY_BOOTSTRAP)
|
|
179
|
+
.digest("hex");
|
|
173
180
|
const LINUX_NODE_ENTRY_SNAPSHOT_SCOPE = "plugin-entry-source";
|
|
174
181
|
const LINUX_NATIVE_ENTRY_SNAPSHOT_SCOPE = "plugin-entry-executable";
|
|
175
182
|
const LINUX_NODE_PLUGIN_TREE_SNAPSHOT_SCOPE = "all-pinned-plugin-regular-files";
|
|
@@ -283,6 +290,14 @@ const windowsAdapterCacheEntries = new Set();
|
|
|
283
290
|
const windowsTemporaryCleanupBacklog = new Set();
|
|
284
291
|
let windowsTemporaryCleanupRetryTimer = null;
|
|
285
292
|
const windowsAppContainerCleanupBacklog = new Set();
|
|
293
|
+
const issuedWindowsMcpCodeSnapshotPlans = new WeakMap();
|
|
294
|
+
// Only the unified production adapter can register a Windows MCP launch
|
|
295
|
+
// capability. Direct callers of the exported platform-specific helper (and
|
|
296
|
+
// callers that inject a test/runtime facade into applySandbox) may exercise
|
|
297
|
+
// plan construction, but cannot mint a Broker-admissible capability.
|
|
298
|
+
const WINDOWS_MCP_CODE_SNAPSHOT_ISSUER = Symbol(
|
|
299
|
+
"windows-mcp-code-snapshot-issuer",
|
|
300
|
+
);
|
|
286
301
|
// Each AppContainer retry starts a synchronous, digest-attested PowerShell
|
|
287
302
|
// helper. Bound automatic retries so a permanently unsupported Windows host
|
|
288
303
|
// cannot repeatedly block a long-lived CLI; explicit cleanup/reset and process
|
|
@@ -453,6 +468,8 @@ export function generateMacSeatbeltProfile(opts = {}, runtimeOverrides = {}) {
|
|
|
453
468
|
allowNetwork = false,
|
|
454
469
|
allowExec = true,
|
|
455
470
|
} = opts;
|
|
471
|
+
const seatbeltLiteral = (value) =>
|
|
472
|
+
String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
456
473
|
|
|
457
474
|
const lines = [
|
|
458
475
|
"(version 1)",
|
|
@@ -485,12 +502,12 @@ export function generateMacSeatbeltProfile(opts = {}, runtimeOverrides = {}) {
|
|
|
485
502
|
|
|
486
503
|
// Allow read/write to specific paths
|
|
487
504
|
for (const p of allowRead) {
|
|
488
|
-
const abs = runtime.resolvePath(p);
|
|
505
|
+
const abs = seatbeltLiteral(runtime.resolvePath(p));
|
|
489
506
|
lines.push(`(allow file-read* (subpath "${abs}"))`);
|
|
490
507
|
}
|
|
491
508
|
|
|
492
509
|
for (const p of allowWrite) {
|
|
493
|
-
const abs = runtime.resolvePath(p);
|
|
510
|
+
const abs = seatbeltLiteral(runtime.resolvePath(p));
|
|
494
511
|
lines.push(`(allow file-read* file-write* (subpath "${abs}"))`);
|
|
495
512
|
}
|
|
496
513
|
|
|
@@ -511,6 +528,144 @@ export function generateMacSeatbeltProfile(opts = {}, runtimeOverrides = {}) {
|
|
|
511
528
|
return lines.join("\n");
|
|
512
529
|
}
|
|
513
530
|
|
|
531
|
+
function validateMacMcpCapsuleContract(
|
|
532
|
+
command,
|
|
533
|
+
args,
|
|
534
|
+
spawnOpts,
|
|
535
|
+
contract,
|
|
536
|
+
runtime,
|
|
537
|
+
sync,
|
|
538
|
+
) {
|
|
539
|
+
if (
|
|
540
|
+
contract?.kind !== MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND ||
|
|
541
|
+
contract.contractVersion !== 1 ||
|
|
542
|
+
(sync !== true && sync !== false) ||
|
|
543
|
+
spawnOpts?.shell !== false ||
|
|
544
|
+
!linuxStdioIsNarrow(spawnOpts?.stdio) ||
|
|
545
|
+
spawnOpts?.serialization !== undefined ||
|
|
546
|
+
spawnOpts?.argv0 !== undefined ||
|
|
547
|
+
spawnOpts?.uid !== undefined ||
|
|
548
|
+
spawnOpts?.gid !== undefined ||
|
|
549
|
+
!Array.isArray(args) ||
|
|
550
|
+
args.length < 1 ||
|
|
551
|
+
args.some((value) => typeof value !== "string" || value.includes("\0")) ||
|
|
552
|
+
command !== contract.runtimePath ||
|
|
553
|
+
command !== contract.runtimeIdentity?.realPath ||
|
|
554
|
+
args[0] !== contract.entryIdentity?.realPath ||
|
|
555
|
+
![".js", ".cjs", ".mjs"].includes(
|
|
556
|
+
path.posix.extname(contract.entryIdentity?.realPath || "").toLowerCase(),
|
|
557
|
+
)
|
|
558
|
+
) {
|
|
559
|
+
return { ok: false, reason: "launch_identity_mismatch" };
|
|
560
|
+
}
|
|
561
|
+
for (const value of [
|
|
562
|
+
contract.pluginRoot,
|
|
563
|
+
contract.workingDirectory,
|
|
564
|
+
contract.rootIdentity?.realPath,
|
|
565
|
+
contract.entryIdentity?.realPath,
|
|
566
|
+
contract.runtimeIdentity?.realPath,
|
|
567
|
+
]) {
|
|
568
|
+
if (
|
|
569
|
+
typeof value !== "string" ||
|
|
570
|
+
!path.posix.isAbsolute(value) ||
|
|
571
|
+
value.includes("\0")
|
|
572
|
+
) {
|
|
573
|
+
return { ok: false, reason: "noncanonical_contract_path" };
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
try {
|
|
577
|
+
if (
|
|
578
|
+
linuxRealpath(runtime, contract.pluginRoot) !== contract.pluginRoot ||
|
|
579
|
+
linuxRealpath(runtime, contract.workingDirectory) !==
|
|
580
|
+
contract.workingDirectory ||
|
|
581
|
+
linuxRealpath(runtime, spawnOpts.cwd) !== contract.pluginRoot ||
|
|
582
|
+
contract.workingDirectory !== contract.pluginRoot ||
|
|
583
|
+
contract.rootIdentity?.realPath !== contract.pluginRoot ||
|
|
584
|
+
!linuxPathWithin(contract.pluginRoot, contract.entryIdentity.realPath)
|
|
585
|
+
) {
|
|
586
|
+
return { ok: false, reason: "noncanonical_contract_path" };
|
|
587
|
+
}
|
|
588
|
+
} catch {
|
|
589
|
+
return { ok: false, reason: "contract_path_unavailable" };
|
|
590
|
+
}
|
|
591
|
+
if (
|
|
592
|
+
!linuxDirectoryIdentityMatches(runtime, contract.rootIdentity) ||
|
|
593
|
+
!linuxIdentityMatches(runtime, contract.runtimeIdentity, {
|
|
594
|
+
executable: true,
|
|
595
|
+
}) ||
|
|
596
|
+
!linuxIdentityMatches(runtime, contract.entryIdentity)
|
|
597
|
+
) {
|
|
598
|
+
return { ok: false, reason: "execution_identity_changed" };
|
|
599
|
+
}
|
|
600
|
+
return { ok: true };
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
function applyMacMcpCapsuleCodeSnapshot(
|
|
604
|
+
command,
|
|
605
|
+
args,
|
|
606
|
+
spawnOpts,
|
|
607
|
+
sandboxOpts,
|
|
608
|
+
runtime,
|
|
609
|
+
base,
|
|
610
|
+
) {
|
|
611
|
+
const contract = sandboxOpts.executionContract;
|
|
612
|
+
const validation = validateMacMcpCapsuleContract(
|
|
613
|
+
command,
|
|
614
|
+
args,
|
|
615
|
+
spawnOpts,
|
|
616
|
+
contract,
|
|
617
|
+
runtime,
|
|
618
|
+
sandboxOpts.sync,
|
|
619
|
+
);
|
|
620
|
+
const unavailable = (reason, runtimeProbe = null) =>
|
|
621
|
+
createSandboxPlan({
|
|
622
|
+
...base,
|
|
623
|
+
backend: null,
|
|
624
|
+
candidateBackend: MACOS_MCP_CAPSULE_BACKEND,
|
|
625
|
+
policyAttested: false,
|
|
626
|
+
runtimeProbe: runtimeProbe
|
|
627
|
+
? {
|
|
628
|
+
kind: "darwin-mcp-capsule-code-snapshot-v1",
|
|
629
|
+
attempted: runtimeProbe.attempted !== false,
|
|
630
|
+
probeRuntime: "node",
|
|
631
|
+
targetRuntime: "node",
|
|
632
|
+
...runtimeProbe,
|
|
633
|
+
}
|
|
634
|
+
: null,
|
|
635
|
+
reason,
|
|
636
|
+
guarantees: [],
|
|
637
|
+
});
|
|
638
|
+
if (!validation.ok) {
|
|
639
|
+
return unavailable("macos_mcp_capsule_execution_contract_invalid", {
|
|
640
|
+
attempted: false,
|
|
641
|
+
runnable: false,
|
|
642
|
+
reason: validation.reason,
|
|
643
|
+
contentSnapshot: false,
|
|
644
|
+
handleAtomic: false,
|
|
645
|
+
entrySnapshotAtomic: false,
|
|
646
|
+
runtimeLaunchAtomic: false,
|
|
647
|
+
sharedLibraryClosure: false,
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Darwin exposes only pathname-based exec/spawn APIs to an unprivileged
|
|
652
|
+
// process. An inherited descriptor can bind the entry source, but public
|
|
653
|
+
// APIs cannot bind the verified Node runtime descriptor to the image that
|
|
654
|
+
// executes. Private temporary paths and Seatbelt still leave a same-UID
|
|
655
|
+
// pathname-replacement window, so they cannot satisfy CODE_SNAPSHOT.
|
|
656
|
+
return unavailable("macos_atomic_runtime_exec_unavailable", {
|
|
657
|
+
attempted: true,
|
|
658
|
+
runnable: false,
|
|
659
|
+
reason: "public_api_has_no_descriptor_bound_exec",
|
|
660
|
+
contentSnapshot: false,
|
|
661
|
+
handleAtomic: false,
|
|
662
|
+
entrySnapshotAtomic: false,
|
|
663
|
+
runtimeLaunchAtomic: false,
|
|
664
|
+
runtimeLaunchMechanism: "darwin-public-api-pathname-exec-only-v1",
|
|
665
|
+
sharedLibraryClosure: false,
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
|
|
514
669
|
/**
|
|
515
670
|
* Apply macOS sandbox via SBWritableProfile or sandbox-exec wrapper.
|
|
516
671
|
*
|
|
@@ -552,6 +707,20 @@ export function applyMacSandbox(
|
|
|
552
707
|
});
|
|
553
708
|
}
|
|
554
709
|
|
|
710
|
+
if (
|
|
711
|
+
Array.isArray(sandboxOpts.requiredBoundaries) &&
|
|
712
|
+
sandboxOpts.requiredBoundaries.includes(SANDBOX_BOUNDARIES.CODE_SNAPSHOT)
|
|
713
|
+
) {
|
|
714
|
+
return applyMacMcpCapsuleCodeSnapshot(
|
|
715
|
+
command,
|
|
716
|
+
args,
|
|
717
|
+
spawnOpts,
|
|
718
|
+
sandboxOpts,
|
|
719
|
+
runtime,
|
|
720
|
+
base,
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
|
|
555
724
|
// A deny-by-default Seatbelt profile cannot safely infer the filesystem,
|
|
556
725
|
// IPC, and inherited-descriptor access required by an arbitrary command.
|
|
557
726
|
// Keep the boundary truthful for the broker's implicit default profile:
|
|
@@ -731,6 +900,218 @@ function sha256(value) {
|
|
|
731
900
|
return crypto.createHash("sha256").update(value).digest("hex");
|
|
732
901
|
}
|
|
733
902
|
|
|
903
|
+
function sameStringArray(left, right) {
|
|
904
|
+
return (
|
|
905
|
+
Array.isArray(left) &&
|
|
906
|
+
Array.isArray(right) &&
|
|
907
|
+
left.length === right.length &&
|
|
908
|
+
left.every((value, index) => value === right[index])
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
function captureWindowsStdio(stdio) {
|
|
913
|
+
if (Array.isArray(stdio)) return Object.freeze([...stdio]);
|
|
914
|
+
return stdio ?? null;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
function sameWindowsStdio(left, right) {
|
|
918
|
+
const normalizedRight = right ?? null;
|
|
919
|
+
if (Array.isArray(left) || Array.isArray(normalizedRight)) {
|
|
920
|
+
return (
|
|
921
|
+
Array.isArray(left) &&
|
|
922
|
+
Array.isArray(normalizedRight) &&
|
|
923
|
+
left.length === normalizedRight.length &&
|
|
924
|
+
left.every((entry, index) => Object.is(entry, normalizedRight[index]))
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
return Object.is(left, normalizedRight);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
function windowsStdioDigestContract(stdio) {
|
|
931
|
+
const normalizeEntry = (entry) => {
|
|
932
|
+
if (entry === null || entry === undefined) return ["null"];
|
|
933
|
+
if (typeof entry === "string") return ["string", entry];
|
|
934
|
+
if (Number.isInteger(entry)) return ["fd", entry];
|
|
935
|
+
return [typeof entry];
|
|
936
|
+
};
|
|
937
|
+
return Array.isArray(stdio)
|
|
938
|
+
? ["array", ...stdio.map(normalizeEntry)]
|
|
939
|
+
: ["scalar", ...normalizeEntry(stdio)];
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
function windowsEnvironmentDigest(env) {
|
|
943
|
+
const entries = Object.entries(env || {})
|
|
944
|
+
.map(([key, value]) => [key, String(value)])
|
|
945
|
+
.sort(([leftKey, leftValue], [rightKey, rightValue]) => {
|
|
946
|
+
if (leftKey !== rightKey) return leftKey < rightKey ? -1 : 1;
|
|
947
|
+
if (leftValue === rightValue) return 0;
|
|
948
|
+
return leftValue < rightValue ? -1 : 1;
|
|
949
|
+
});
|
|
950
|
+
return sha256(JSON.stringify(entries));
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
function windowsMcpBindingIdentity(identity) {
|
|
954
|
+
if (!identity) return null;
|
|
955
|
+
return {
|
|
956
|
+
contractVersion: identity.contractVersion ?? null,
|
|
957
|
+
realPath: identity.realPath ?? null,
|
|
958
|
+
sha256: identity.sha256 ?? null,
|
|
959
|
+
bytes: identity.bytes ?? null,
|
|
960
|
+
fileId: identity.fileId
|
|
961
|
+
? {
|
|
962
|
+
dev: identity.fileId.dev ?? null,
|
|
963
|
+
ino: identity.fileId.ino ?? null,
|
|
964
|
+
}
|
|
965
|
+
: null,
|
|
966
|
+
mtimeMs: identity.mtimeMs ?? null,
|
|
967
|
+
attestation: identity.attestation ?? null,
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
function windowsMcpBindingContract(contract) {
|
|
972
|
+
return {
|
|
973
|
+
contractVersion: contract?.contractVersion ?? null,
|
|
974
|
+
kind: contract?.kind ?? null,
|
|
975
|
+
pluginRoot: contract?.pluginRoot ?? null,
|
|
976
|
+
workingDirectory: contract?.workingDirectory ?? null,
|
|
977
|
+
runtimePath: contract?.runtimePath ?? null,
|
|
978
|
+
rootIdentity: contract?.rootIdentity
|
|
979
|
+
? {
|
|
980
|
+
realPath: contract.rootIdentity.realPath ?? null,
|
|
981
|
+
fileId: contract.rootIdentity.fileId
|
|
982
|
+
? {
|
|
983
|
+
dev: contract.rootIdentity.fileId.dev ?? null,
|
|
984
|
+
ino: contract.rootIdentity.fileId.ino ?? null,
|
|
985
|
+
}
|
|
986
|
+
: null,
|
|
987
|
+
attestation: contract.rootIdentity.attestation ?? null,
|
|
988
|
+
}
|
|
989
|
+
: null,
|
|
990
|
+
entryIdentity: windowsMcpBindingIdentity(contract?.entryIdentity),
|
|
991
|
+
runtimeIdentity: windowsMcpBindingIdentity(contract?.runtimeIdentity),
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
function createWindowsMcpCodeSnapshotPlanBinding({
|
|
996
|
+
executionContract,
|
|
997
|
+
command,
|
|
998
|
+
args,
|
|
999
|
+
spawnOpts,
|
|
1000
|
+
profile,
|
|
1001
|
+
requiredBoundaries,
|
|
1002
|
+
sync,
|
|
1003
|
+
backend,
|
|
1004
|
+
policyAttested,
|
|
1005
|
+
policyDigest,
|
|
1006
|
+
adapterSource,
|
|
1007
|
+
helperInvocation,
|
|
1008
|
+
helperOptions,
|
|
1009
|
+
postSpawn,
|
|
1010
|
+
postSpawnWindows,
|
|
1011
|
+
}) {
|
|
1012
|
+
const helperEnvDigest = windowsEnvironmentDigest(helperOptions.env);
|
|
1013
|
+
const helperStdio = captureWindowsStdio(helperOptions.stdio);
|
|
1014
|
+
const originalArgs = Object.freeze([...(args || [])]);
|
|
1015
|
+
const helperArgs = Object.freeze([...(helperInvocation.args || [])]);
|
|
1016
|
+
const normalizedPostSpawn = Object.freeze({
|
|
1017
|
+
required: postSpawn?.required === true,
|
|
1018
|
+
mode: postSpawn?.mode || "none",
|
|
1019
|
+
});
|
|
1020
|
+
const digestPayload = {
|
|
1021
|
+
version: 1,
|
|
1022
|
+
kind: "windows-mcp-code-snapshot-plan-binding-v1",
|
|
1023
|
+
executionContract: windowsMcpBindingContract(executionContract),
|
|
1024
|
+
originalLaunch: {
|
|
1025
|
+
command,
|
|
1026
|
+
args: originalArgs,
|
|
1027
|
+
cwd: spawnOpts?.cwd ?? null,
|
|
1028
|
+
shell: spawnOpts?.shell ?? null,
|
|
1029
|
+
detached: spawnOpts?.detached ?? null,
|
|
1030
|
+
profile,
|
|
1031
|
+
requiredBoundaries: [...requiredBoundaries],
|
|
1032
|
+
sync,
|
|
1033
|
+
},
|
|
1034
|
+
policy: { backend, policyAttested, policyDigest },
|
|
1035
|
+
adapter: {
|
|
1036
|
+
loaderMode: adapterSource.loaderMode,
|
|
1037
|
+
sourceDigest: adapterSource.sourceDigest,
|
|
1038
|
+
sourceContractDigest: adapterSource.sourceContractDigest,
|
|
1039
|
+
},
|
|
1040
|
+
helperInvocation: {
|
|
1041
|
+
command: helperInvocation.command,
|
|
1042
|
+
args: helperArgs,
|
|
1043
|
+
cwd: helperOptions.cwd ?? null,
|
|
1044
|
+
shell: helperOptions.shell ?? null,
|
|
1045
|
+
detached: helperOptions.detached ?? null,
|
|
1046
|
+
envDigest: helperEnvDigest,
|
|
1047
|
+
stdio: windowsStdioDigestContract(helperStdio),
|
|
1048
|
+
},
|
|
1049
|
+
postSpawn: normalizedPostSpawn,
|
|
1050
|
+
};
|
|
1051
|
+
return Object.freeze({
|
|
1052
|
+
executionContract,
|
|
1053
|
+
originalCommand: command,
|
|
1054
|
+
originalArgs,
|
|
1055
|
+
originalCwd: spawnOpts?.cwd ?? null,
|
|
1056
|
+
originalShell: spawnOpts?.shell ?? null,
|
|
1057
|
+
originalDetached: spawnOpts?.detached ?? null,
|
|
1058
|
+
profile,
|
|
1059
|
+
requiredBoundaries: Object.freeze([...requiredBoundaries]),
|
|
1060
|
+
sync,
|
|
1061
|
+
backend,
|
|
1062
|
+
policyAttested,
|
|
1063
|
+
policyDigest,
|
|
1064
|
+
helperCommand: helperInvocation.command,
|
|
1065
|
+
helperArgs,
|
|
1066
|
+
helperCwd: helperOptions.cwd ?? null,
|
|
1067
|
+
helperShell: helperOptions.shell ?? null,
|
|
1068
|
+
helperDetached: helperOptions.detached ?? null,
|
|
1069
|
+
helperEnvDigest,
|
|
1070
|
+
helperStdio,
|
|
1071
|
+
postSpawn: normalizedPostSpawn,
|
|
1072
|
+
postSpawnWindows: postSpawnWindows || null,
|
|
1073
|
+
planBindingDigest: sha256(JSON.stringify(digestPayload)),
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Consume the one-launch capability attached to a real built-in Windows MCP
|
|
1079
|
+
* code-snapshot plan. The issuer stays module-private so an injected adapter
|
|
1080
|
+
* cannot make a structurally similar helper payload authoritative.
|
|
1081
|
+
*/
|
|
1082
|
+
export function consumeWindowsMcpCodeSnapshotPlanBinding(plan, expected = {}) {
|
|
1083
|
+
const issued = issuedWindowsMcpCodeSnapshotPlans.get(plan);
|
|
1084
|
+
if (!issued) return false;
|
|
1085
|
+
issuedWindowsMcpCodeSnapshotPlans.delete(plan);
|
|
1086
|
+
return (
|
|
1087
|
+
issued.executionContract === expected.executionContract &&
|
|
1088
|
+
issued.originalCommand === expected.command &&
|
|
1089
|
+
sameStringArray(issued.originalArgs, expected.args) &&
|
|
1090
|
+
issued.originalCwd === (expected.cwd ?? null) &&
|
|
1091
|
+
issued.originalShell === (expected.shell ?? null) &&
|
|
1092
|
+
issued.originalDetached === (expected.detached ?? null) &&
|
|
1093
|
+
issued.profile === expected.profile &&
|
|
1094
|
+
sameStringArray(issued.requiredBoundaries, expected.requiredBoundaries) &&
|
|
1095
|
+
issued.sync === (expected.sync === true) &&
|
|
1096
|
+
plan.backend === issued.backend &&
|
|
1097
|
+
plan.policyAttested === issued.policyAttested &&
|
|
1098
|
+
plan.policyDigest === issued.policyDigest &&
|
|
1099
|
+
plan.command === issued.helperCommand &&
|
|
1100
|
+
sameStringArray(plan.args, issued.helperArgs) &&
|
|
1101
|
+
plan.options?.cwd === issued.helperCwd &&
|
|
1102
|
+
plan.options?.shell === issued.helperShell &&
|
|
1103
|
+
plan.options?.detached === issued.helperDetached &&
|
|
1104
|
+
windowsEnvironmentDigest(plan.options?.env) === issued.helperEnvDigest &&
|
|
1105
|
+
sameWindowsStdio(issued.helperStdio, plan.options?.stdio) &&
|
|
1106
|
+
plan.postSpawn?.required === issued.postSpawn.required &&
|
|
1107
|
+
plan.postSpawn?.mode === issued.postSpawn.mode &&
|
|
1108
|
+
(plan.postSpawnWindows || null) === issued.postSpawnWindows &&
|
|
1109
|
+
plan.runtimeProbe?.planBindingMechanism ===
|
|
1110
|
+
"windows-mcp-code-snapshot-plan-binding-v1" &&
|
|
1111
|
+
plan.runtimeProbe?.planBindingDigest === issued.planBindingDigest
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
734
1115
|
function windowsFileIdentity(stat) {
|
|
735
1116
|
const timestamp = (nanosecondsKey, millisecondsKey) => {
|
|
736
1117
|
if (stat[nanosecondsKey] !== undefined) {
|
|
@@ -2041,6 +2422,16 @@ function windowsAppContainerPolicyDigest({
|
|
|
2041
2422
|
? "verified-handle-inherited-pipe-module-compile-v1"
|
|
2042
2423
|
: null,
|
|
2043
2424
|
handleAtomic: false,
|
|
2425
|
+
...(snapshotLocks.length > 0 &&
|
|
2426
|
+
executionContract?.kind === MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND
|
|
2427
|
+
? {
|
|
2428
|
+
entrySnapshotAtomic: true,
|
|
2429
|
+
runtimeLaunchAtomic: true,
|
|
2430
|
+
runtimeLaunchMechanism:
|
|
2431
|
+
"filter-oplock-locked-createprocess-suspended-image-v1",
|
|
2432
|
+
sharedLibraryClosure: false,
|
|
2433
|
+
}
|
|
2434
|
+
: {}),
|
|
2044
2435
|
launchPathLocks: snapshotLocks,
|
|
2045
2436
|
},
|
|
2046
2437
|
}),
|
|
@@ -2067,6 +2458,7 @@ export function applyWindowsSandbox(
|
|
|
2067
2458
|
spawnOpts,
|
|
2068
2459
|
sandboxOpts = {},
|
|
2069
2460
|
runtimeOverrides = {},
|
|
2461
|
+
planBindingAuthority = null,
|
|
2070
2462
|
) {
|
|
2071
2463
|
let runtime = resolveRuntime(runtimeOverrides);
|
|
2072
2464
|
const requiredBoundaries = Array.isArray(sandboxOpts.requiredBoundaries)
|
|
@@ -2087,6 +2479,10 @@ export function applyWindowsSandbox(
|
|
|
2087
2479
|
SANDBOX_BOUNDARIES.RESOURCE_LIMITS,
|
|
2088
2480
|
SANDBOX_BOUNDARIES.PRIVILEGE_REDUCTION,
|
|
2089
2481
|
];
|
|
2482
|
+
const appContainerSupportedBoundaries = [
|
|
2483
|
+
...appContainerGuarantees,
|
|
2484
|
+
SANDBOX_BOUNDARIES.CODE_SNAPSHOT,
|
|
2485
|
+
];
|
|
2090
2486
|
const base = {
|
|
2091
2487
|
platform: runtime.platform,
|
|
2092
2488
|
profile: sandboxOpts.profileName || "default",
|
|
@@ -2133,7 +2529,7 @@ export function applyWindowsSandbox(
|
|
|
2133
2529
|
if (
|
|
2134
2530
|
requiresAppContainer &&
|
|
2135
2531
|
requiredBoundaries.some(
|
|
2136
|
-
(boundary) => !
|
|
2532
|
+
(boundary) => !appContainerSupportedBoundaries.includes(boundary),
|
|
2137
2533
|
)
|
|
2138
2534
|
) {
|
|
2139
2535
|
return unavailablePlan("windows_appcontainer_boundary_unsupported");
|
|
@@ -2493,10 +2889,14 @@ export function applyWindowsSandbox(
|
|
|
2493
2889
|
detached: false,
|
|
2494
2890
|
shell: false,
|
|
2495
2891
|
cwd: helperWorkingDirectory,
|
|
2496
|
-
env: hostEnvironment,
|
|
2892
|
+
env: Object.freeze({ ...hostEnvironment }),
|
|
2893
|
+
stdio: Array.isArray(invocation.options.stdio)
|
|
2894
|
+
? Object.freeze([...invocation.options.stdio])
|
|
2895
|
+
: invocation.options.stdio,
|
|
2497
2896
|
};
|
|
2498
2897
|
let appContainerCleanupVerified = false;
|
|
2499
2898
|
let appContainerCleanupRecord = null;
|
|
2899
|
+
let issuedWindowsMcpPlan = null;
|
|
2500
2900
|
const cleanupAppContainer = () => {
|
|
2501
2901
|
if (!appContainer || appContainerCleanupVerified) return true;
|
|
2502
2902
|
if (appContainerCleanupRecord) {
|
|
@@ -2534,6 +2934,10 @@ export function applyWindowsSandbox(
|
|
|
2534
2934
|
return false;
|
|
2535
2935
|
};
|
|
2536
2936
|
const cleanup = () => {
|
|
2937
|
+
if (issuedWindowsMcpPlan) {
|
|
2938
|
+
issuedWindowsMcpCodeSnapshotPlans.delete(issuedWindowsMcpPlan);
|
|
2939
|
+
issuedWindowsMcpPlan = null;
|
|
2940
|
+
}
|
|
2537
2941
|
const failures = [];
|
|
2538
2942
|
const attempt = (label, action) => {
|
|
2539
2943
|
try {
|
|
@@ -2594,6 +2998,28 @@ export function applyWindowsSandbox(
|
|
|
2594
2998
|
},
|
|
2595
2999
|
}
|
|
2596
3000
|
: {};
|
|
3001
|
+
const windowsMcpPlanBinding =
|
|
3002
|
+
entrySnapshot.locks &&
|
|
3003
|
+
sandboxOpts.executionContract?.kind ===
|
|
3004
|
+
MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND
|
|
3005
|
+
? createWindowsMcpCodeSnapshotPlanBinding({
|
|
3006
|
+
executionContract: sandboxOpts.executionContract,
|
|
3007
|
+
command,
|
|
3008
|
+
args,
|
|
3009
|
+
spawnOpts,
|
|
3010
|
+
profile,
|
|
3011
|
+
requiredBoundaries,
|
|
3012
|
+
sync: sandboxOpts.sync === true,
|
|
3013
|
+
backend,
|
|
3014
|
+
policyAttested: requiresAppContainer ? true : null,
|
|
3015
|
+
policyDigest: appContainerPolicyDigest,
|
|
3016
|
+
adapterSource,
|
|
3017
|
+
helperInvocation,
|
|
3018
|
+
helperOptions: options,
|
|
3019
|
+
postSpawn: identityContract.postSpawn,
|
|
3020
|
+
postSpawnWindows: identityContract.postSpawnWindows,
|
|
3021
|
+
})
|
|
3022
|
+
: null;
|
|
2597
3023
|
const entrySnapshotRuntimeProbe = entrySnapshot.locks
|
|
2598
3024
|
? {
|
|
2599
3025
|
...(appContainerRuntimeProbe || nodeSnapshotRuntimeProbe),
|
|
@@ -2622,13 +3048,17 @@ export function applyWindowsSandbox(
|
|
|
2622
3048
|
({ role }) => role === "entry",
|
|
2623
3049
|
)?.bytes,
|
|
2624
3050
|
entrySnapshotAtomic: true,
|
|
2625
|
-
runtimeLaunchAtomic:
|
|
3051
|
+
runtimeLaunchAtomic: true,
|
|
3052
|
+
runtimeLaunchMechanism:
|
|
3053
|
+
"filter-oplock-locked-createprocess-suspended-image-v1",
|
|
2626
3054
|
sharedLibraryClosure: false,
|
|
3055
|
+
planBindingMechanism: "windows-mcp-code-snapshot-plan-binding-v1",
|
|
3056
|
+
planBindingDigest: windowsMcpPlanBinding.planBindingDigest,
|
|
2627
3057
|
}
|
|
2628
3058
|
: {}),
|
|
2629
3059
|
}
|
|
2630
3060
|
: appContainerRuntimeProbe;
|
|
2631
|
-
|
|
3061
|
+
const plan = createSandboxPlan({
|
|
2632
3062
|
...base,
|
|
2633
3063
|
applied: true,
|
|
2634
3064
|
enforcement: backend,
|
|
@@ -2655,6 +3085,14 @@ export function applyWindowsSandbox(
|
|
|
2655
3085
|
...identityContract,
|
|
2656
3086
|
cleanup,
|
|
2657
3087
|
});
|
|
3088
|
+
if (
|
|
3089
|
+
windowsMcpPlanBinding &&
|
|
3090
|
+
planBindingAuthority === WINDOWS_MCP_CODE_SNAPSHOT_ISSUER
|
|
3091
|
+
) {
|
|
3092
|
+
issuedWindowsMcpPlan = plan;
|
|
3093
|
+
issuedWindowsMcpCodeSnapshotPlans.set(plan, windowsMcpPlanBinding);
|
|
3094
|
+
}
|
|
3095
|
+
return plan;
|
|
2658
3096
|
}
|
|
2659
3097
|
|
|
2660
3098
|
/**
|
|
@@ -3817,7 +4255,6 @@ function applyLinuxMcpCapsuleCodeSnapshot(
|
|
|
3817
4255
|
]);
|
|
3818
4256
|
const descriptors = [runtimeSnapshot.finalMount, entrySnapshot.finalMount];
|
|
3819
4257
|
const runtimeFd = 3;
|
|
3820
|
-
const entryFd = 4;
|
|
3821
4258
|
const snapshotIdentity = Object.freeze({
|
|
3822
4259
|
runtimeSnapshotSha256: runtimeSnapshot.attestation.sha256,
|
|
3823
4260
|
runtimeSnapshotBytes: runtimeSnapshot.attestation.bytes,
|
|
@@ -3834,6 +4271,8 @@ function applyLinuxMcpCapsuleCodeSnapshot(
|
|
|
3834
4271
|
].sort(),
|
|
3835
4272
|
identity: snapshotIdentity,
|
|
3836
4273
|
cwd: invocation.options.cwd,
|
|
4274
|
+
entrySnapshotBootstrapSha256: MCP_STDIO_FD_ENTRY_BOOTSTRAP_SHA256,
|
|
4275
|
+
runtimeLaunchMechanism: "inherited-executable-fd-v1",
|
|
3837
4276
|
passthroughArgsDigest: sha256(JSON.stringify(invocation.args.slice(1))),
|
|
3838
4277
|
}),
|
|
3839
4278
|
);
|
|
@@ -3862,13 +4301,22 @@ function applyLinuxMcpCapsuleCodeSnapshot(
|
|
|
3862
4301
|
contentSnapshotScope: "mcp-capsule-entry-and-node-runtime",
|
|
3863
4302
|
contentSnapshotMechanism: LINUX_MCP_CAPSULE_SNAPSHOT_MECHANISM,
|
|
3864
4303
|
handleAtomic: true,
|
|
4304
|
+
entrySnapshotAtomic: true,
|
|
4305
|
+
runtimeLaunchAtomic: true,
|
|
4306
|
+
runtimeLaunchMechanism: "inherited-executable-fd-v1",
|
|
4307
|
+
entrySnapshotBootstrapSha256: MCP_STDIO_FD_ENTRY_BOOTSTRAP_SHA256,
|
|
3865
4308
|
sharedLibraryClosure: false,
|
|
3866
4309
|
...snapshotIdentity,
|
|
3867
4310
|
},
|
|
3868
4311
|
reason: null,
|
|
3869
4312
|
guarantees: [SANDBOX_BOUNDARIES.CODE_SNAPSHOT],
|
|
3870
4313
|
command: `/proc/self/fd/${runtimeFd}`,
|
|
3871
|
-
args: [
|
|
4314
|
+
args: [
|
|
4315
|
+
"-e",
|
|
4316
|
+
MCP_STDIO_FD_ENTRY_BOOTSTRAP,
|
|
4317
|
+
"--",
|
|
4318
|
+
...invocation.args.slice(1),
|
|
4319
|
+
],
|
|
3872
4320
|
options: {
|
|
3873
4321
|
...invocation.options,
|
|
3874
4322
|
shell: false,
|
|
@@ -5695,7 +6143,10 @@ export function applyLinuxSandbox(
|
|
|
5695
6143
|
boundary === SANDBOX_BOUNDARIES.PROCESS_TREE,
|
|
5696
6144
|
);
|
|
5697
6145
|
|
|
5698
|
-
if (
|
|
6146
|
+
if (
|
|
6147
|
+
requiredBoundaries.includes(SANDBOX_BOUNDARIES.CODE_SNAPSHOT) &&
|
|
6148
|
+
!requiresStrongLinuxBoundary
|
|
6149
|
+
) {
|
|
5699
6150
|
return applyLinuxMcpCapsuleCodeSnapshot(
|
|
5700
6151
|
command,
|
|
5701
6152
|
args,
|
|
@@ -6357,17 +6808,36 @@ export function applyLinuxSandbox(
|
|
|
6357
6808
|
const supervisorBinding = supervisorPin.attestation;
|
|
6358
6809
|
closeLinuxPinnedMounts(runtime, [supervisorPin]);
|
|
6359
6810
|
supervisorPin = null;
|
|
6811
|
+
const capsuleContract =
|
|
6812
|
+
validation.contract.kind === MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND;
|
|
6813
|
+
const baseRuntimeProbe = linuxBubblewrapProbe(
|
|
6814
|
+
true,
|
|
6815
|
+
true,
|
|
6816
|
+
null,
|
|
6817
|
+
validation.entryRuntime,
|
|
6818
|
+
entrySnapshot?.attestation,
|
|
6819
|
+
supervisorBinding,
|
|
6820
|
+
pluginTreeSnapshot,
|
|
6821
|
+
nativeDynamicClosure,
|
|
6822
|
+
);
|
|
6360
6823
|
const runtimeProbe = Object.freeze(
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6824
|
+
capsuleContract
|
|
6825
|
+
? {
|
|
6826
|
+
...baseRuntimeProbe,
|
|
6827
|
+
mcpCapsuleCodeSnapshot: true,
|
|
6828
|
+
entrySnapshotAtomic: true,
|
|
6829
|
+
runtimeLaunchAtomic: true,
|
|
6830
|
+
runtimeLaunchMechanism:
|
|
6831
|
+
"bwrap-descriptor-mount-node-runtime-exec-v1",
|
|
6832
|
+
sharedLibraryClosure: false,
|
|
6833
|
+
runtimeSnapshotSha256: validation.contract.runtimeIdentity.sha256,
|
|
6834
|
+
runtimeSnapshotBytes: validation.contract.runtimeIdentity.bytes,
|
|
6835
|
+
entrySnapshotSha256: entrySnapshot.attestation.sha256,
|
|
6836
|
+
entrySnapshotBytes: entrySnapshot.attestation.bytes,
|
|
6837
|
+
runtimeLaunchPath: "/opt/chainless/runtime/node",
|
|
6838
|
+
entrySnapshotPath: sandboxEntry,
|
|
6839
|
+
}
|
|
6840
|
+
: baseRuntimeProbe,
|
|
6371
6841
|
);
|
|
6372
6842
|
const options = {
|
|
6373
6843
|
...spawnOpts,
|
|
@@ -6405,6 +6875,7 @@ export function applyLinuxSandbox(
|
|
|
6405
6875
|
SANDBOX_BOUNDARIES.FILESYSTEM,
|
|
6406
6876
|
SANDBOX_BOUNDARIES.NETWORK,
|
|
6407
6877
|
SANDBOX_BOUNDARIES.PROCESS_TREE,
|
|
6878
|
+
...(capsuleContract ? [SANDBOX_BOUNDARIES.CODE_SNAPSHOT] : []),
|
|
6408
6879
|
],
|
|
6409
6880
|
command: finalLaunch.command,
|
|
6410
6881
|
args: [...policyArgs, "--", ...targetArgs],
|
|
@@ -6480,9 +6951,10 @@ export function applySandbox(
|
|
|
6480
6951
|
args,
|
|
6481
6952
|
spawnOpts,
|
|
6482
6953
|
profileOrRequest = "default",
|
|
6483
|
-
runtimeOverrides =
|
|
6954
|
+
runtimeOverrides = undefined,
|
|
6484
6955
|
explicitRequest = null,
|
|
6485
6956
|
) {
|
|
6957
|
+
const runtimeInjected = runtimeOverrides !== undefined;
|
|
6486
6958
|
const runtime = resolveRuntime(runtimeOverrides);
|
|
6487
6959
|
const sandboxRequest = normalizeSandboxRequest(
|
|
6488
6960
|
profileOrRequest,
|
|
@@ -6546,6 +7018,7 @@ export function applySandbox(
|
|
|
6546
7018
|
spawnOpts,
|
|
6547
7019
|
profile,
|
|
6548
7020
|
runtimeOverrides,
|
|
7021
|
+
runtimeInjected ? null : WINDOWS_MCP_CODE_SNAPSHOT_ISSUER,
|
|
6549
7022
|
);
|
|
6550
7023
|
}
|
|
6551
7024
|
if (runtime.platform === "linux") {
|
|
Binary file
|
|
Binary file
|