Context
Follow-up to #935 — that PR integrates the Snaps attenuated endowment factories for timers, Date, crypto, and Math, but explicitly scopes network out because it doesn't drop in cleanly against our existing platform-level fetch.
We currently expose fetch to vats via the @metamask/kernel-platforms layer (see packages/kernel-platforms/src/capabilities/fetch/), which enforces allowedHosts. Vats do not get Request, Headers, or Response classes in their compartment, so they can only use the return value of fetch() but can't construct Requests, preset Headers, etc.
Snaps' network factory provides more than we do:
fetch — wrapped with request/stream teardown on vat termination
Request, Headers, Response — hardened constructors available to vat code
teardownFunction — cancels in-flight requests and open body streams when a vat is stopped
- Lifecycle hooks via a
notify callback (JSON-RPC style)
What to do
Replace the platform-level fetch endowment with the Snaps network factory from @metamask/snaps-execution-environments/endowments, wired through the same factory/teardown pattern used in #935 for timers.
Open design questions:
- Host allowlist — the Snaps factory doesn't take an
allowedHosts option. Either:
- Pre-compose a caveated
fetch (reusing makeHostCaveat from shared.ts) and pass it into the Snaps factory via dependency injection, or
- Keep the caveat logic outside and chain the Snaps-wrapped
fetch through makeCaveatedFetch.
notify callback — Snaps uses it to emit OutboundRequest/OutboundResponse JSON-RPC notifications. Decide whether to bridge to @metamask/logger, route through the existing kernel RPC stream, or stub with a no-op.
- Platform layer fate — if all vat
fetch goes through the Snaps factory, most of packages/kernel-platforms/src/capabilities/fetch/ becomes redundant. Decide whether to delete it or keep the caveat utilities as host-restriction building blocks.
- Config shape — today vats opt into fetch via
platformConfig.fetch.allowedHosts. Decide if this moves to vatConfig.globals: ['fetch', 'Request', ...] with allowedHosts lifted to kernel-level config, or stays per-vat.
Integration
packages/ocap-kernel/src/vats/endowments.ts — add network factory to the createDefaultEndowments() bundle (guarded behind the allowlist)
packages/ocap-kernel/src/vats/VatSupervisor.ts — ensure the network teardown is picked up by the existing aggregate teardown
packages/kernel-test/src/endowments.test.ts + packages/kernel-test/src/vats/endowment-fetch.ts — migrate to the new endowment, verify allowedHosts, Request/Headers/Response availability, and teardown on vat termination
packages/kernel-platforms/src/capabilities/fetch/ — revise or remove per design decision above
Depends on
Context
Follow-up to #935 — that PR integrates the Snaps attenuated endowment factories for timers, Date, crypto, and Math, but explicitly scopes network out because it doesn't drop in cleanly against our existing platform-level
fetch.We currently expose
fetchto vats via the@metamask/kernel-platformslayer (seepackages/kernel-platforms/src/capabilities/fetch/), which enforcesallowedHosts. Vats do not getRequest,Headers, orResponseclasses in their compartment, so they can only use the return value offetch()but can't construct Requests, preset Headers, etc.Snaps' network factory provides more than we do:
fetch— wrapped with request/stream teardown on vat terminationRequest,Headers,Response— hardened constructors available to vat codeteardownFunction— cancels in-flight requests and open body streams when a vat is stoppednotifycallback (JSON-RPC style)What to do
Replace the platform-level
fetchendowment with the Snapsnetworkfactory from@metamask/snaps-execution-environments/endowments, wired through the same factory/teardown pattern used in #935 for timers.Open design questions:
allowedHostsoption. Either:fetch(reusingmakeHostCaveatfromshared.ts) and pass it into the Snaps factory via dependency injection, orfetchthroughmakeCaveatedFetch.notifycallback — Snaps uses it to emitOutboundRequest/OutboundResponseJSON-RPC notifications. Decide whether to bridge to@metamask/logger, route through the existing kernel RPC stream, or stub with a no-op.fetchgoes through the Snaps factory, most ofpackages/kernel-platforms/src/capabilities/fetch/becomes redundant. Decide whether to delete it or keep the caveat utilities as host-restriction building blocks.platformConfig.fetch.allowedHosts. Decide if this moves tovatConfig.globals: ['fetch', 'Request', ...]with allowedHosts lifted to kernel-level config, or stays per-vat.Integration
packages/ocap-kernel/src/vats/endowments.ts— add network factory to thecreateDefaultEndowments()bundle (guarded behind the allowlist)packages/ocap-kernel/src/vats/VatSupervisor.ts— ensure the network teardown is picked up by the existing aggregate teardownpackages/kernel-test/src/endowments.test.ts+packages/kernel-test/src/vats/endowment-fetch.ts— migrate to the new endowment, verifyallowedHosts, Request/Headers/Response availability, and teardown on vat terminationpackages/kernel-platforms/src/capabilities/fetch/— revise or remove per design decision aboveDepends on