Security and threat model
The server cannot read your data, and here is exactly what it can see. Scientist seals every record on the device that creates it, and the server holds no key. The claim is bounded by the list further down, which is the whole of what the server holds: counts, sizes, timings and public keys, and not one byte of what you wrote. A protection not yet built is marked as such; a limit is stated, not softened.
System and scope
Scientist is a task, project and journal system. Per account the server keeps an authenticated, encrypted, append-only log of changes, wrapped copies of the account key, a device registry and a sealed drop box. It orders events and moves bytes. Every query, schedule, plan, search and model call runs on a device holding the key; the server holds nothing readable, not a task's text, date or priority, nor the shape of the graph containing it.
Left of the boundary is trusted with the key. Right of it, nothing is, the operator included.
Account isolation
An account is one sealed log under one master key. No sharing, no second key holder, no administrative access, because no mechanism exists that could reach it. The operator cannot be compelled to open what it cannot read. The cost: every recovery path must work without the operator. See Irrecoverable loss.
What the server can see
This is the complete list. It changes by explicit decision, never by implementation drift, and any change is recorded in the build log with its date.
- That an account exists, and when it was created.
- Passkey credential identifiers and public keys, and the drop-box public key.
- The number, size and timing of sealed records. A busy period is visible as a burst. Sizes are not padded, so a record's size separates a full rewrite from a one-field edit, and a journal entry from a task being ticked off: the kind of activity, never its subject. Padding is available and not taken, and a record already written keeps the size it was written at, so this is not closable after the fact.
- The number of devices, how far each has read, and when each was last seen. Needed to prune old records.
- The number and timing of drop-box arrivals.
- Which device wrote each record, and when. The log has one writer at a time and the server has to advance that device's place in it, so it sees each device's rhythm and can tell one from another. Not what any of them wrote.
- A history of security events on the account. Every recovery attempt with its time and its outcome, every device registration and revocation with its time. It is kept so that you can read it, which is why the server can read it too. It says when the account's security was exercised, never by whom.
- The number of capture credentials, and when each was minted, last used and revoked. A capture credential is not a device. Its last-used time moves on every capture, a coarse signal of where captures come from over time; its name is sealed to the drop-box key and is a blob to the server.
- A passkey's signature counter. Kept so that a cloned authenticator can be detected. It moves on every use of that credential anywhere, so a counter that has jumped between two sign-ins says the passkey was used on another site in between: a small window onto activity outside Scientist.
- Short-lived operational machinery. Challenges and their expiries, hashes of session and capture tokens, rate-limit counters, idempotency keys, the device-linking relay's commitment, the nightly dump's bookkeeping. None of it is content, none of it names a person, and an alarm deletes each within minutes to a day.
- The source IP address of each request, in the logs this operator controls, kept for 7 days. The number governs what our own server writes down. The host's edge telemetry sits underneath it and is kept under the host's policy, whatever this page says.
No email address of yours, for any purpose. The server does mint one deliverable address per account so that mail can be captured into the drop box: it is generated by the server, it belongs to the account rather than to you, it is never an address you gave, and it says nothing about who you are. Nothing on this list links an account to a person. Paying for Scientist goes through the App Store or a Stripe Checkout page, so the payment provider holds the identity; once billing exists the server will hold an entitlement date, and for web purchases a provider customer id, and this list will say so. Task names, dates, priorities, projects, notes and journal entries are not on this list and cannot be added to it.
One stored record. The server writes down the outside and stores the inside without opening it.
Protections and mechanisms
- Content. AES-256-GCM under a key derived from the master key, with associated data binding each ciphertext to its account, purpose and key version, so it cannot be moved between contexts.
- Structure. Each change is one opaque payload; collection names, identifiers, field names and the graph's shape sit inside the ciphertext.
- The master key at rest. Wrapped only, under a key from a passkey's PRF output or the recovery code. The server sees neither and has no endpoint that could receive one.
- The master key in transit. During linking it is sealed to the new device's ephemeral public key; the server relays an opaque blob.
- Inbound items. Sealed to the drop-box public key on arrival; the plaintext is discarded.
- Integrity. Every envelope is authenticated. A fabricated or altered record fails to open rather than returning altered content.
- Admitting a new device. Recovery means opening a challenge sealed to the account, which proves possession of the master key. Rate-limited, logged, and every registered device is told.
Adversaries and mitigations
Each is a capability, not a person, so a new attack files under an existing entry.
- Theft of a locked device. Disk encryption and the platform keystore; the master key is never on disk unwrapped. The web client keeps it in memory and drops it when the tab closes.
- Theft of an unlocked device. The adversary is the owner. Mitigations are operational: auto-lock, an app lock timer, biometrics before the journal opens, revocation from another device.
- A network attacker. Sees that a connection exists, its timing, size and endpoints. The payload is ciphertext the operator cannot read, so a mis-issued certificate yields no more than the server already has.
- A malicious or compromised operator. The adversary this design is aimed at. It reads the list above and nothing more. It can withhold, reorder, duplicate or delete; it cannot fabricate a record that opens, or enrol a device that reads.
- An operator under legal compulsion. Can be made to disclose what it holds, to start logging, to retain. Cannot be made to produce keys it does not hold. Ciphertext, key wraps and metadata are all there is.
- A supply-chain attacker. Both cryptography libraries have no third-party runtime dependency. Lockfiles pin integrity hashes, the web bundle is built reproducibly, the content security policy forbids code from any other origin, native binaries are signed.
- A hostile browser extension. With permission for the app origin while the app is unlocked, it reaches plaintext and the key. Nothing inside a web page prevents this.
- Whoever controls the passkey provider. A synced passkey is copied between your devices by the provider, and the secret that unwraps the master key travels with it, so whoever can make that credential assert unwraps the account: a compromised or compelled Apple ID or password-manager account. Nothing here prevents it, because the choice is made outside the system. A passkey bound to its authenticator, one that does not sync, leaves the provider nothing to hold; registering more than one, and the list of credentials in the app, are the rest of what v1 does. A synced passkey makes your data as reachable as the account it syncs to.
- Compromise of the recovery code. The code alone rebuilds the master key. There is no second factor, because one the operator could enforce is a door the operator controls. At 160 bits guessing is infeasible; finding a copy you left somewhere is not.
Known weakness: the web client
In the web client, the operator delivers the code that holds the key. An operator intent on reading your data would not attack the encryption. It would serve you, once, a build that sends the key elsewhere.
Native: the code and the data reach you from different parties. Web: one party supplies both.
The native apps differ because Apple distributes their code and our server only the data. Four measures reduce the web exposure without removing it: the source published at launch and the bundle's hash published, so served code can be checked against the repository (the build is reproducible today; neither publication has happened yet, see the last section); a dedicated origin serving nothing else, so a compromise of this site does not reach the app; a content security policy allowing no third-party origin, no analytics, no hosted fonts; and the key in memory by default, gone on tab close, persistence opt-in. Together they turn an undetectable attack into a detectable one, for a party who verifies.
Outside the boundary
No mechanism here changes any of these.
- A compromised device. Malware with your privileges sees what you see. End-to-end encryption protects data from the server, not from the machine that decrypts it.
- Input and output capture. A keylogger, a screen recorder, someone in the room.
- Traffic analysis. Timing and record sizes are visible to the operator.
- Momentary plaintext on inbound email. A message arrives readable, is sealed, and the plaintext is discarded. The guarantee is not stored, not never seen. Every relay on the way also handled it; that is email.
- Loss of availability. An outage, a suspension or a billing failure makes the service unreachable, not the data lost: every full client holds a complete replica and can seed a fresh server.
- Metadata correlation. Whoever runs the infrastructure can tie an account to an IP address over time, and a payment provider's records can tie a customer id to a person.
- Physical access to an unattended device, and hardware implants.
- Your own key handling. A photographed recovery code, an unlocked laptop, a four-digit passcode.
- Asking a model about a note. There is no Scientist-run model: the browser calls the provider you chose, with your own key, under that provider's terms and retention, and the note body leaves your device in the clear. Before anything goes, a preflight screen shows the exact bytes, the provider, the model and the destination, and says when a note body is among them. Our server is never in the path, which is why this is not in the list above, and it is outside the guarantee, which is why it is here.
Irrecoverable loss
If every device is lost and the recovery code with them, the data is unrecoverable. Not withheld pending support: gone. That is the cost of the guarantee and the evidence it is real. A system that could recover your data could read it.
So linking a second device is the routine path, not an advanced feature. The clients prompt for export and offer a readable export and an encrypted archive that restores an account exactly. The recovery code is shown once, confirmed, and can be rotated from any unlocked client; a printed recovery kit is offered, since paper outlives disks. Server-side backups exist and are worthless to an adversary: ciphertext under a key the server does not hold.
Decisions and trade-offs
Four decisions a reasonable party might have taken differently.
- Record sizes are not padded. Padding costs every write and resists only an adversary already watching the timing of every change.
- IP logs are kept for 7 days. Enough to investigate an incident; no standing history to be compelled. The period is a policy applied to the logs our own server writes, and the host's edge logs are underneath it and outside it.
- No warrant canary. A canary lapsing through inattention asserts something its author did not intend. This document carries the disclosure obligation instead.
- Revocation does not erase a device. It withdraws server access; it cannot reach back into the device, and a server-issued wipe would contradict this document. A revoked device locks itself and offers to delete its store. No string in Scientist will claim the server erased anything.
Claims not yet verified
Design is not evidence. These remain to be built or measured; the list shortens as each is discharged.
- Detection of a withheld or forked log. The server cannot fabricate a record, but it can hold one back. Every client stops on a log shorter than the longest it has seen, which catches a rollback and not the three cases beside it: a new device started from whatever point the server chose, two devices served logs that differ and each only grow, and the newest records withheld from one device. Closing those needs every record to carry the fingerprint of the one its writer last saw, which is named for a later version. This one stays open.
- Published bundle hashes. The build is reproducible: two builds produce byte-identical output and a verifier matches a served copy against its manifest. The hashes are not yet published here, so until they are a reader cannot perform that check.
- Passkey PRF and X25519 across target browsers. Both underpin the web client; neither is measured yet. Where a browser lacks either, the decision is recorded before any code changes.
- The local store at rest on native devices. Relies on FileVault and iOS Data Protection, with no application-level encryption of the local database. A Mac without FileVault is a genuine exposure. The web store holds ciphertext only.
Change control
A change to what the server can see is a decision in its own right, never a side effect of implementation, recorded in the build log with its date. A new adversary or residual risk is added here before the code provoking it is written.
A weakness found in any of this goes to support@scienti.st, and is read by a person. The machine-readable form is /.well-known/security.txt.