Skip to content

Design: Home GUI as a sandboxed capsule with a Runtime-owned host #172

Open

Description

@andersalm

Part of #173 (isolation plan). Design first; Sasha reviews what users see and Irzhy reviews security.

Current source separates a trusted top-level host from the opaque Home GUI. The GUI still receives 12-hour app bearer fragments and mounts app frames; Runtime authority therefore still crosses the GUI boundary. The split below gives Runtime ownership of each app grant, frame lifecycle and approval request.

The design must deliver: a minimal Runtime-owned host (session, passkeys, window placement, approval surface); the Home GUI as a capsule in an opaque sandbox with only a delegation capability (launch, stop, broker); app capabilities minted by the Runtime directly into the frames it mounts, bound to the instance, short-lived, revocable, and ended by a real stop; every approval shown by the Runtime-owned surface with the passkey challenge bound to what is shown; Carrier peers (remote Homes, rooms, contacts, service offers) held to the same rules; provider-to-provider calls carry the originating principal's capability; and the role of the Runtime's local control listener after the split.

The note must also decide four things. First, the capability transport: a MessagePort that the host transfers into each frame at mount, with a capability that expires within minutes and is renewed only over that port. Bearer strings cannot be bound to a frame. The note defines the host broker that attaches authority to port requests, the instance, principal and session binding that #177 uses, and exactly what the receiver of a port can exercise. Second, whether the phone layout work (#92, PR #116) lands before or after the split. Third, which browser edges the host keeps (clipboard, wallet extension connectors, downloads, fullscreen), and which are hidden for 0.8.0. Fourth, that turning Discovery on or off becomes an approval, and that desktop file actions go through Library's brokered capability.

This design lands in 0.7.3; the work it designs is S2 (0.8.0).

Done means

  • A reviewed design note in this issue covers the host/GUI split, window management, capability minting, stop, approvals, Carrier peers, provider-to-provider calls carrying the originating principal's capability, the role of the Runtime's local control listener after the split, the phone layout work (Required: Home on phones #92, PR Home on a phone: Home screen pages, phone title bars and stage, sheets, 44 px targets (phone-only) #116) and its order relative to the split, the MessagePort capability transport (the broker, the instance, principal and session binding, and what a port's receiver can exercise), the browser edges the host keeps or hides for 0.8.0, Discovery on/off as an approval, and desktop file actions through Library's brokered capability.
  • The design note also decides that third-party executable capsules stay unavailable until a later issue proves publisher identity, exact-package approval, permission-change consent, no silent replacement and revocation.
  • Home: split into a Runtime-owned host and a sandboxed Home GUI capsule #176 to Hacked-Home regression suite in CI #180 link this note, each with its own Done means, including a regression suite where a hacked Home, a hacked app frame and a foreign origin each try every route and capability and fail.

Design proposal for Irzhy and Sasha: #172 (comment). Acceptance is pending; #176-#180 implementation starts only after their acceptance.

Activity

  1. added this to the 0.7.3 milestone on Oct 1, 2026
  2. andersalm commented on Oct 1, 2026

    @andersalm
    ContributorAuthor

    The implementation tasks for this design are filed: #176 Runtime-owned host and sandboxed Home GUI, #177 per-frame capabilities with real stop, #178 approval surface, #179 Carrier peers, #180 hacked-Home suite. The design note here should cover all five before they start.

  3. andersalm commented on Oct 2, 2026

    @andersalm
    ContributorAuthor
    1. Design proposal for Irzhy and Sasha, after Serve CID and user content in an opaque sandbox, never as Home #168 and Web terminal only in developer mode, off by default and in public mode #169 merged: Runtime owns session state, passkeys, window placement and approvals. Current source already has a trusted host and an opaque Home GUI; the remaining authority gap is that the GUI receives 12-hour app bearer fragments and mounts app frames. Under Home: split into a Runtime-owned host and a sandboxed Home GUI capsule #176, the admitted, hash-checked host package (Serve only hash-verified capsule assets #171) becomes the sole script-running document on its origin and enforces Trusted Types; the proposed budget is 1,000 unminified, nonblank, noncomment JavaScript lines across all its imported first-party modules, for Irzhy to accept. The host mounts every app and validates placement, Expose, switcher and phone-stage requests. Home receives instance IDs and one delegation channel for launch, stop and broker intents. Runtime owns launch grants for the approved package and permissions; Home receives each grant's outcome. First-party app smokes must pass with the host as their parent.
    2. Runtime places scoped, short-lived app capabilities into each frame, with real stop #177 uses a dedicated MessagePort transferred by the host directly into each mounted frame after a checked mount handshake. Runtime keeps the capability; the host broker validates operation-specific requests and attaches fixed package, instance, principal, session and grant authority. The port receiver can exercise only that instance's granted resources and operations, under its storage/request quotas. Proposed leases expire in five minutes and renew only through the live port after Runtime rechecks the session and grant; substituted bindings, HTTP replay, expired leases and revoked grants are refused. MessagePorts are transferable: a forwarded receiver retains the original instance's fixed scope, quotas and lifetime. Irzhy must accept this receiver policy or require stronger platform enforcement before acceptance. Stop, frame removal/navigation, session end and host channel retirement revoke the instance, cancel jobs and close ports; liveness failure also retires the channel. Runtime reconciles effects already dispatched, including payments, and records their outcome.
    3. Runtime-owned approval surface for every approval, with the passkey bound to what is shown #178 makes the top-level host render Inbox approvals for capability, service, room/contact, wallet, recovery, administrator and hosted-egress operations, including Discovery on/off. Inbox keeps history. The host alone displays the user's recognition phrase and an immutable request with actor, operation, target, effect, expiry and permission changes; the WebAuthn challenge binds its digest, nonce, expiry and operation. Changed requests, replay, expiry and cancellation are refused; denied/expired requests remain visible with zero partial grant. Fresh-machine Recovery Kit import registers a passkey in the host-only flow before accepting secrets. For 0.8.0, retain host-brokered, bounded clipboard actions and Library file selection, desktop file actions, download and export; retain host-controlled fullscreen, exiting it before approvals. Hide wallet extension connectors until an accepted broker flow proves identity, exact effect and refused cases. Sasha accepts the complete screens and recovery journeys; Irzhy accepts the request binding and approval-space protection.
    4. Carrier peers follow the same capability rules as local apps #179 gives signed Carrier peers owner-granted capabilities with the same scope, expiry, quotas and revocation as local instances. Before a grant, only signed, rate-limited Discovery/contact/invite knocks enter the host approval queue; enforce 64 KiB first-line limits, timeouts, per-peer stream limits and import quotas. Provider-to-provider calls carry and attenuate the originating principal's capability, with operation and replay checks at the receiver. Runtime-account tools own the private local control listener and scoped authentication; provider confinement excludes that listener, socket and attach secret. Capsules use Runtime Net/Exit; CID/site content uses a separate authority-free origin. The sole proposed direct-egress exception is the Browser engine edge adapter for its selected, approved media service. Gateway-only connect-src is insufficient proof: CSP specifies a separate WebRTC directive. Irzhy must accept the exact enforcement mechanism, including supported-target proof that hostile fetch/WebSocket/WebRTC attempts to localhost, LAN and external hosts fail while the approved Browser edge works; S2 acceptance waits for that proof.
    5. Land Required: Home on phones #92 through its existing draft PR Home on a phone: Home screen pages, phone title bars and stage, sheets, 44 px targets (phone-only) #116 after Home: split into a Runtime-owned host and a sandboxed Home GUI capsule #176/Runtime places scoped, short-lived app capabilities into each frame, with real stop #177, adapting its phone stage and switcher to host-owned placement; retain its dependency and independent server-review gates, run exact-candidate Chromium/WebKit desktop/phone smokes, then obtain Sasha's final phone check. Third-party executable capsules stay unavailable until a later issue proves publisher identity, approval of the exact package, permission-change consent, explicit replacement and revocation. Home: split into a Runtime-owned host and a sandboxed Home GUI capsule #176-Hacked-Home regression suite in CI #180 link this proposal and retain their own Done means; implementation waits for Irzhy and Sasha to accept the budget, port policy, expiry, browser edges, egress enforcement and phone order. Hacked-Home regression suite in CI #180 enumerates every gateway/Runtime route and capability at test time, uses operation-specific payloads, and pairs refused attacks with permitted controls for hacked Home, apps, CID/site pages, foreign origins, sibling ports, escaped/top-level documents, unauthenticated local processes, hostile rendered content/model output and Carrier peers. Assistant effects require scoped grants and exact-effect host approvals. Include guest-registration cases, two bounded Runtimes and complete process/port/data cleanup; add at most 15 minutes to CI, with exact-artifact manual UX/media and lifecycle proof for visible journeys.
  4. andersalm commented on Oct 2, 2026

    @andersalm
    ContributorAuthor

    Parked for #89; the five-part design proposal and linked #176-#180 acceptance criteria are preserved in GitHub.
    Done: host/GUI split, per-instance port authority, stop, approvals, Carrier/provider propagation, browser edges and phone order are proposed.
    Left: Irzhy and Sasha acceptance, exact egress enforcement, and the #209/#210 boundary separating S2 capabilities from protection against the host operator.
    Resume only when Anders reopens the design: reconcile the saved proposal with the current threat model, settle those decisions here, then obtain both acceptances before #176-#180 implementation.
    The release session continues only #89's install/update producer work; this design stays open.

  5. modified the milestones: 0.7.3, 0.8.0 on Oct 7, 2026
  6. andersalm commented on Oct 10, 2026

    @andersalm
    ContributorAuthor

    North star review (10 Oct), additions for this design: any capsule that draws pixels can draw a fake approval, so approvals need a region no capsule can overlay, and the passkey signs what is shown (#178).
    Agents and shells only propose; Runtime minimum policy decides, and an agent never approves its own request. WASM components share the Runtime process with its keys, so third-party executable capsules also need key-free confined workers (#285).

  7. andersalm commented on Oct 13, 2026

    @andersalm
    ContributorAuthor

    Postponed to 0.8.1: isolation S1/S2 is not a 0.8.0 blocker (Anders, 12 Oct); #170 states the real isolation.

  8. modified the milestones: 0.8.0, After 0.8.0 on Oct 13, 2026
  9. andersalm commented on Oct 17, 2026

    @andersalm
    ContributorAuthor

    Anders, 16 Oct, clarified the abstraction: this is starting/activating a capsule with parameters, not granting permission to open a window. A requesting capsule proposes an admitted target capsule/resource and validated parameters. Runtime resolves identity/package, binds the exact recipient, operation and data transfer to the requesting principal/session/launch, and enforces a narrow capability; Home displays the result according to target/platform policy. A desktop window, existing view or phone screen is presentation, not the authorization unit. The bounded initial consent is Allow once / Deny through an immutable Runtime request rendered by trusted top-level Home as an Inbox approval, showing requester, target, parameters/data disclosure, requested authority and expiry. Runtime holds a short-lived nondelegatable single-use token and consumes it atomically. The recipient gets independently authorized capabilities: launch permission neither inherits the caller permissions nor grants recipient file/network access. The caller receives an outcome/opaque handle, not recipient credentials. Changed target/parameters, wrong caller, replay, denial, expiry, cancellation, revoke or epoch must cause no launch. Caller retirement/navigation or logout cancels pending requests; restart invalidates requests or preserves consumption durably. External web/OS navigation is a separate explicit export effect, not implicit capsule-launch authority. Direct app popups remain blocked; no standing/session grants until lifecycle revocation is enforced. Current launch code already separates target resolution from window_policy/attach_kind, but its free-form query is not claimed to provide the proposed typed-parameter contract. Implementation, review and installed proof remain pending. This does not complete or accept the deferred #176/#177 MessagePort/host split; Sasha and Irzhy retain the broader S2 UX/security acceptance gates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions