OpenMLS v0.4 Release

Today, we are excited to announce the release of v0.4 of OpenMLS! πŸŽ‰

Some time has passed since we wrote about our roadmap to v0.4. In this post, we want to provide some insight into what has happened in the development of OpenMLS generally, but also relative to the goals we included in the roadmap.

Our high-level goal with v0.4 was to reach a state where we have an API stable enough and an implementation robust enough such that people interested in OpenMLS can start exploring it in the context of their own projects. However, this is not v1.0 and we can neither promise that the API won’t change in the future, nor do we advise using OpenMLS in production or indeed in any security-sensitive context. With this disclaimer out of the way, let’s see what has happened in these past months.

🎯 Milestones Reached

In our roadmap blog post, we documented a number of milestones that we were aiming for. Here is an overview of the milestones and how we reached them.

πŸ“œ High-Level API and Documentation

After a lot of clean-up and re-design, OpenMLS now exposes the MlsGroup API, a high-level API that allows an application to create and manage a group, as well as parse, process, and validate MLS messages. The new API comes with the following changes:

  • Major improvements to the documentation of the structs and functions we expose. The docs can be found here.
  • The way that errors are exposed by OpenMLS was completely refactored, such that callers can now usefully branch on the errors thrown by a function.
  • Members of a group are now addressed using their KeyPackageRef (a hash of the key material representing the member in a given group) rather than their index in the group’s ratchet tree. This change required a major refactoring effort throughout our code-base, mirroring the preceding effort made on the spec-level to better abstract away the tree underlying MLS.

πŸ“š User Manual

OpenMLS now has a user manual that contains guidance on how to use the MlsGroup API to perform MLS group operations, along with some explicit examples.

πŸ” Crypto Provider

With v0.4 comes the OpenMlsCryptoProvider trait, that in turn wraps three other traits:

  • the OpenMlsCrypto trait, on which OpenMLS relies for crypto implementations
  • the OpenMlsKeyStore trait, which can be used to store and retrieve cryptographic key material
  • the OpenMlsRand trait, which OpenMLS uses to generate randomness

OpenMLS provides two implementations of the OpenMlsCryptoProvider trait, one based on the evercrypt crypto provider and one on the Rust Crypto implementations. Both implementations rely on the rand_chacha crate for random number generation and a simple memory-based key store. See here for more information on the traits and their implementations.

With the traits in place, anyone can bring their own implementations to use with OpenMLS.

βš™οΈ Supported Platforms

OpenMLS is now compiled and tested for a number of 32 and 64-bit architectures:

OS Target Build Tests CI
🐧 x86_64-unknown-linux-gnu βœ… βœ… GitHub
🐧 i686-unknown-linux-gnu βœ… βœ… GitHub
πŸͺŸ x86_64-pc-windows-msvc βœ… βœ… GitHub
πŸͺŸ i686-pc-windows-msvc βœ… βœ… GitHub
🍎 x86_64-apple-darwin βœ… βœ… GitHub
🐧 aarch64-unknown-linux-gnu βœ… βœ…
🍎 aarch64-apple-darwin βœ… ❌ GitHub
🐧 aarch64-unknown-linux-gnu βœ… ❌ GitHub
πŸ€– aarch64-linux-android βœ… ❌ GitHub
🍎 aarch64-apple-ios βœ… ❌ GitHub
🍎 aarch64-apple-ios-sim βœ… ❌ GitHub
πŸ•ΈοΈ wasm32-unknown-unknown βœ… ❌ GitHub

πŸ’Œ Validation & Authorization

Making use of Rust’s strong type system, the CoreGroup layer underneath the MlsGroup API not only ensures that every incoming MLS message is syntactically and semantically validated according to the MLS spec, but also that messages created using the MlsGroup API fulfill these requirements. Before any messages are finally applied to a group, the API exposes the message to the application along with all information required to make its own policy decisions.

All validation steps are indexed and documented, as well as thoroughly tested.

πŸ—οΈ Still Not Finished: MLS Keeps Improving

For a while now, MLS has been β€œclose to a working group last call”, but as implementations have matured and academic research on the protocol has progressed, issues and improvement proposals have been steadily trickling in. As a result, at the time of release of OpenMLS v0.4, there is still no working group last call and no additional draft of the specification has been released. Consequently, v0.4 is not quite feature-complete, but advances the implementation to draft 12+.

πŸ§‘πŸΌβ€πŸ”§ More Improvements Under the Hood

To achieve all of the milestones listed above, OpenMLS has seen many improvements under the hood.

  • 🌳 TreeSync: The tree implementation supporting OpenMLS has been re-written in a style that allows a diff-merge process and that exposes a clear abstraction boundary between the ratchet tree and the rest of the implementation.
  • ⚠️ Errors: OpenMLS now uses the thiserror crate throughout. Instead of module-wide error types, every function now returns an error enum that contains only the errors that can actually occur during the course of the function.
  • 😱 Almost panic-free: Although not quite there yet, we have made a lot of progress in transitioning to a panic-free implementation, such that even in the event of an implementation bug we can ensure that OpenMLS functions will not panic.
  • ⏱️ Parallelization: The performance-critical functions of OpenMLS around the encryption of key material to other group members is now parallelized using the rayon crate.

πŸ’Ό Future Work

The MLS specification is still in motion and there are many things that need to be improved before we can move towards the next OpenMLS release. If you have a suggestion, please let us know by joining our Zulip instance or by filing an issue in our GitHub repo. Or send us an email at

πŸ’― Metrics

Here are some data points that give an overview of our activity since the release of the roadmap in October 2021.