General Text & Computing Company

Encryption

Synced workspaces in General Text are end-to-end encrypted. Your files are encrypted on your device before they travel, and decrypted only on your devices and the devices of people you share with. Our servers relay and store ciphertext; they hold no key that can open it. This page explains how that works and, just as importantly, where its edges are.

Sync is a property of the account: subscribe one and every workspace it owns syncs (and is encrypted); leave it unsubscribed and every workspace it owns stays on your device, never touching our servers, living as plain files on your disk that you and any tool can read. If you want something to stay local even while you pay for sync elsewhere, put it in its own account — see Accounts and workspaces.

What is (and isn't) encrypted

Encrypted end to end:

  • File contents. Every edit travels and is stored as ciphertext.
  • File names and folder structure. Files sync under opaque random ids, and the name-to-file map is itself an encrypted document. The server never sees what anything is called.
  • Binary files. Images, PDFs, and other attachments are encrypted on your device before upload.
  • Live cursors. In-file cursors and who's-typing signals are encrypted in transit and never stored.
  • App data. The files and documents your apps read and write are your content, so they are encrypted like anything else in the workspace. (The apps' code is not; see below.)

Not encrypted (and we're explicit about it):

  • Account and membership data. Your email, account and workspace names, and who belongs to what. The server needs these to route and bill.
  • Traffic shape. Ciphertext sizes, how many files exist, and when syncs happen.
  • Who's online. Workspace-level presence — display names, colors, and an opaque marker for which file each person has open — passes through the relay unencrypted and is never stored. The marker is a random id, so the server still can't tell what any file is called.
  • App code. We host and serve every app's code for the purposes of installing it in workspaces, which means it is not hidden from us, whether the app is public in the gallery or private to your account ("private" means only your account can install it, not that we can't see it). Once installed it runs entirely from an encrypted copy in your workspace, so we can't see when or how often you use it. We host the code only for installation. As always, the data those apps read and write is your content, and stays encrypted (above).

In short: the server can see that your workspace has 40 files totalling some megabytes and that you edited this morning. It cannot see what any file says or what any file is called.

The keys

Everything hangs off one identity per account, protected in layers:

  1. Your identity keypair. Created on your device when you set up encryption: one key for receiving encrypted material (X25519) and one for signing your changes (Ed25519). The public halves are published; the private halves never leave your devices unencrypted.
  2. Your encryption passphrase. Your private keys are encrypted under a key derived from a passphrase you choose (Argon2id, derived on your device). The server stores only the resulting wrapped blob. Entering the passphrase on a new device is how your identity travels; the passphrase itself is never sent anywhere. It is separate from your login password on purpose: login proves who you are to us, the passphrase unlocks what we cannot read.
  3. Your recovery key. Shown once at setup: a second, independent wrapping of the same identity. If you forget your passphrase, the recovery key restores access and lets you set a new one. Store it somewhere safe (a password manager, a printed copy).
  4. The account key. Each account has one key, delivered to each member as a grant: sealed to that member's public key and signed by the member who granted it. The server stores grants as opaque blobs it cannot open. Holding the account key is what makes you an insider: one grant, and every workspace the account lets you open, opens.
  5. Workspace keys. Every synced workspace has its own content key (XChaCha20-Poly1305) that actually encrypts its files. For members it travels wrapped under the account key, so joining an account never means a pile of per-workspace handshakes. For guests (people invited to a single workspace) it is sealed and signed to them individually: a guest never holds the account key, so the only thing they can ever decrypt is the workspace they were invited to.
  6. The device cache. After you unlock once, your identity is kept on the device under a non-extractable browser key so you aren't retyping the passphrase constantly. You control how quickly it re-locks after inactivity (Settings › Security), from minutes to never.

How sharing works

How a new member gets the account key depends on whether they already use General Text. If they do, then the moment you invite them your own device wraps the account key to their published public key and stores the sealed grant, so they have access the instant they accept, with nothing else to do. If they're new to General Text, they first accept the invitation, sign in, and choose an encryption passphrase (which publishes their public key); an admin then grants them the key. We email the account's admins the moment a member is waiting, so nobody has to keep checking. Either way the wrap happens on an admin's own device, never on our servers, and the two of you never need to be online at the same time: the sealed grant waits on the server until the new member's device picks it up.

The receiving device verifies the grant's signature against the member roster before accepting the key, and pins the key's fingerprint so that a later substitution trips an alarm instead of silently re-keying the device. The server only moves the sealed grant; it can neither read it nor forge one.

Inviting a guest to a single workspace works the same way at a smaller radius: when a workspace admin next opens the workspace, their device seals that workspace's key to the guest's published identity and signs it. The guest gets exactly one workspace; removing them deletes their grant and disconnects them immediately.

Because the server distributes public keys, a compromised server could in principle try to substitute one. That's what safety numbers are for: each account has a fingerprint (Settings › Security) that two people can compare over a trusted channel, in person or on a call. Matching fingerprints prove you hold each other's real keys. On the granting side the same fingerprint is shown next to each member in the account's Encryption access settings, so an admin can compare it before handing over the key.

If you'd rather make that comparison mandatory, an owner or admin can turn on Require manual approval for every member in the account's Encryption access settings. Every new member, whether or not they already use General Text, then waits for an admin to grant them by hand after checking the fingerprint, trading the automatic instant-access convenience for a guaranteed human check on every key.

Every change is signed

Each edit and snapshot carries a signature from its author inside the encryption, so the relay never learns who wrote what, but every receiving device verifies that changes come from a current member of the account. Devices reject anything unsigned or signed by an unknown key, and the server refuses to store unsigned frames at all. Each device also remembers the highest sync position it has seen per file and raises a warning if the server ever serves older history than that, so a rolled-back or tampered log cannot pass silently.

Recovery

End-to-end encryption has a consequence: we cannot reset what we cannot read.

  • Forgot your passphrase? Use your recovery key to restore access and set a new one.
  • Lost the recovery key but know your passphrase? Generate a new recovery key in Settings › Security.
  • Lost both? Your synced data is unrecoverable by us, by design. Copies already on your devices remain readable there, and an account's content can be re-granted by another member, but a solo account with no unlocked device has no back door. Keep the recovery key safe.

Removing someone

Removing a member deletes their grant and disconnects their sessions immediately; they can no longer fetch anything. Encryption cannot un-share the past. Anything they already synced may exist in copies they kept, which is true of every collaboration system. For content created after removal, they hold no working access.

History

Every synced file keeps a version history you can browse and restore from (the History view next to Edit and Preview). It works the same way everything else here does: the server stores an opaque log of encrypted changes and your device decrypts and replays them, so we can serve your history without ever being able to read it. Each version shows who made it, verified by the same signatures that protect live editing. Restoring an old version applies it as a new change; nothing is rewritten, and the restore itself becomes part of the history.

Current limits

  • Binary files (images, PDFs, and other attachments) are capped at 100 MB each. A text file's synced state can grow to 16 MB; large changes sync in chunks automatically.
  • History for synced files is kept for up to 14 days and counts toward your storage. Local-only workspaces keep history on your own device, and there you can set how long to store.

The crypto

All cryptography runs client-side via libsodium: XChaCha20-Poly1305 for content (each file's id is bound into the ciphertext so blobs can't be swapped between files), X25519 sealed boxes for key grants, Ed25519 for authorship signatures, and Argon2id for the passphrase. The server's job is to move and store bytes it cannot interpret, and the app sandbox (see Security) bounds what code you install can reach.