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-importfeature lets applications move existing group state to a storage provider using a different serde codec (e.g. bincode -> CBOR), via new import entry points onMlsGroupandPublicGroup. See Migrating from a previous version. - Targeted messages. Initial support for targeted messages, behind the new
targeted-messages-draftfeature flag. - Reworked
AppDataUpdateprocessing. BothMlsGroupandPublicGroupnow return commits carryingAppDataUpdateproposals asProcessedMessageContent::UnresolvedAppDataCommit, replacing the previousunprotect_message/process_unverified_message_with_app_data_updatesflow 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::OwnPendingCommitvariant. - #2109:
Capabilities::for_provider, plus dedicatedUnsupportedCiphersuiteerrors returned early when a provider doesn’t support a requested ciphersuite. - #2099:
ProcessedMessageContent::OwnPrivateMessagevariant for processing echoed-back own messages. - #2128: Storage-format migration helper (
migration-importfeature). - #2028: Targeted messages (
targeted-messages-draftfeature). - #2046, #2118: P-384, ML-DSA and additional PQ ciphersuites.
- #2037: Safe AAD capabilities from the extensions draft.
- #2045: Unchecked constructors to bypass
KeyPackage/LeafNodevalidation for already-verified input. - #2095:
AppDataUpdateproposals allowed in external commits; group-context getter onVerifiableGroupInfo. - #1979: Application data dictionary extension in key packages.
- #2113:
VcKeyPackageBatchBuilderfor virtual clients (experimental).
Changed
- #2149:
build_with_new_signernow always generates an UpdatePath, so the new signature key reaches the committer’s leaf. External commits take their credential solely fromExternalCommitBuilder::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
PublicGroupcreation now fail early withUnsupportedCiphersuiteinstead of failing deep in a crypto operation. - #1980: Enriched lifetime-related leaf node validation errors.
- #1972:
MlsGroup::max_past_epochs()now returnsOption<usize>. - #1963:
MessageEncryptionErroris now public (behindvirtual-clients-draft). - #2043: Renamed and deprecated
MlsGroup::propose_external_psktopropose_pre_shared_key(and the_by_valuevariant). - #2084: Renamed
StageCommitError::OwnCommittoOwnCommitMismatch. - #2099: Removed
ValidationError::CannotDecryptOwnMessage— processing an ownPrivateMessageis no longer an error. - #2060: Renamed the
extensions-draft-08feature flag toextensions-draft(across theopenmls,openmls_sqlite_storageandopenmls_sqlx_storagecrates). - #2092, #2098, #2099: Reworked the
AppDataUpdatereceive-side API onMlsGroupandPublicGroup(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
DeserializeBytesimpls. - #2143:
build_with_new_signernow signs the Welcome and exported GroupInfo with the new signer. Previously invited members rejected the Welcome withInvalidGroupInfoSignature. - #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’ssupports()now agrees withsupported_ciphersuites()forMLS_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
openmlsv0.7.1 and earlier is restored by default (0-8-1-storage-formatfeature keeps v0.8.1 compatibility). - #2125: A bare
GroupContextExtensionsproposal could bypass theAppDataUpdateimmutability check on theapp_data_dictionaryextension. - #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-08 → extensions-draft feature-flag rename from #2060 (an unstable/draft feature that was never part of a stable release):
openmls_traits0.6.0 (feature-flag rename, new PQ/virtual-clients/targeted-messages draft feature flags)openmls_memory_storage0.6.0 (feature-flag rename, new features)openmls_rust_crypto0.6.0openmls_libcrux_crypto0.4.0 (feature-flag rename, new features, fix)openmls_basic_credential0.6.0openmls_sqlite_storage0.3.0 (feature-flag rename, new features)openmls_sqlx_storage0.3.0 (feature-flag renameextensions-draft-08→extensions-draft)openmls_test0.3.0 (dev-only)openmls_serialization_helpers0.1.0 (new crate)
See each crate’s own CHANGELOG.md for details.