Satchel

How Satchel works

A plain technical overview of Satchel 0.3.0, a Firefox and LibreWolf add-on. Everything runs inside the add-on (JavaScript and WebAssembly). The only other piece is Session Router on the same computer.

1. Keys and identity

Your identity is a key pair, not an account. When you first open My Satchel you choose a passphrase (at least 8 characters) and Satchel makes a 32-byte Ed25519 seed. Two keys come from that one seed:

You can keep several profiles, each with its own key, name, mail and contacts, and pick one per site. Nothing in Satchel links one profile to another. There is also a throwaway key that lives only in memory and is gone when you end it.

2. Reaching .sesh through Session Router

.sesh names belong to the Session network. Session Router runs on your computer and wires .sesh DNS into the system, so a name resolves to a local address starting with fd2e:7365:7368:. Satchel doesn't carry any traffic itself; it uses the browser's own requests, and the router carries them.

.sesh sites are plain http://, because Session Router already encrypts the traffic end to end. With HTTPS-Only mode on, the browser rewrites those requests to https://. When Satchel sees that, it loads the page by the router address instead of by its name. LibreWolf also rewrites local addresses, so there it needs dom.security.https_only_mode.upgrade_local set to false.

If the browser uses DNS over HTTPS, .sesh names go to an outside server that can't answer them and learns which sites you open. Satchel's setup check warns about this, and the fix is to exclude sesh from DNS over HTTPS.

3. Signed records and collections

A place is one collection on one host: a chat room, board, wiki, People list, directory, file drop or app collection. Its address looks like http://<host>.sesh/<kind>/<name>, and a join link carries the collection's 64-hex root key after the #.

Anyone can run their own collection on their own host. On My Satchel, places are grouped by the collection they come from, and Remove host leaves a collection's places and stops syncing with it.

4. Mail

A mail address is a signed card holding your Ed25519 key, your X25519 key and a list of one to three mail hosts. It is shared as a link of the form srnet://mail/<key>…, and People cards and Contacts show it so others can write to you.

5. File drops

A file is encrypted in the browser before upload with ChaCha20-Poly1305 in 64 KiB chunks, one random key per file version, padded to a power-of-two size bucket so the host learns only the bucket. The file key is wrapped to each recipient's X25519 key. A share link carries the key after the #, which browsers don't send to the host.

6. The app sandbox

A host can offer small apps for a collection. An app is one JavaScript file (at most 256 KiB), published as a record signed by the collection's root key. Satchel fetches it and checks its size and hash before it runs.

7. Permissions and why

PermissionWhy
webRequest, webRequestBlockingTo notice requests for .sesh names (and HTTPS-Only rewrites of them) and load them by their router address. The listeners match only .sesh names, a list of search engines' result pages and the exact router addresses Satchel fetches itself.
dnsTo check that .sesh names resolve through Session Router, and to find a site's router address.
storage, unlimitedStorageTo keep your encrypted key, mail, contacts and joined places in the browser, without the browser clearing them when space runs low. Satchel also asks once for persistent storage.
Access to http:// sites ("Access your data for all websites")Router addresses are plain http:// local addresses, and Firefox has no narrower way to allow them. Satchel uses this only for .sesh.
*.sesh, 127.0.0.1.sesh places, and a local control endpoint on this computer that some Session Router builds offer, used only after you pair with it.
Search engine result pagesWhen you type name.sesh in the address bar, the browser may send it to a search engine. Satchel catches that and opens the site instead.

Satchel has no content scripts and doesn't read or change other sites. The microphone isn't an install-time permission: Firefox asks for it only when you press record in a voice clip window, and only Satchel's own page calls for it. The manifest declares that no data is collected.

8. Storage and backup

Your key is stored encrypted: PBKDF2-SHA256 with 600,000 rounds and a random 16-byte salt derives an AES-256-GCM key from your passphrase. The public key is stored in the clear next to it so Satchel can show what's yours while locked. The seed is held in memory only while the key is open, and it is dropped after 15 minutes without use, or when you press Lock. Background work, like the automatic mail check, doesn't count as use. Synced collections are kept in the browser's IndexedDB.

Right after a key is made, Satchel asks you to save a backup file, and a reminder stays on My Satchel until you do. Export key saves the same encrypted file at any time. It opens only with your passphrase. Restore from a backup file, on the first screen, brings it back on the same or a new install. Without the passphrase or a backup file there is no way to recover the key.

Copyright the Satchel authors. MPL-2.0.