MishmarמִשְׁמָרMEESH-marHebrew for a guard post — the watch, and the people who keep it.

WorkIdentity and cryptography

A team messenger whose server cannot read message content

An end-to-end encrypted messenger for a small private group, built on MLS (RFC 9420), with passkey-only sign-in and a written statement of the metadata the server still sees.

The problem

A hosted tool that encrypts data at rest with keys the provider holds lets the provider, and anyone who compromises it, read every message. The goal here was a team messenger for a small private group, on phones and desktops, where whoever runs the infrastructure, including its builder, cannot read the content.

Removing someone has to stop both their connection and their ability to decrypt. And a privacy tool that overstates its guarantees is worse than one that makes none, so the limits were written as requirements.

What was built

  • One group key protocol for everything. Each channel, including each direct message, is one MLS group (RFC 9420) whose members are devices, not users. MLS provides forward secrecy and post-compromise security, and every membership change rotates keys. Call media keys come from the same group through the RFC 9420 exporter, so a call inherits channel membership without a second key exchange.
  • A server that only relays. It orders and stores opaque blobs, relays handshake messages and enforces who may connect. It holds no key and takes no part in any MLS operation.
  • Passkey-only sign-in. No password exists anywhere in the system. Sessions are per device and individually revocable. Passkeys protect the session and MLS device keys protect content, so a stolen session cannot read messages.
  • Desktop keys sealed at rest. In the installed desktop app, key state is sealed at rest with the OS keychain by the privileged side of the app. The page never holds the sealing key, and the state is served only to the app’s own origin. Storage is refused rather than downgraded when OS encryption is unavailable. On mobile, the design keeps a 32-byte data key in the platform keystore and stores the state as AES-GCM ciphertext.
  • Files and search that stay on the client. Each file gets its own random 32-byte key, carried inside the encrypted message with the filename and type. Search runs entirely on the device.

Design decisions

Removal happens in two halves, transport first. The server decides who is a member and ends the session immediately. A client-side designated committer, chosen by a deterministic rule every member computes the same way, makes the change cryptographically true. Revocation goes first because a commit needs another member’s device online.

Commits and messages share one ordered log. A message cannot be decrypted until the commit for its epoch is applied, and two separate sequences cannot express which came first.

The desktop shell limits what the interface can reach. It keeps key material in a privileged process that checks the origin of every request for it; the interface process is sandboxed, with no direct operating-system access. Off-origin navigation is blocked, new windows go to the system browser only for http and https, device permissions are denied by default, and a strict Content Security Policy names the only origins the interface may connect to.

No hand-rolled cryptography. An established Rust MLS implementation is compiled to WebAssembly for desktop and bound natively for mobile, behind one interface. A pure-TypeScript alternative was rejected because its author states it has not been security audited.

Failures are loud. The first milestone’s placeholder provider, which did no encryption, had three independent guards against shipping. A device refuses to load key state that belongs to a different identity.

Evidence and limits

Every milestone runbook ends with an explicit list of what was proven and what was not.

  • 271 automated tests passing at the last recorded count, across the Rust core, the WebAssembly binding, the client core and the server.
  • Two real clients, using the desktop app’s session code, formed a group against a running server, exchanged messages both ways, and left no stored payload containing plaintext.
  • Removal verified in both halves: sessions revoked over HTTP, and the removed device unable to decrypt under real MLS.
  • On a physical phone, the crypto self-test passed 8 of 8 checks, including locking out a removed device.

Defect classes found and fixed: a deduplicated retry that used up a sequence number and could stall a channel; a WebAssembly build with no randomness source; a connection policy that allowed any host; and a backup security key that enrolled as a new member unable to read earlier history.

The server cannot see Metadata the server does see includes
Message, file and call content Who communicates with whom, and when
Filenames and file types Message and file sizes
Search queries and the index Channel membership
Any encryption key Which channel and uploader a file belongs to

The claim is content confidentiality, not traffic-analysis resistance, and the requirements make the interface say so. Deletion is cooperative: a device that already decrypted a message can keep it.

Not yet proven: one mobile platform’s native binding has never been built or run; the mobile secure-storage path has not been exercised on a device; the concurrent-committer test has not been written; the call cryptography is tested but no real encrypted call has been held; ringing a locked phone is unfinished; file transfer is unit-tested, not verified end to end. Losing every device loses history in this version, by decision.

Where it applies

  • Authorization packages. The split between verified and not verified is the useful artifact. Narratives for key management (SC-12), cryptographic protection (SC-13) and identification (IA-2) hold up better when every claim points to a test and every gap is named.
  • Customer security questionnaires. Asked who can read shared engineering data, a supplier can answer in the shape of the table above: state what the provider observes instead of implying it observes nothing.
  • Fractional security leadership. The same questions apply to any vendor’s claim of end-to-end encryption: where the keys live, who issues membership changes, what removal actually revokes, and what metadata remains visible.

Independent work by Wade Blackwell. Each write-up is written from scratch for this site, without client, employer or personal data. Names, hostnames, addresses and configuration detail are left out on purpose.