Encryption and identity

How do you use MLS (RFC 9420) for group messaging on mobile?

To use MLS on mobile, you run an implementation of RFC 9420 on each phone and supply the parts MLS leaves to the application. Those are a way to publish and fetch key packages, a delivery path, a rule for ordering group changes, credential checks and durable storage for group state. MLS then gives the group a shared key that changes as members join, leave or update, with forward secrecy and post-compromise security.

Learning objectives

After reading this article you will be able to:

  • List the parts MLS leaves to your app, from key package directory to commit ordering
  • Compare OpenMLS and mls-rs on mobile testing and audit status
  • Explain what phones change for MLS, such as durable state, key deletion and idle devices

What MLS does for you

Messaging Layer Security, published by the IETF as RFC 9420, is a protocol for agreeing a shared key across a group whose members may not be online at the same time. The RFC describes it as providing forward secrecy and post-compromise security for groups ranging from two members to thousands. See the MLS glossary entry for a short definition.

A group moves through a series of epochs. Each epoch has its own keys, derived from a ratchet tree that represents the membership. Four message types drive it:

  • KeyPackage. A signed object a client publishes in advance, carrying a public key others can use to add it to a group.
  • Proposal. A suggested change, such as adding, removing or updating a member.
  • Commit. A message that applies a set of proposals and starts the next epoch.
  • Welcome. What a new member receives so it can set up its state for the epoch it joined.

Every client must implement the mandatory cipher suite MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, which uses X25519 for key exchange, AES-128-GCM, SHA-256 and Ed25519 signatures.

What MLS leaves to your app

MLS defines the cryptography and the messages, not the service around them. RFC 9420 assumes two services exist, and RFC 9750 describes them in detail.

  • A key package directory. Clients publish KeyPackages so others can add them. RFC 9750 says each KeyPackage is meant to be used only once, to avoid replay and keep forward secrecy, with an optional “last resort” package that should be rotated soon after use. A phone needs to keep enough fresh packages available.
  • A Delivery Service. Something has to route messages between members. It can be a server, or, as RFC 9750 notes, a peer-to-peer network that carries MLS messages.
  • An Authentication Service. Something has to decide which key belongs to which person or device. RFC 9750 recommends credentials that bind identity and key strongly, such as X.509, over the basic credential type, which has no built-in binding.
  • A rule for ordering commits. Two members can send a Commit for the same epoch at once. RFC 9420 says applications must have an established way to resolve that, either by preventing it or by deciding which Commit is canonical.

Choosing an implementation

MLS is a long and detailed specification, so a maintained library, wrapped for your app’s platform, is usually safer than writing your own.

  • OpenMLS describes itself as a Rust implementation of MLS as specified in RFC 9420. Its README lists the targets it builds and tests on CI. Android and iOS targets are listed as built but not tested, so on a phone you own the testing.
  • mls-rs, from AWS Labs, describes itself as an implementation of RFC 9420. Its README states that it has been validated for conformance to the specification but has not yet had a full third-party security audit, and it lists several crypto providers, including one based on Apple’s CryptoKit.

Both are written for Rust, so a React Native, Swift or Kotlin app reaches them through a native binding layer that you build or adopt.

What changes on a phone

Phones are switched off, out of range or asleep for long periods, and they get restored from backups. Several points from the two RFCs matter more there than on a server:

  • Store state carefully. Group state must be saved durably and updated as one step. RFC 9420 adds a random reuse_guard value to each encrypted message to avoid nonce reuse if a client loses or corrupts its state, which a restore from an old backup can cause.
  • Delete old keys. Forward secrecy only holds if a client deletes keys as soon as they have been used. RFC 9420 also requires apps to keep old or forked group states only as long as they need them.
  • Handle idle devices. RFC 9750 warns that a client which stays offline keeps old keying material, which undermines forward secrecy and post-compromise security if that device is later compromised. It recommends requiring key updates from quiet clients and removing clients that are idle for too long.
  • Treat each device as its own member. A person with a phone and a tablet is two MLS clients, each with its own keys.
  • Mind metadata. MLS encrypts application messages, but RFC 9750 assumes the transport keeps metadata private and recommends one that does, such as TLS or QUIC, when there is a network.

Running MLS without a central server

On a local mesh, there may be no server to put commits in order. RFC 9750 calls this an eventually consistent Delivery Service: messages can arrive in different orders, and clients must reconcile them. It suggests clients wait briefly after a Commit to see whether a competing one arrives, then pick a winner with a deterministic tie-breaking rule. The alternative, which RFC 9750 calls strongly consistent, trusts one party to put changes in a single order and break ties between competing Commits.

The choice resembles sync conflict resolution, with one difference: every member must reach the same answer, or the group splits into members who can no longer read each other. For the wider picture of keys and trust with no server, see how end-to-end encryption works without a server.

Frequently asked questions

Do all members need to be online for MLS to work?

No. RFC 9750 notes that no MLS operation requires two members to be online at the same time. When members who were away reconnect, they process the group changes they missed.

Is MLS only for large groups?

No. RFC 9420 describes it as covering groups ranging from two members to thousands, so the same protocol can protect one-to-one conversations and large groups.

Sources

Build it with Offline Protocol

The Offline Protocol mesh SDK for React Native creates MLS groups, invites and removes members and encrypts group messages through its own methods. The groups reference lists each method and the events it emits.

Read the groups reference