General Text & Computing Company

Security & the App Sandbox

Security & the app sandbox

General Text runs apps you didn't write: from the gallery, from a URL, or your own. So the platform makes apps self-contained by construction: an app depends on nothing but your files and the runtime, and runs with no network access by default.

An installed app can read or write only the files in its own scope, and runs with no network access. It reaches no external server, so it can't phone home or pull in third-party code, and it can't touch the rest of your workspace.

This is first a durability promise: because an app calls no outside service, it keeps working offline and for as long as you keep the files, even if we disappear. It is a privacy promise too, an app with no network has nothing to leak. This holds for first-party apps as well; we hold ourselves to the same boundary, so "it's just an app" always means the same thing.

What an app can and cannot do

  • Can: read and write files in its own data folder, _gtApps/{app}/data/, its private storage, and live-sync them. This needs no permission.
  • Can, with your permission: read or write a folder (say notes/) or a file type (say .md) that you grant it. Grants are per workspace, can be read-only or read-write, and you manage or revoke them any time in Settings › Apps › Access.
  • Cannot: see or change anything else in your workspace, including its own install record and code, which sit next to data/ and are platform-managed.
  • Cannot: reach the network. No outbound requests, no analytics, no third-party scripts, no phoning home. Its data moves only through the brokered message channel below, never a network call.

How it's enforced

Four mechanisms, each independent, combine so the guarantee doesn't rest on any single check.

  1. Isolated origin. Every app runs on its own dedicated web origin, separate from the General Text shell, with its code served there over a short-lived, scope-limited token. The browser's same-origin policy keeps it walled off from your session and from other apps; your sign-in cookie is never sent to it.
  2. No network access. A Content-Security-Policy (connect-src 'self', plus form-action, object-src, and base-uri locks) blocks every standard way an app could reach the network: fetch, XHR, WebSocket, images, fonts, form posts, and navigation to another origin. An app's data reaches the platform only through the brokered message channel below, never a network call. Two lower-level browser channels (WebRTC and cross-origin navigation) sit outside what a Content-Security-Policy can cover; because no legitimate app uses them, the shell watches for them and terminates any app that reaches for one, and on the desktop app they are disabled at the engine level. You can watch the default in your browser's devtools: a blocked request to anywhere else is the boundary made visible.
  3. Brokered data, scope-checked. The app never connects to your files directly. Every read, write, and live-sync subscription is a message it passes to the General Text shell, which checks each one against the app's granted scope and drops anything outside it. The app holds no roaming credential of its own, so it cannot widen its own reach.
  4. Server-side enforcement. For synced workspaces the server independently re-checks scope on every file operation, so a bug or a lie on the client side still can't reach a file the app wasn't granted.

Synced data is end-to-end encrypted

The sandbox bounds what an app can see. A second, independent guarantee bounds what we can see: synced workspace content is end-to-end encrypted.

  • Encrypted on your device. File contents and file names are encrypted before they leave your machine (XChaCha20-Poly1305), and decrypted only on your devices and those of the people you invite. The server relays and stores ciphertext; it holds no key.
  • Keys stay with people, not servers. Each member has a personal keypair, protected by a passphrase and a recovery key. The workspace key is shared member-to-member as sealed, signed grants; granting or revoking access never routes a readable key through us.
  • You hold the recovery. Because we cannot read your data, we also cannot reset it. If you lose both your passphrase and your recovery key, your synced data is unrecoverable, by design. Keep the recovery key safe.
  • What the server still sees. Honesty matters here: the server necessarily knows your account email, who is in which workspace, and coarse facts like ciphertext sizes and when syncs happen. It cannot see what any file says or what any file is called.

Local-only workspaces never touch our servers at all; encryption applies to what you choose to sync.

The full picture (the key hierarchy, sharing, safety numbers, recovery, and the exact server-visible surface) is on the Encryption page.

What this means for you as a developer

You don't write any of this; it's automatic. Practically:

  • Keep your app's data under _gtApps/{your-app}/data/ (address it relative to your data folder) and it works with zero permissions.
  • To touch the user's own files, request a grant. The user approves the scope, and can revoke it later.
  • Bundle everything. Because apps have no network access, third-party CDN scripts, fonts, and analytics are blocked. Ship a self-contained build.
  • Your app's data is plain files the user owns, readable by them, their other tools, and their AI, for as long as they keep them.

See Building Apps for the full contract.