Who we defend against
This is the threat model in plain words. The longer, exact version is the project's SECURITY.md; where this page and that one differ, that one is right and this page has a mistake to report.
The idea
Messages, files and calls are sealed on your device with keys that never leave it. The server stores and forwards what it cannot open. It is deliberately dumb: it decides who may send to whom and for how long it keeps things, and that is all. Everything below follows from that, including the places where it stops being enough.
Who might attack, and what they can do
| Attacker | What they can do | What stands in the way | What does not |
|---|---|---|---|
| Someone on the network | Watch that a connection exists and how much moves | TLS between your device and the server; the messages are sealed on top of it | They can see that you use Yeetline, when, and roughly how much |
| Someone who steals the server's disk or a backup | Read everything the server stores: who has accounts and their email addresses, who is in which conversation, when and how big messages are, profile names and pictures, the sign-in log, and sealed messages | The messages are sealed to keys the server does not have; a backup that leaves the machine is encrypted | The social graph and the timing are readable. The key to the machine's own backups is kept on that machine, so someone who takes the whole machine has it (a copy of a backup alone does not). A passphrase can be guessed offline against the account keystore the server holds if you turned on sync; the guess costs 32 MiB of memory each |
| An operator who reads but does not change anything | The same as the stolen disk, live | The same | The same |
| An operator who acts: serves modified code, lies about keys, or lists members that are not there | Tamper with what it serves and what it says | Apps built with the release key refuse code the key did not sign. Safety numbers and the pinned key catch a swapped identity, most strongly in a direct message | In a web browser nothing stops an operator who serves different code. In a room, who is a member is the server's word, so an operator can add an account it holds. See "What the server can do if it lies" below |
| A member of a conversation | Send you anything, including hostile files and links; leave; copy what they were sent | Nothing they send is run; pictures are checked; message text is never put into the page as markup. A message cannot claim to be from someone else or be counted for another person | Anyone you send a message to can show it to anyone else |
| A stranger with an account on the same server | Probe for who exists and who is in what | The server answers a non-member the same way whether or not a conversation exists; sign-in and sends are rate limited | Names that are public (profiles) are public |
| Someone who holds your device | Everything you can do, while it is unlocked | The keys on disk are sealed twice, once under your passphrase and once under a key the browser will not export (the second guards against a script that reads storage, not against someone who holds the disk) | A stolen unlocked device, or one where you chose to stay signed in, is a stolen account. A locked profile is only as strong as your passphrase |
| A script injected into the page | Use your keys while the page is open, in the page's own name | No inline script, no outside script, nothing a message holds is ever put in the page as markup, and what is stored is sealed under a key the browser will not export, so a script that only reads storage once gets nothing it can open later | It cannot be stopped from using the keys the page holds, or from sending out what the page can read, for as long as it runs |
| Whoever can read your recovery email | Start an account recovery | A wait, a notice to your devices, and a second factor if you set one. Recovery gives the name new keys: nothing from before | They can take the name. They cannot read what came before |
| A future computer that breaks today's public-key cryptography, with traffic recorded now | Open messages recorded today | Sessions mix in a lattice key exchange (ML-KEM-768), and the ratchet adds more of it as the conversation goes on | The sealed block used for the personal-key tier, the account's recovery backup and the transport layer are not post-quantum |
What the server can see, and what it cannot
It cannot: read a message or a file, sign in as you, read a call, or tell what an attachment is beyond its size bucket.
It can see: who has an account, who is in which conversation, when messages are sent and roughly how big they are (in buckets), which two people are in a call and for how long, the last few addresses each account signed in from, a log of sign-in attempts with what each browser said about itself, each account's email address, the record of what administrators and moderators did, and the public things you choose to publish (a name and a picture, and the profile details you fill in). It keeps sealed messages as long as the server's retention setting says, and no longer. The complete list, with where each item is kept, is in the project's SECURITY.md.
What the server can do if it lies
An operator who is willing to act, not only to read, can do some things the sentence above does not cover, and the project would rather you hear them here.
- Add an account it holds to a room. Who is in a room is the server's word. Messages sent after that are sealed to the extra member too. You would see the member count change and a new name in the list. A direct message has two named people, and the safety number and personal keys are what hold the server to them.
- Present a different key for a contact. The app pins the first key it sees and warns when it changes. In a direct message sending is held until you answer. In a room it warns and carries on.
- Hold back or damage messages. It can delay, drop or reorder what it relays. A damaged message is lost for good where a dropped one is not.
- Hand out an old key again. A key you retired can be offered again for as long as the old half is still on your device (a month).
The first review of this found and fixed two other things in this family: a way for a server to write a stranger's first message as a contact's, and a way to move a message from one conversation into another. Both are described on the review page.
What each part of the app protects
| Part | Protects | Does not protect |
|---|---|---|
| The message sessions (a handshake with a lattice key exchange, then a ratchet that changes keys all the time) | What is said, from the server and the network, including after a later key theft | Who talked to whom, and when |
| Safety numbers and the three badges | That the key you are sealing to is the key the other person has, as far as you both compared | Anything before you compared them; rooms, where the server lists members |
| The personal key and the top badge | That a swapped key later is caught, and that a message really is signed by the person | Forward secrecy and post-quantum safety: it sits inside the ratchet and adds neither |
| The keystore on your device | Your keys, sealed under your passphrase with a memory-hard function, and again under a key the browser holds | A weak passphrase; a script running in the page while it is open |
| Files | The contents, which are sealed in 512 KiB pieces, each tied to its place | The size bucket, and that a file was sent |
| Calls | The audio and video, between the browsers | That a call happened, between whom, for how long; and that the server relays the setup, so an operator who rewrote it could stand in the middle |
| The signed web bundle in the phone and desktop apps | That the app runs the code the release owner signed | A browser tab; code the owner signed that is wrong |
| The sign-in hand-off from the app to another page of this service | That only the page you meant to open can use the carried sign-in, once, within a minute | A script on either page while it is open |
| Account recovery by email | Getting the name back with new keys, after a wait, with warnings to your devices | Any of the old messages: they cannot come back |
| The recovery key (optional) | Getting your account's own keys back, after losing every device | What other people sent you, which cannot come back; it is only as safe as the paper |
What we do not defend against
- A compromised device, or someone who watches you type.
- Metadata: who talks to whom and when. This is the price of delivering a message only to the people in the conversation, and it is not being traded away (a scheme that hides the sender from the server would conflict with erasing an account's data when asked).
- An operator who serves different code to a browser tab.
- Someone who forces you to unlock your device.
Where to go next
Our own security review says what has been checked and how to check it again. Reporting a security problem is how to tell us we are wrong.
Last changed 2026-10-19