ADR-0026: Require explicit execution isolation profiles
- Status: Accepted
- Date: 2026-09-13
- RFC: RFC-0001
Context
ADR-0017 permits a fixed node-defined set of trust-class execution hosts for stronger containment, but does not define when such a host is required. Phase 3 adds externally supplied capsules, capability providers and application renderers while the delivered runtime still uses fresh Wasmtime stores in fixed in-process cells. Phase 2 also delivered an optional Linux x86_64 isolated AOT compiler and authenticated same-node native reuse. Those boundaries solve different problems and must not be represented as interchangeable security guarantees.
Decision
LSF security-sensitive execution uses explicit, versioned isolation profiles with exact threat assumptions, trusted components, platform prerequisites and finite acceptance evidence.
Profile compatibility fails closed. A requested profile that is unknown, unavailable or only partially enforceable must be rejected. Admission, preparation, provider selection or renderer selection may not silently downgrade to a weaker profile, in-process compilation, unauthenticated native loading or an unsupported host.
The baseline matrix is defined by RFC-0001:
local-experimental-v1is the delivered T0 profile for operator-trusted/local workloads. Fresh Wasmtime stores provide the documented guest execution barrier under the node/engine/OS trusted computing base, but trusted-local admission and in-process compilation do not establish the end-to-end T1 external-capsule profile.isolated-aot-compiler-v1is the delivered bounded Linux x86_64 compiler-child boundary. It isolates compiler work only.authenticated-native-aot-v1is the delivered same-node authenticated native reuse/loading path. The native loader and node remain trusted; arbitrary external native artifacts are unsupported.external-capsule-v1requires enforced package admission, exact ABI/profile compatibility, protected trust configuration, the reviewed runtime baseline and supported isolated compilation before it can be selected. Phase 3 #280 implements these requirements as documented in the execution-profile reference.- in-process providers and the closed Angular Component Model renderer are implemented under their documented trusted computing base. Their capability or renderer identity does not add process-compromise containment.
- work that requires containment after compromise of the process executing the guest/provider/renderer/native compatibility layer requires
fixed-execution-host-v1, a separate node-owned fixed/bounded host pool. That profile is unsupported until implemented and tested. - host/kernel compromise and strong same-machine side-channel isolation remain outside the current standalone security boundary.
A package signature, compiler sandbox, guest Store limiter, profile label or cache entry is not proof that another boundary is present.
Implementation status: #280 delivers the securityProfile node selector for
local-experimental-v1 and external-capsule-v1, bounded compiler readiness in
startup/check-config and a persisted restart requirement. The compiler/native
subprofiles remain separately observable mechanisms. The
provider broker and
Angular runtime document the
installed in-process boundaries. The fixed execution-host profile remains
unavailable.
This status update does not change the accepted threat-class taxonomy.
Ownership of follow-up implementation
This ADR assigns enforcement rather than expanding the current runtime:
- #202 and #204 bind exact requested host/provider compatibility;
- #224 selects and validates renderer compatibility;
- #280 implements deployment/startup enforcement for the external-capsule profile;
- #238 retains integrated adversarial evidence;
- provider-specific tickets own provider bounds and failure behavior.
A new external execution backend is not required to complete this decision. If one is later implemented, its process count must remain fixed or node-configured bounded independently of service count. The supervisor may create, stop, kill, quarantine, reap and replace only those node-owned hosts. A failed host remains charged until termination and reap are observed and is never returned to the reusable pool.
A separate PID alone does not establish T2. OS and IPC restrictions must prevent a compromised host from accessing supervisor memory, trust/signing keys and unrelated resources. CPU, memory, descriptors, IPC buffers and descendant work require independent hard boundaries. Untrusted executable/provider/native work stays in the execution host; the supervisor accepts bounded authenticated messages rather than executing worker-supplied native code or callbacks.
Interruption and accounting
In-process activations retain current cancellation, deadline, fuel/epoch and affirmative cleanup semantics. A failure that cannot safely stop or clean an in-process guest cannot be promoted to a process-containment claim; the affected cell must not be reused and node-level recovery may be required.
The isolated compiler retains child ownership and reservations through cancellation, kill and actual reap. Native deserialize remains a trusted synchronous node operation. Installed providers and renderers retain their actual cleanup owners. Any future fixed-host profile must define bounded ownership, quarantine, shutdown and crash recovery before support.
Guest store limits are not whole-process RSS limits. Runtime/embedder allocations, native code, allocator retention, provider state, caches and IPC have separate ownership and accounting domains.
Resource invariant
The decision preserves:
resident resources = fixed node runtime + active activations + bounded shared caches and provider pools
Dormant deployments do not own processes, threads, listeners, sockets, provider instances, renderers, runtime instances or execution cells. Stronger containment may add fixed/bounded node-owned infrastructure, never one persistent host per service.
Consequences
- Security-profile names become compatibility requirements, not informal descriptions.
- Stronger claims require profile-specific evidence before they are documented as supported.
- Supported current contracts retain their documented guarantees. Obsolete alpha compatibility is removed under ADR-0044.
- Phase 3 can proceed under the documented in-process trust model without pretending that compiler isolation provides guest-process isolation.
- Hostile-multitenant/native-compatibility workloads that require process-compromise resistance remain unsupported until a fixed execution-host backend exists and passes its evidence matrix.