Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/openmls/openmls/llms.txt

Use this file to discover all available pages before exploring further.

PublicGroup holds all public values of an MLS group and enables tracking of group membership and state based on PublicMessages, without requiring private key material. This is useful for delivery services and observers.

Overview

The PublicGroup struct allows tracking an MLS group’s public state, including:
  • Group membership and the ratchet tree
  • Proposal store for pending proposals
  • Group context and configuration
  • Validation of commits and proposals
Internally, MlsGroup relies on a PublicGroup for its public state management.

Creating a public group

from_external

Creates a PublicGroup instance to start tracking an existing MLS group from external information.
crypto
&impl OpenMlsCrypto
Cryptographic provider for validation
storage
&StorageProvider
Storage provider for persisting the group state
ratchet_tree
RatchetTreeIn
The ratchet tree to initialize from
verifiable_group_info
VerifiableGroupInfo
Group info for initializing the group context
proposal_store
ProposalStore
Initial proposal store (typically empty)
Result
Result<(PublicGroup, GroupInfo), CreationFromExternalError>
Returns the public group and verified group info, or an error if validation fails
let (public_group, group_info) = PublicGroup::from_external(
    provider.crypto(),
    provider.storage(),
    ratchet_tree,
    verifiable_group_info,
    ProposalStore::new(),
)?;
This function performs comprehensive validation including:
  • Leaf node validation (ValSem1407)
  • Signature key uniqueness (ValSem0111)
  • Encryption key uniqueness (ValSem0112)
  • Tree hash verification (ValSem1405)
  • Group info signature validation (ValSem1402)

Group information

group_id

Returns the group ID.
GroupId
&GroupId
Reference to the group ID
let id = public_group.group_id();

group_context

Returns the group context containing epoch, tree hash, and extensions.
GroupContext
&GroupContext
Reference to the group context
let context = public_group.group_context();
let epoch = context.epoch();
let tree_hash = context.tree_hash();

ciphersuite

Returns the ciphersuite used by the group.
Ciphersuite
Ciphersuite
The group’s ciphersuite

version

Returns the MLS protocol version.
ProtocolVersion
ProtocolVersion
The protocol version

confirmation_tag

Returns the most recent confirmation tag.
ConfirmationTag
&ConfirmationTag
Reference to the confirmation tag

Membership

members

Returns an iterator over all members of the group.
Iterator
impl Iterator<Item = Member>
Iterator over group members, each containing index, credential, encryption key, and signature key
for member in public_group.members() {
    println!("Member {}: {:?}", member.index.u32(), member.credential);
}

leaf

Returns the leaf node at a given index.
leaf_index
LeafNodeIndex
The index of the leaf to retrieve
Option
Option<&LeafNode>
The leaf node if present, None if the leaf is blank
if let Some(leaf_node) = public_group.leaf(leaf_index) {
    println!("Credential: {:?}", leaf_node.credential());
}

treesync

Returns the current tree state.
TreeSync
&TreeSync
Reference to the tree sync state

export_ratchet_tree

Exports the nodes of the public tree.
RatchetTree
RatchetTree
The exported ratchet tree
let tree = public_group.export_ratchet_tree();

Proposal management

add_proposal

Adds a queued proposal to the internal proposal store.
storage
&Storage
Storage provider
proposal
QueuedProposal
The proposal to add
Result
Result<(), Storage::Error>
Returns () on success
public_group.add_proposal(provider.storage(), queued_proposal)?;

remove_proposal

Removes a proposal from the internal proposal store.
storage
&Storage
Storage provider
proposal_ref
&ProposalRef
Reference to the proposal to remove
Result
Result<(), Storage::Error>
Returns () on success

queued_proposals

Returns all queued proposals from storage.
storage
&Storage
Storage provider
Result
Result<Vec<(ProposalRef, QueuedProposal)>, Storage::Error>
Vector of proposal references and their corresponding proposals
let proposals = public_group.queued_proposals(provider.storage())?;
for (proposal_ref, proposal) in proposals {
    // Process proposal
}

Commit processing

merge_commit

Merges a staged commit into the public group state.
storage
&Storage
Storage provider
staged_commit
StagedCommit
The staged commit to merge
Result
Result<(), MergeCommitError>
Returns () on success
public_group.merge_commit(provider.storage(), staged_commit)?;
This operation:
  • Applies the commit’s changes to the tree
  • Updates the group context
  • Clears the proposal store
  • Persists the new state

Storage operations

load

Loads a PublicGroup from storage.
storage
&Storage
Storage provider
group_id
&GroupId
ID of the group to load
Result
Result<Option<PublicGroup>, Storage::Error>
Returns the group if found, None if not found
if let Some(group) = PublicGroup::load(provider.storage(), &group_id)? {
    // Use the public group
}

delete

Deletes a PublicGroup from storage.
storage
&Storage
Storage provider
group_id
&GroupId
ID of the group to delete
Result
Result<(), Storage::Error>
Returns () on success
PublicGroup::delete(provider.storage(), &group_id)?;

Advanced operations

derive_path_secrets

Derives encryption keypairs for nodes in the shared direct path between two leaves.
crypto
&impl OpenMlsCrypto
Cryptographic provider
ciphersuite
Ciphersuite
The ciphersuite to use
path_secret
PathSecret
The path secret to derive from
sender_index
LeafNodeIndex
Index of the sender
leaf_index
LeafNodeIndex
Index of the target leaf
Result
Result<(Vec<EncryptionKeyPair>, CommitSecret), DerivePathError>
Returns the derived keypairs and commit secret, or an error if the derived keys don’t match existing ones

ext_commit_sender_index

Returns the index of the sender of a staged external commit.
commit
&StagedCommit
The staged commit
Result
Result<LeafNodeIndex, LibraryError>
The sender’s leaf index

required_capabilities

Returns the required capabilities extension if present in the group context.
Option
Option<&RequiredCapabilitiesExtension>
Optional reference to the required capabilities
if let Some(required_caps) = public_group.required_capabilities() {
    // Check capabilities
}

Use cases

The PublicGroup API is designed for:

Delivery service tracking

// Track group membership without private keys
let (public_group, _) = PublicGroup::from_external(
    crypto,
    storage,
    ratchet_tree,
    verifiable_group_info,
    ProposalStore::new(),
)?;

// Monitor membership changes
for member in public_group.members() {
    delivery_service.register_member(member.index, member.credential);
}

Group state observation

// Track epochs and context changes
let context = public_group.group_context();
println!("Current epoch: {}", context.epoch().as_u64());
println!("Tree hash: {:x?}", context.tree_hash());

Proposal validation

// Track proposals without processing them
let proposals = public_group.queued_proposals(storage)?;
for (_, proposal) in proposals {
    match proposal.proposal() {
        Proposal::Add(_) => println!("Add proposal pending"),
        Proposal::Remove(_) => println!("Remove proposal pending"),
        _ => {}
    }
}