GA Release

The Multi-Agent WebGPU Engine & Interactions API are now generally available.

Part 22: Security, Privacy & the Local-First Data Model

Exactly where your prompts, keys, chats, and files live; how sandboxes, CSP, and the server proxy protect you; and what (if anything) ever leaves your machine.

Category: Reference • Read Time: 23 min read • Updated: August 2026

1. The One-Paragraph Summary

Your conversations, files, memories, skills, and settings are stored in your browser — in IndexedDB and local/session storage. The app does not keep a server-side chat database. Depending on the feature and provider you select, requests and assets can still leave the device:

  • Prompts, selected context, and provider authorization headers go to the model service you choose. For some remote providers, the request first passes through the Accelerated Logic server proxy, which forwards it to that provider; a local endpoint may be contacted directly.
  • Optional backups you enable go to Google Drive. If you connect Drive, Google returns the account email, which the app stores locally to identify the connected account.
  • Browser-local model runtimes and model weights may be downloaded from their configured CDN or model host before inference. Other static assets can also load from third-party CDNs.

2. Where Each Kind of Data Lives

DataStored whereLeaves device?
Chats, messagesIndexedDB chats storeOnly to providers as prompts / optional Drive backup
Ingested filesIndexedDB files storeOnly when attached to a prompt
Memories, skills, agentsIndexedDB storesRelevant memories and enabled skills may be included in prompts to the selected model; optional backup may send data to Drive
SettingsIndexedDB + localStorage mirrorsSecrets stripped before any Drive sync
API keys / PATsCredential store (session + local)Sent in provider authorization headers; remote requests may transit the app proxy. Encrypted Drive vault is optional.
Google Drive token and account emailToken in sessionStorage; connected email in localStorageUsed for Google Drive authentication and to label the connected account; not added to model prompts by this integration

Storage operations are resilient: if localStorage is unavailable (private/sandboxed contexts), writes fall back to an in-memory store so the app keeps working for that session.

3. How Credentials Are Protected

  • One credential chokepoint. All API keys and tokens are read and written through a single SecretStore helper rather than scattered raw localStorage calls, so there is one place to audit and harden.
  • Drive backups are account-protected and encrypted. The normal settings document still strips every API key. When Drive sync is enabled, a separate AES-GCM credential vault backs up provider keys and fallback keys as ciphertext; its key record is stored only in Google Drive AppData, which is gated by the signed-in Google account and never appears in the readable settings document. This lets the same Drive account restore keys on another device. Restores only fill blank local credential slots, so an older cloud copy cannot replace a newer local key.
  • Local export is redacted by default. The "export database snapshot" action omits secrets unless you explicitly include them; MCP server headers/keys are also stripped.
  • Full logout works. Disconnecting GitHub purges the access token from every storage tier and the OAuth refresh token and its expiry; it is not left behind.
  • Masked inputs. All key/token fields use type="password".

Honest limitation: anything in browser storage is reachable by any script executing on the page origin. The real defense against that is strict input sanitization and CSP (below) — there is no evals, no raw HTML rendering of chat, and untrusted code is confined to sandboxed frames. Treat a browser session as you would any logged-in app, and use the clear/revoke controls on shared machines.

4. Sandboxes: Untrusted Code Cannot Touch Your Data

Code generated by agents or pasted by you is never run in the main page:

  • Web Sandbox / Code Preview run user code inside <iframe sandbox="allow-scripts"> frames — note there is deliberately no allow-same-origin, so the frame cannot access the parent's storage, cookies, or DOM.
  • Python runs in Pyodide inside a Web Worker; local LLMs run in Web Workers. Workers have no DOM access and are terminated/revoked when torn down.
  • Bridge messages are validated. The parent only accepts messages whose event.source is the exact sandbox frame (and same origin for tool bridges), console payloads are capped in length and count, and any injected HTML in docs runs through DOMPurify with forced iframe sandboxing.

5. Transport & Server Protections

  • Content Security Policy restricts scripts to the app origin plus a small set of named hosts, allows WebAssembly via wasm-unsafe-eval (not blanket unsafe-eval), and limits who can embed the app via frame-ancestors.
  • SSRF-hardened proxy. Browser requests are relayed by a small Express server that only forwards to an allowlist of known AI/search domains, blocks private (10/8, 172.16/12, 192.168/16) and link-local (169.254/16) addresses, pins connections to validated IPs to prevent DNS rebinding, and re-checks every redirect target.
  • Security headers: HSTS, X-Content-Type-Options: nosniff, X-Frame-Options, a restrictive Referrer-Policy and Permissions-Policy.
  • OAuth is origin-scoped. GitHub login uses short-lived, cryptographically random session ids/secrets with timing-safe comparison, exact-origin relay checks, 15-minute expiry, and no tokens held server-side. The GitHub client secret is read from environment variables, never the repo.
  • Rate limiting is applied to API, auth, proxy, and prompt-enhancement routes; request bodies are capped.

6. Browser-local model inference

With a supported WebLLM, Transformers.js, or Chrome built-in model selected and loaded, inference is performed on the device. Runtime code and model weights may be fetched from a CDN or model host during setup; browser caches can be cleared or evicted. This describes the model inference path, not all network traffic from the website or other connected features.

7. Clearing & Exporting Your Data

Export: Settings → Backup lets you download a full JSON snapshot (secrets optional) or per-slice exports (models, chats, skills, memories).

Clear: "Clear all data" wipes the IndexedDB stores and app-owned local/session keys while deliberately keeping non-content preferences like your theme and EULA acceptance (it does not blindly localStorage.clear() unrelated keys).

Quota handling: if browser storage fills up, the app first evicts regenerable caches and (as a last resort) strips large base64 images from the oldest chats, then retries — your conversation text is preserved.