Build encrypted group messaging on Nostr (Marmot/MLS)
Esta página aún no está disponible en tu idioma.
You want a group chat where only the members can read the messages — no central server, no phone numbers, and ideally not even a record of who is talking to whom. That is exactly what Marmot is for: it runs the IETF MLS group- encryption standard over Nostr’s decentralized network. This guide explains what the pieces are, how they fit, and — just as importantly — where the rough edges are.
What Marmot is
Section titled “What Marmot is”Marmot = MLS (the cryptography) + Nostr (the identity and transport).
- MLS (RFC 9420) is the IETF’s Messaging Layer Security standard for end-to-end-encrypted group messaging. It gives you forward secrecy (compromising today’s keys doesn’t expose past messages) and post-compromise security (the group heals after a member rotates keys).
- Nostr provides the identity (your own keypair — no phone or email) and the transport (relays you choose, not a central server).
Marmot is the specification that ties them together — a set of “MIPs” (Marmot’s spec documents) defining which Nostr event kinds carry MLS KeyPackages, group invites, and encrypted messages. White Noise is the production reference client built on it.
Why MLS over Nostr (and not something else)
Section titled “Why MLS over Nostr (and not something else)”Marmot’s own framing: Signal has excellent E2EE but centralized infrastructure; plain Nostr DMs (NIP-04/NIP-17) lack forward secrecy and real group messaging. Marmot aims to combine MLS’s proven group cryptography with Nostr’s censorship-resistance and identity freedom — encrypting both message content and, as a goal, the metadata of who is in a group.
The pieces, and how they fit
Section titled “The pieces, and how they fit”You do not implement any of the cryptography yourself. You assemble vetted, license-verified libraries and wire up the Nostr event choreography. The crypto lives in audited code; your job is integration.
| Layer | What it does | Use |
|---|---|---|
| MLS core | The actual group cryptography (RFC 9420) | openmls (Rust) · ts-mls (TS) |
| Marmot engine | Marmot’s high-level API over MLS — KeyPackages, groups, Welcomes, message encryption | mdk-core (Rust, the engine inside White Noise) · @internet-privacy/marmot-ts (TS) |
| Media | Encrypted images/files, stored off-relay | Blossom protocol · a Blossom server · blossom-client-sdk |
| Reference client | The production app that proves it works | White Noise |
The moving parts, in plain terms (event kinds pinned from the MIPs at commit 21a67b2):
- Identity → KeyPackage. Your Nostr keypair becomes your MLS identity. You
publish a KeyPackage (
kind:30443) so others can invite you, and advertise where your KeyPackages live with a KeyPackage relay list (kind:10051). - Group + Welcome. A group is an MLS group tagged with the Marmot Group Data
Extension (
0xF2EE). To add someone, you fetch their KeyPackage and send a Welcome (kind:444) gift-wrapped for privacy (NIP-59). - Messages. Group messages (
kind:445) are encrypted with a key the MLS library derives per epoch (ChaCha20-Poly1305). New members read them from the relays named in their Welcome. - Media (optional). Files are encrypted, stored on Blossom by their hash,
and shared with a small
imetatag in the message.
The step-by-step choreography ships as four companion skills (and matching
Goose recipes) in this repo: marmot-group-setup, marmot-relay-strategy,
marmot-encrypted-media, and marmot-push-notifications. Each one orchestrates the
Nostr events and delegates every cryptographic operation to MDK / marmot-ts —
never reconstructing MLS by hand.
Driving it from the Build Studio
Section titled “Driving it from the Build Studio”Use the Build Studio to assemble the stack — pick your language (Rust via MDK, or TypeScript via marmot-ts), add the catalog entries above, and export a Goose recipe. Then run it in your own Goose, on your machine, with your own model and keys. The platform hands Goose a recipe; it never sees your keys or your messages.
Honest limitations
Section titled “Honest limitations”Choose your protocol by threat model
Section titled “Choose your protocol by threat model”Both Nostr (Marmot) and AT Protocol (Germ-style) approaches inherit MLS’s forward secrecy and post-compromise security. The real decision is about transport, ecosystem, and maturity — match it to your threat model, not to hype.
- Your users’ identities already live on Nostr; you value censorship-resistance and no phone/email. → Marmot / White Noise (Nostr). You get decentralized relays you choose and Nostr-native identity. Accept that it’s experimental and capped at ~150-member groups for now.
- Your users live on AT Protocol / Bluesky and you want E2EE there. → the AT Protocol path (e.g. Germ’s lexicon). This is an even earlier, separate ecosystem — and again, not wire-compatible with White Noise.
- You need audited, production-grade E2EE today, and decentralization is secondary. → Be honest with yourself and your users: a formally-audited messenger is the safer choice right now. Come to Marmot to build and contribute, or when decentralization and Nostr identity outweigh maturity.
Where to go next
Section titled “Where to go next”- Browse the verified building blocks in the catalog.
- Stand up your harness with Get started with Goose.
- Read the protocol itself: Marmot (and its MIPs), pinned at
commit
21a67b2.