Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

0.9.0 (2026-08-25)

Highlights

  • Storage. Non-self describing storage formats are officially not supported anymore in OpenMLS starting with this release.
  • Storage migration helper. A new opt-in migration-import feature lets applications move existing group state to a storage provider using a different serde codec (e.g. bincode -> CBOR), via new import entry points on MlsGroup and PublicGroup. See Migrating from a previous version.
  • Targeted messages. Initial support for targeted messages, behind the new targeted-messages-draft feature flag.
  • Reworked AppDataUpdate processing. Both MlsGroup and PublicGroup now return commits carrying AppDataUpdate proposals as ProcessedMessageContent::UnresolvedAppDataCommit, replacing the previous unprotect_message/process_unverified_message_with_app_data_updates flow that exposed unverified content.
  • MSRV raised to Rust 1.91.

Added

  • #1972: APIs for time-based deletion of past epoch secrets, and for setting the past epoch deletion policy for an MlsGroup.
  • #2010: MlsGroup::propose_self_update_with_new_signer.
  • #2084: ProcessedMessageContent::OwnPendingCommit variant.
  • #2109: Capabilities::for_provider, plus dedicated UnsupportedCiphersuite errors returned early when a provider doesn’t support a requested ciphersuite.
  • #2099: ProcessedMessageContent::OwnPrivateMessage variant for processing echoed-back own messages.
  • #2128: Storage-format migration helper (migration-import feature).
  • #2028: Targeted messages (targeted-messages-draft feature).
  • #2046, #2118: P-384, ML-DSA and additional PQ ciphersuites.
  • #2037: Safe AAD capabilities from the extensions draft.
  • #2045: Unchecked constructors to bypass KeyPackage/LeafNode validation for already-verified input.
  • #2095: AppDataUpdate proposals allowed in external commits; group-context getter on VerifiableGroupInfo.
  • #1979: Application data dictionary extension in key packages.
  • #2113: VcKeyPackageBatchBuilder for virtual clients (experimental).

Changed

  • #2149: build_with_new_signer now always generates an UpdatePath, so the new signature key reaches the committer’s leaf. External commits take their credential solely from ExternalCommitBuilder::build_group, with new errors for a mismatched credential or a new signer.
  • #2174: Faster duplicate and membership checks during validation (hash sets, binary search for unmerged leaves). No API change.
  • #2109: Group/key-package creation, welcome processing, external commits and PublicGroup creation now fail early with UnsupportedCiphersuite instead of failing deep in a crypto operation.
  • #1980: Enriched lifetime-related leaf node validation errors.
  • #1972: MlsGroup::max_past_epochs() now returns Option<usize>.
  • #1963: MessageEncryptionError is now public (behind virtual-clients-draft).
  • #2043: Renamed and deprecated MlsGroup::propose_external_psk to propose_pre_shared_key (and the _by_value variant).
  • #2084: Renamed StageCommitError::OwnCommit to OwnCommitMismatch.
  • #2099: Removed ValidationError::CannotDecryptOwnMessage — processing an own PrivateMessage is no longer an error.
  • #2060: Renamed the extensions-draft-08 feature flag to extensions-draft (across the openmls, openmls_sqlite_storage and openmls_sqlx_storage crates).
  • #2092, #2098, #2099: Reworked the AppDataUpdate receive-side API on MlsGroup and PublicGroup (see Highlights above).
  • #2083: Raised MSRV to Rust 1.91.

Fixed

  • #2186: Fix wrong computation of tree node indexes when provided invalid inputs, which could let a commit from a sender outside the tree be accepted.
  • GHSA-rrmv-c79f-cf5r: Fix out-of-bounds panic in manual DeserializeBytes impls.
  • #2143: build_with_new_signer now signs the Welcome and exported GroupInfo with the new signer. Previously invited members rejected the Welcome with InvalidGroupInfoSignature.
  • #2147: Fix an off-by-one in the variable-length prefix size during extension serialization.
  • #2134: Known structured extension payloads now reject trailing bytes during decoding.
  • #2109: OpenMlsRustCrypto’s supports() now agrees with supported_ciphersuites() for MLS_256_MLKEM1024_AES256GCM_SHA512_MLDSA87.
  • #2089: A Commit without an UpdatePath from this client’s own leaf that doesn’t match the pending commit is now staged normally instead of rejected.
  • #2034: Fixed incorrect storage-format deserialization caused by changed integer storage tags; storage-format compatibility with openmls v0.7.1 and earlier is restored by default (0-8-1-storage-format feature keeps v0.8.1 compatibility).
  • #2125: A bare GroupContextExtensions proposal could bypass the AppDataUpdate immutability check on the app_data_dictionary extension.
  • #2051: Backward-incompatible deserialization of PastEpochDeletionPolicy.

Supporting crates

None of these contain breaking changes to their own stable public APIs — all additive (new PQ ciphersuite support, virtual-clients-draft storage plumbing) or internal fixes. Several also carry the extensions-draft-08extensions-draft feature-flag rename from #2060 (an unstable/draft feature that was never part of a stable release):

  • openmls_traits 0.6.0 (feature-flag rename, new PQ/virtual-clients/targeted-messages draft feature flags)
  • openmls_memory_storage 0.6.0 (feature-flag rename, new features)
  • openmls_rust_crypto 0.6.0
  • openmls_libcrux_crypto 0.4.0 (feature-flag rename, new features, fix)
  • openmls_basic_credential 0.6.0
  • openmls_sqlite_storage 0.3.0 (feature-flag rename, new features)
  • openmls_sqlx_storage 0.3.0 (feature-flag rename extensions-draft-08extensions-draft)
  • openmls_test 0.3.0 (dev-only)
  • openmls_serialization_helpers 0.1.0 (new crate)

See each crate’s own CHANGELOG.md for details.