Library / SDK
openmls/openmls avatar
openmls/openmls

OpenMLS: a Rust implementation of the MLS group messaging protocol

Rust implementation of the Messaging Layer Security (MLS) protocol

1,051 stars201 forksRustMIT

At a glance

What is it?
OpenMLS is a Rust library implementing the Messaging Layer Security protocol as specified in RFC 9420, with three ciphersuites, pluggable cryptography providers, pluggable storage backends including memory, SQLite and SQLx, a WebAssembly build, and a feature set that is deliberately small: extensions, fork resolution and the js target.
Who is it for?
OpenMLS suits a team building an end-to-end encrypted group messaging application that has decided to implement MLS rather than pick a hosted protocol, and that wants the cryptography delegated to an audited provider rather than implemented in house.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What OpenMLS is: the protocol, not the application

OpenMLS is a Rust implementation of the Messaging Layer Security protocol as specified in RFC 9420, and the README describes it as a software library that can serve as a building block in applications that require end-to-end encryption of messages. That framing sets the expectation. You get groups, epochs, key packages, proposals, commits and the state machine that ties them together, and you get an interface that hides the complexity of the underlying cryptographic operations. What you do not get is a transport, a client, a user interface or a key distribution service. The homepage is openmls.tech, the licence is MIT, the primary language is Rust, and the last push to the repository was on 2026-10-15. The documentation is split between an API reference on docs.rs and a book at book.openmls.tech, which is the more useful of the two for anyone trying to build on it.

Three ciphersuites, and the one marked MTI

The supported ciphersuites are listed in three lines and the notation is doing the work. MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 is marked MTI, which means it is the one a conforming implementation must support, the mandatory-to-implement suite of the specification. The other two are MLS_128_DHKEMP256_AES128GCM_SHA256_P256, using the NIST P-256 curve, and MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519, using ChaCha20-Poly1305 instead of AES-GCM. All three share the 128 bit security level, which is why they share the 128 prefix. The practical note is that a deployment has to pick one, and the choice is a compatibility decision as much as a performance one, because a client that only speaks one suite cannot talk to a group using another.

The cryptography is somebody else's problem, deliberately

OpenMLS does not implement its own cryptographic primitives. Instead it relies on existing implementations of the primitives used by MLS, and there are two cryptography providers implemented right now, but consumers can bring their own implementation, with the traits crate holding the details. The two providers in the tree are openmls_rust_crypto and libcrux_crypto. This is the right division of labour for a protocol implementation, because getting the primitives wrong is catastrophic and hard to review, while the protocol logic is what you actually need to be interoperable with. The cost is that you inherit a dependency and its security posture, and you have to make the choice deliberately rather than by default. The features list exposes the provider selection as a feature flag, so a build chooses one.

The feature set is small on purpose, and the developer flags are the honest part

Three features are listed for normal use. extensions-draft enables features defined in the MLS extensions draft, so the library can follow the specification as it grows rather than freezing at the RFC. fork-resolution provides helper functionality for resolving forks, which is the case where two members of a group have different views of the group state and the protocol has to bring them back together. And js enables compilation to wasm. Then there is a separate list under developer features, and this is where the interesting flags are. libcrux-provider and openmls_rust_crypto select the crypto provider, sqlite-provider selects the SQLite storage backend, backtrace enables backtraces, and two flags are worth noting for anyone doing development. content-debug allows printing sensitive content of messages for debugging, and crypto-debug allows printing cryptographic key material for debugging. Both are obviously dangerous in a production build, and both being explicit feature flags rather than a debug mode is the right design.

The workspace is a set of small crates, and the split tells you the architecture

The Cargo.toml is a workspace with fifteen members, and reading the list is the fastest way to understand the architecture. The core is openmls, with traits for the pluggable interfaces and openmls_test for the test utilities. Then there are the crypto providers, openmls_rust_crypto and libcrux_crypto, and the storage backends, memory_storage, sqlite_storage and sqlx_storage, the last of which is excluded from the workspace and built separately, which suggests a heavier dependency set. basic_credential supplies a simple credential type, serialization_helpers handles wire encoding, and the delivery-service directory holds a ds and a ds-lib crate, which is the message delivery service, the part of MLS that a group needs to exchange proposals. Then there is openmls-wasm for the browser build, an interop_client, a cli, and a fuzz directory. The workspace requires Rust 1.94.0.

The sync and async split runs through the whole crate

The workspace dependencies show a design decision that is easy to miss and expensive to discover late. The crate maybe-async is pinned to 0.2.11, and the comment says why, that 0.2.11 is the first version that rewrites -> impl Future returns in sync mode. So the same source serves both a synchronous API and an asynchronous one, and the library is written against the async version and transformed for the sync build. That is why openmls_async_tests exists as a separate crate alongside openmls_test, so both paths are exercised. The cost is that some APIs are awkward, and the benefit is that a consumer can pick the model that fits their application without waiting for the other one. For a messaging library, where the transport is likely to be async, that is a reasonable trade, but it is worth understanding before you design around it.

Platform coverage, maintenance and who stands behind it

OpenMLS is built and tested on GitHub CI for four Rust targets, x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc, aarch64-apple-darwin and aarch64-unknown-linux-gnu, and a further set is built but not tested, including i686, aarch64 Android and iOS, wasm32-unknown-unknown, and armv7 Android. The distinction between tested and merely built is the one to read, since a wasm target that compiles is not the same as a wasm target that has been exercised, and the browser build is a headline feature. The project supports 32 bit platforms and above. Maintenance is by Phoenix R&D and CE Labs, and the community runs on a Zulip chat with a Zulip Cloud Standard tier and a mailing list. The releases are v0.7.4 on 2026-03-02, v0.8.1 on 2026-02-13 and v0.9.0 on 2026-08-25, so the version is still in the zero series.

Editorial conclusion

OpenMLS suits a team building an end-to-end encrypted group messaging application that has decided to implement MLS rather than pick a hosted protocol, and that wants the cryptography delegated to an audited provider rather than implemented in house. It is the wrong choice if you need the protocol handled for you, since OpenMLS is a building block and not a client, and a poor fit if you need a storage backend other than the three provided, since adding one means implementing the storage traits. Before adopting it, read the user manual on the book site, check the ciphersuite list against your platform requirements, and note that the crypto provider is a separate choice with its own supply chain, because OpenMLS deliberately implements no cryptographic primitives of its own.

Frequently asked questions

What is OpenMLS?

It is a Rust implementation of the Messaging Layer Security protocol as specified in RFC 9420, described as a software library that can serve as a building block in applications requiring end-to-end encryption of messages, with a safe and easy-to-use interface that hides the complexity of the underlying cryptographic operations. The licence is MIT.

Which ciphersuites does OpenMLS support?

Three, all at the 128 bit security level. MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 is marked MTI, the mandatory-to-implement suite of the specification, alongside MLS_128_DHKEMP256_AES128GCM_SHA256_P256 and MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519.

Does OpenMLS implement its own cryptography?

No. It relies on existing implementations of the cryptographic primitives used by MLS. Two providers are implemented in the repository, openmls_rust_crypto and libcrux_crypto, and consumers can bring their own implementation through the traits crate.

What are the main features of OpenMLS?

extensions-draft enables features defined in the MLS extensions draft, fork-resolution provides helper functionality for resolving forks, and js enables compilation to wasm. There is also a set of developer features including the crypto provider selection, the sqlite-provider, backtrace, and the content-debug and crypto-debug flags that allow printing sensitive message content and key material.

Which platforms does OpenMLS build and test on?

It is built and tested on GitHub CI for x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc, aarch64-apple-darwin and aarch64-unknown-linux-gnu. The CI also builds but does not test i686, aarch64 Linux Android and iOS, wasm32-unknown-unknown and armv7 Android, and the project supports 32 bit platforms and above.

Official sources

  1. License: MIT
  2. openmls/openmls on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/openmls-openmls.svg)](https://hysenlabs.com/projects/openmls-openmls)

Was this useful?