Security
Your content is encrypted on your device. Sharing is backed by signed access rules: the app verifies the signed policies, access manifests, and write signatures on the records it uses.
This page summarizes the implementation. The technical documents define the rules and known gaps in detail.
Assumptions
These properties assume an honest, uncompromised client that runs its validation checks, uncompromised user private keys, authentic identity keys, and working cryptographic primitives. The API and its storage may be compromised. Some behaviors still cannot be detected or prevented; they are listed under Limits.
Your device and the sync service
Local encryption protects data stored on your device. End-to-end content encryption lets the service sync documents and files without the keys needed to read them.
Keys are unwrapped and content is decrypted here.
Unlock the local keyring
A host wrapping key protects the account root key. An optional PIN adds another layer.
Derive separate local keys
One key each for the database, the local file store, and the saved identity.
Keep local storage encrypted
The app reads and writes through the encrypted database and file store.
The unlocked app can read plaintext.
The API stores and delivers encrypted records.
- Encrypted payloads
- Document updates, files, and encrypted metadata.
- Wrapped keys
- Encrypted key envelopes that authorized clients can open.
- Signed access records
- Signed policies, grants, and content-write headers.
The service holds no plaintext content keys.
Encrypted
- Document and file contents
- Encrypted metadata, such as folder names
- Organization names and custom group names
- The keys wrapped for recipients
Decrypting them requires the matching private keys or unwrapped content keys.
Visible to the service
- Built-in group roles, such as Admins and Members
- Roster and group membership
- The structure of folders, documents, and files, including which attachments belong to which documents
- Identifiers and public keys
- Access-policy and grant relationships
- Which user and device signed each access change and write, with its signed timestamp
- The metadata that orders document updates
- Ciphertext sizes and storage usage
- IP addresses, session and activity times, and the IP address recorded when your identity is registered
- Subscription and billing records, including the billing email for a web subscription
Encryption does not hide this information or traffic patterns such as request timing and size.
Verified sharing
A container (a folder in Explorer) groups content and its access rules. Clients derive who can receive its keys from verified access manifests and signed group policies. Editing a server-side membership row is not enough to grant access.
Verify access
Check signed access manifests, the group policies they reference, pinned identity keys, and remembered checkpoints.
Encrypt and wrap
Encrypt the content. Wrap content keys under container keys, and wrap container keys for the verified recipients.
Validate and store
Enforce write authorization and signed commitments. Store ciphertext and wrapped keys for delivery.
Verify and decrypt
Verify the signed records and access path, unwrap the keys, and decrypt the content locally.
Signed history and checkpoints
Signatures and hash chains bind policies and access changes to their authors and predecessors. Clients remember identity keys and policy and access checkpoints, and reject later substitutions, conflicting versions of the same history, and rollbacks below the state they have seen.
Revocation applies going forward
Removing group members rotates the group key and the affected container keys in one atomic update. Removing access cannot erase content or keys someone already received. Nested containers and retained history have further limits, listed under Limits.
Cryptography
Content encryption, recipient key delivery, signatures, and local storage each have a distinct role in the protocol.
Public-key operations in the client and API keying protocol are post-quantum only: ML-KEM-1024 (FIPS 203) for key delivery and ML-DSA-87 (FIPS 204) for signatures. That statement covers the keying path, not TLS connections or deployment tooling.
Synced content and sharing
| Purpose | Mechanism | Role |
|---|---|---|
| Document and file records | AES-256-GCM + HKDF-SHA256 | Authenticated encryption with a separate derived key for each content record. |
| Recipient key delivery | ML-KEM-1024 + AES-256-GCM | Wraps container keys for users and groups. Content keys are wrapped under container keys with AES-256-GCM. |
| Digital signatures | ML-DSA-87 | Authenticates signed policies, access events, and content-write headers. |
| Local key separation | HKDF-SHA256 | Derives purpose-specific storage keys from the wrapped local account root key. |
On your device
| Purpose | Mechanism | Role |
|---|---|---|
| Local database | ChaCha20 (SQLite3MultipleCiphers) | Encrypts the SQLite database file at rest. |
| Local file store | AES-256-GCM | Encrypts stored file bytes in authenticated chunks. |
| PIN lock | PBKDF2-SHA256 + AES-256-GCM | Derives a wrapping key from the PIN. |
| Password-protected backups | PBKDF2-SHA256 + AES-256-GCM | Derives the backup key from the backup password. |
| Recovery phrase | BIP39, 24 words | Encodes the entropy from which an identity's signing and key-encapsulation keys are derived. |
Local storage and PIN protection
The local keyring stores a wrapped account root key and derives keys for the encrypted SQLite database, local files, and identity persistence. In the browser, data is stored in the origin-private file system (OPFS); the keyring manifest and wrapping key normally live in IndexedDB.
Protection depends on the host keystore. The web app persists a Web Crypto key. The desktop and mobile apps store exported key bytes in IndexedDB instead. Tearleads does not keep this key in a hardware-backed keychain on any platform; its protection depends on how the browser, WebView, and operating system protect the app's stored data.
An optional PIN adds a PBKDF2-SHA256 and AES-256-GCM wrapper around the host-wrapped root key, so reopening requires both the host key and the PIN. On the desktop and mobile apps, which store the wrapping key as raw bytes, someone with a copy of the app's stored data, such as a device backup, can try PINs offline, and without a PIN can decrypt that copy directly. In a browser, a copy of the browser's stored data may allow the same. No PIN is required by default, and a local PIN does not change remote sharing permissions.
Limits
What the design does not detect, prevent, or promise, even under the assumptions above.
- First contact establishes trust
- Each device pins the first identity bundle it accepts and rejects later changes. A server that substitutes a key on that first lookup can still establish a false identity. Matching a key to its fingerprint in signed state does not prove who controls it. The app shows signing-key fingerprints, but it has no step for confirming a key out of band before it pins that key.
- Checkpoints only cover what a device has seen
- A device with no checkpoint for a policy or folder (a new device, a folder or organization it is seeing for the first time, or a device whose local data was reset) can receive old but validly signed history. Signatures alone do not prove that a view is the newest or that all devices see the same view. Stronger split-view resistance needs independent witnessing or gossip.
- Encryption does not ensure availability
- The service can withhold ciphertext, policies, or key envelopes and refuse requests. When required verification material is missing, the operation cannot safely proceed, so it stops.
- An unlocked device can read content
- Local encryption does not protect against malicious code running in an unlocked client or a compromised device. Anyone who obtains the recovery phrase, including its QR code, can recover that identity.
- New members can read retained history
- Access includes history: a member added to a container can read the history that container retains, not only changes made after they joined.
Revocation, nested containers, and historical access
Revocation cannot retract keys someone already learned or content they already downloaded. Rotating a parent container does not automatically rekey every nested container, and refreshing a nested container's signed access history does not itself replace its encryption keys or promise confidentiality from a former member.
A revoked signer working with a compromised server may still present records under valid historical authority to a device that has not seen newer signed state. Verifying that authority does not prove when the record was actually created.
Current container keys also unlock retained predecessor keys, so current members can read history. A compromised current container key therefore exposes that retained history.
Technical documents
These documents in the public Tearleads repository on GitHub define the verification rules, assumptions, and remaining gaps in more detail.
- Security guarantees (GitHub)
- What each property protects, the threat model, and the known gaps.docs/security-guarantees.md
- Keying design (GitHub)
- How content keys, container keys, and recipients fit together.docs/keying-design.md
- Protocol specification (GitHub)
- Messages, proofs, validation rules, and failure semantics.docs/protocol-specification.md
- Cipher suites (GitHub)
- The cryptographic primitives and where each one is used.docs/cipher-suites.md
- Protocol models (TLA+) (GitHub)
- Bounded models of protocol safety rules that complement, not replace, tests.formal/README.md