The skynet browser (wasm-visor iframe browser)¶
The wasm-visor ships an in-tab skynet browser — a WinBox window whose address
bar accepts a visor PK, pk.dmsg, an alias.dmsg (e.g.
home.dmsg), or an https:// clearnet URL. Pages are fetched over dmsg
(skynet) — no DNS, no certificate authorities, IP-anonymous — or, for clearnet,
sent through the proxy named in the ⚙ field — one [scheme://]host:port (empty: the visor's default egress).
Nav bar: ◀ ▶ ⟳ ⌂ (back / forward / reload / home → home.dmsg), the
address bar + go, ⚙ (the proxy address + per-window request log), and ⓘ
(this page's summary, in-UI).
Limitations (by design)¶
Every fetched page is rendered into an iframe declared
sandbox="allow-scripts allow-forms" — deliberately without
allow-same-origin. The browser then forces each document into a unique
opaque origin, which is the source of the properties below.
- No persistent storage. Opaque origins cannot use Web Storage, cookies, IndexedDB, or the Cache API — access throws. So cookies / localStorage / logins do not persist, not even across a reload; each visit is effectively a fresh, incognito, storage-less context.
- Isolation. Sites cannot read each other's data, and — critically — cannot
read the visor's own storage. The visor's secret key lives in the parent
page's
localStorage(skywire-visor-sk); the opaque-origin sandbox walls browsed sites off from it. This isolation is the whole reason for the sandbox. - Restricted scripting.
allow-scripts allow-formsonly: no plugins, no popups, no top-level navigation, noallow-same-origin. Some clearnet sites that depend on cookies or service workers will misbehave. - Direct-load path is sandboxed too. For "direct" clearnet sites the engine
sets
frame.src = urlbut leaves thesandboxattribute on the element, so even a directly-loaded real site runs opaque-origin and cannot use its cookies.
These are a privacy tradeoff, not bugs: no cross-site or site→visor leakage, and no persistent tracking state.
Why the wasm visor can't give per-site persistence¶
Browser storage is partitioned by origin (scheme://host:port). To give each
site its own durable, isolated storage bucket, each site must be a distinct
origin. A browser tab cannot mint new origins for content it fetches itself, and
a Service Worker is scoped to its page's single origin (path separation does not
isolate storage). So in the keyless in-tab wasm visor there is no way to give
browsed sites real per-origin storage without either (a) wildcard-subdomain
serving infrastructure with a per-subdomain dmsg fetch relay, or (b) an embedded
dmsg client per site — both heavy, and (a) reintroduces domain/DNS dependence the
keyless model avoids.
The native path (future): one local proxy origin per site¶
On the native desktop browser (a real process, e.g. the WebKitGTK sibling) per-site persistence is achievable, two ways:
- Wildcard-host loopback reverse proxy. Serve
http://<sitekey>.skynet.localhost:PORT/where<sitekey>is a stable 1:1 encoding of the dmsg target (e.g.PubKey.DNSLabel()base32). Decode the host → dmsg target, fetch over the existing resolving-proxy path, serve it back under that host.*.localhostneeds no DNS and is a secure context in Chromium, so each site gets its own persistent, isolated cookies / localStorage / IndexedDB / service worker — isolated from other sites and from the visor UI origin. In-page links are rewritten to keep same-site navigations on the same synthetic host (cross-site → another<sitekey>.skynet.localhost, clearnet → a clearnet-proxy origin). With isolation coming from the origin, the sandbox can be dropped. - Point the whole webview at the resolving SOCKS5 proxy. With
socks5h://127.0.0.1:<port>resolving<pk>.dmsg, the browser engine treats<pk>.dmsgas the origin and partitions storage per-pk for free — no reverse proxy, no rewriting. Browsers just don't allow a per-iframe SOCKS proxy, which is why the wildcard-localhost reverse proxy is the fallback for the embedded case.
Recommended pairing: an ephemeral / incognito toggle that clears a site's bucket on close, and keeping the visor UI origin strictly out of the proxy's host namespace so a proxied site can never navigate to it or read its storage.