Skip to content

fix(gateway): let apps open inside the sandboxed home shell - #202

Merged
andersalm merged 2 commits into
developfrom
fix/167-app-frame-ancestors
Oct 2, 2026
Merged

andersalm merged 2 commits into
developfrom
fix/167-app-frame-ancestors

Conversation

@SashaMIT

@SashaMIT SashaMIT commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the app-frame regression from #197 reported in #167. With this change, Marketplace, Assistant and every other app open inside the installed Home again. Base develop.

Cause

App documents carried frame-ancestors <Home origin>. The Home GUI shell that mounts them is an opaque sandboxed document, and frame-ancestors checks every ancestor against the source list. An opaque origin serializes as null, so the browser refused every app frame with ERR_BLOCKED_BY_RESPONSE.

Change

shell_content_security_policy applies option (1) from the #167 analysis:

  • The Home host keeps frame-ancestors 'none'.
  • The shell capsules (home-gui, home-cli) keep frame-ancestors <Home origin>, because the Home host is their direct parent.
  • App and viewer documents rely on the response sandbox until the Runtime-owned host mounts app frames directly (Home: split into a Runtime-owned host and a sandboxed Home GUI capsule #176). All other directives stay the same.

Home keeps its cookie, launch token and API authority. A foreign page that frames an app receives an opaque sandboxed document that holds only what the page itself supplies.

Tests

  • content_sandbox_browser opens Home, then the sandboxed shell (/apps/home-gui/, origin null), then Assistant and Marketplace, all from real gateway responses. Both apps load, and Home's cookie and storage stay with Home. The test fails against develop's server code, where Assistant stays blocked inside the shell.
  • In the same signed-in browser context, a hostile.example page frames Assistant. The browser sends that request without the Home cookie, Home's cookie and storage stay with Home, and the gateway answers unsigned API requests with 403.
  • The app-document unit test checks the sandbox, an opaque origin and the absence of frame-ancestors. The shell test still checks frame-ancestors <Home origin>.

Local results on a Mac: both browser tests, cargo fmt, clippy -D warnings and the source-gate steps pass. 2272 elastos-server lib tests pass; 8 custody and media tests depend on the local environment and fail the same way on develop.

Claude wrote this change, so the independent review comes from a different model family. Irzhy owns the isolation design.

Refs #167

Made with Cursor

Current integration candidate: 0146b8ae315f4ac94a84b77628ffe3ab8688e6a9, tree a7f65054bbd6a744f1894657e02397f017ad7f74, after a normal merge of develop 0bc1c277. The feature files are unchanged, and approved #216 is integrated. Anders authorized this session to finish the branch and mark ready. Basic gates and current Codex source review pass. Current CI and installed signed-in Home Marketplace/Assistant journey are active; every gate applies to this exact candidate.

App documents carried frame-ancestors <Home origin>, but the Home GUI
shell that mounts them is an opaque sandboxed document. frame-ancestors
checks every ancestor and an opaque origin never matches, so every app
frame in the installed Home was blocked (ERR_BLOCKED_BY_RESPONSE).

Keep frame-ancestors 'none' on the Home host and <Home origin> on shell
capsules; drop it from app and viewer documents until the Runtime-owned
host mounts app frames directly (#176). A foreign page that frames an
app gets an opaque sandboxed document with no Home cookie, launch token
or API authority.

The browser regression now opens Assistant and Marketplace through the
real gateway Home -> shell -> app chain (fails on develop), and checks
that a foreign frame carries no cookie and gets no API authority.

Refs #167

Co-authored-by: Cursor <cursoragent@cursor.com>
@andersalm

Copy link
Copy Markdown
Contributor

Review by the operator (Claude Opus, 2 October 08:35 UTC). This is the same model family as this PR's author, so it is not the independent different-family review the rule needs; a Codex review of this head is still required before merge.
Result: no blocking finding. The Home host keeps frame-ancestors 'none', shell capsules keep frame-ancestors , and only app, viewer and other non-shell documents lose it; their sandbox CSP is unchanged without allow-same-origin; cookies stay SameSite=Strict and the launch token stays in the fragment; tests cover apps inside the opaque shell and a foreign framer (no cookie, no storage, 403).
Non-blocking: decide the shell role with is_trusted_home_shell_id rather than the manifest's self-declared role (browser_capsules.rs:343); the browser test uses a fixture shell, so prove the real signed-in Home launch with #153's installed journey. The red source-home-linux (ubuntu-24.04) job is a Kubo download timeout, not this change.

@SashaMIT

SashaMIT commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Tested in a real signed-in Home on macOS, built from this PR's head 3bceced34 with setup-source-home.sh and mac-source-home-restart.sh --init, collaboration mode isolated.

  • Marketplace and Assistant both open inside the Home GUI shell after Touch ID sign-in.
  • Served headers match the change: /home/ has frame-ancestors 'none'; /apps/home-gui/ has sandbox and frame-ancestors http://localhost:61190; /apps/marketplace/ and /apps/assistant/ have sandbox and no frame-ancestors.
  • Unrelated to this PR: model download stops at the metadata read (model_index_read availability fallback fails; isolated mode has no Carrier peers while the public seed is paused). Browser needs the browser-vm-image component, which a source install doesn't include.

CI: all checks pass except source-home-linux (ubuntu-24.04), which fails twice at local-carrier setup smoke because the Kubo download from dist.ipfs.tech times out. The site is unreachable from here too; only the macOS job caches Kubo. I'll re-run it when the site is back.

@andersalm

Copy link
Copy Markdown
Contributor

Independent adversarial review (Codex, gpt-6.1-sol; different model family from the Claude author), requested by Anders on 2 October, head 3bceced34ddb0b79139becc3e933745556349b55.
VERDICT: PASS for the source change; the installed #153 journey remains a separate merge gate.
Home keeps frame-ancestors none, shells retain the Home ancestor restriction, and app/viewer HTML, XHTML, SVG and SVG 304 responses keep the opaque sandbox without allow-same-origin; removing the app ancestor list restores the nested shell/app chain.
Capsule responses serve packaged bytes; private APIs still require signed launch authority, Home cookie authority requires exact-origin provenance, and opaque CORS responses grant no credentialed access. Registered window-source checks still protect Home messages; the foreign-framer test supplies a stronger local-network attacker and proves the refused API/cookie/storage cases.
Exact diff and browser-script syntax checks pass. Non-blocking coverage and shell-classification notes are recorded in #167; merge waits for Sasha's ready state, all green checks, and the exact-head installed Marketplace/Assistant journey.

@andersalm

Copy link
Copy Markdown
Contributor

Installed #153 Home proof has started for exact head 3bceced34ddb0b79139becc3e933745556349b55: Mac run 36998746112.
The workflow builds the clean candidate before adding pinned existing test files (cd00623c core harness and aa9a2bda eight-token request); receipts compare built and installed Runtime/provider hashes.
The requested Linux rerun, attempt 3, failed again on the pinned Kubo archive connection timeout inside local-carrier's separate Home; source-home setup passed because Linux auto mode skips Kubo.
The failing workflow/setup paths are unchanged by #202. The bounded CI repair is to use existing seed-kubo-cache.sh and seed the fixture root selected with ELASTOS_LOCAL_TEST_ROOT; keep its setup checks enabled.
The Codex source PASS remains current. Merge waits for Sasha's ready state, all green checks and this exact-head installed proof; #167 closes only after the same journey passes on merged develop.

@andersalm

Copy link
Copy Markdown
Contributor

The installed proof 36998746112 stopped before build after six Kubo connection timeouts; its dispatch branch cannot read the develop/PR caches under GitHub's cache scopes.
The official Darwin archive and Linux archive checksum sidecars match the exact candidate's pinned SHA-512 values.
Own workflow-only commit 6155e69b2c9770dbbd6bcb6daaab5a627dc63d20 downloads that immutable Mac input, then calls the unchanged candidate verifier; a tampered-cache refused case runs in the same CI job.
The repaired exact-head installed journey is 37002735025, still testing 3bceced34ddb0b79139becc3e933745556349b55; all four local basic gates, workflow syntax and the real verifier's tampered-input refusal pass.
For the remaining Linux check, the same official GitHub archive plus the existing verifier can seed local-carrier's explicit fixture root. Sasha retains #202's branch and ready state; source PASS stays current, with green CI and installed acceptance pending.

@andersalm

Copy link
Copy Markdown
Contributor

Exact head 3bceced34ddb0b79139becc3e933745556349b55 passes the installed #153 core Home journey in 37002735025; source tree 05c89ed8489234e4ba9f0b0ffababb5f9ada1446 was clean before build.
A fresh isolated Home completes passkey sign-in, opens Marketplace through the Home GUI controls, admits the pinned model package, then opens Assistant and receives a real six-character reply with the eight-token request; the recorded journey takes 103.81 seconds.
Built/installed Runtime SHA-256 both equal c30c4cb91ec443d749e2ce4519035b89c22cf5ca861aad984835bc7337814abe; built/installed model-provider SHA-256 both equal 4a913f0b27329bd76a4af696a6680baba82395a43262eb91801a3f3898c79d01. Receipts bind the installation and component manifest.
Pinned harness provenance (cd00623c core, aa9a2bda bounded request), desktop/phone screenshots and cleanup receipts were inspected; the remaining owned helper stopped and the final process list is empty. This proves the requested installed launch gate, separate from #153's three-Mac timing acceptance and manual UX.
The Codex source PASS is current. Sasha's ready state and the remaining Linux CI Kubo repair still gate merge; after merge I will run the same journey on the exact develop merge SHA before closing #167.

@andersalm
andersalm marked this pull request as ready for review October 2, 2026 18:36
@andersalm

andersalm commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Finished under Anders’s authorization: PR202 merged after green CI, Codex adversarial PASS and the exact-head installed Home journey.
#167 is closed with installed receipts after the exact merged-develop journey also passed; Marketplace and Assistant opened, binary/provider parity matched and owned-process cleanup ended empty.
Your source branch remains preserved under your retirement decision. This session’s clean completed checkout and reproducible screenshot copies are cleaned under their recorded lifecycle conditions; #201 now uses the accepted frame baseline.

@andersalm

Copy link
Copy Markdown
Contributor

Independent adversarial review (Codex), exact head 0146b8a / tree a7f65054bbd6a744f1894657e02397f017ad7f74.
VERDICT: PASS. No blocking source finding in the app-frame correction.
Reviewed the three-file feature delta against develop 0bc1c27 and compatibility with its approved security baseline; those files are byte-identical to the previously reviewed 3bceced candidate. Home keeps its authority and frame restriction, shells keep the Home ancestor restriction, and app documents retain the opaque response sandbox on normal and cached responses.
The actual-browser fixtures cover nested Marketplace/Assistant loading and a foreign frame receiving neither Home cookie/storage access nor API authority. Existing shell-classification and broader foreign-frame coverage notes remain non-blocking in #167.
Local basic gates pass. Current CI37048331449 and installed proof37048532582 still gate merge; this source review leaves exact installed Marketplace/Assistant acceptance to the recorded journey and receipts.

@andersalm

Copy link
Copy Markdown
Contributor

Exact candidate0146b8ae315f4ac94a84b77628ffe3ab8688e6a9 / tree a7f65054bbd6a744f1894657e02397f017ad7f74 passes all checks in CI37048331449 and the installed Home journey37048532582; current Codex adversarial PASS remains exact-head.
Inspected artifact11246717487 binds clean source, pinned harness hashes and installed/build Runtime SHA-256 e0a959e1950752016c35a1c6795a7cbdd92f4fce357392c20c5ce3900aa74c3e; model-provider parity is 4a913f0b27329bd76a4af696a6680baba82395a43262eb91801a3f3898c79d01.
A fresh isolated passkey-authenticated Home opens Marketplace and Assistant through the real GUI controls; app-frame requests admit the pinned model and return a real six-character, eight-token-bounded reply. All three core checks pass in103.82 seconds.
Desktop/phone Home screenshots and public receipts are inspected; the remaining fixture-owned process stops, forced-stop and final process lists are empty. This is automated launch/Runtime acceptance; full interaction/manual UX and #153 timing remain separate.
Anders’s authorization permits normal develop merge now. #167 will stay open until this journey also passes on the exact merged develop commit.

@andersalm
andersalm merged commit 1327347 into develop Oct 2, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants