Skip to content

SystemOperation

SystemOperation is the protocol/MLS operations envelope in Cryptid. It carries messages that change group state, cryptographic operations, and protocol-level events. NOT user-facing chat content.

We separate SystemOperation from CryptidMessage for:

  • Clarity of semantics:
    • Clients can treat CryptidMessage as “chat stuff” and SystemOperation as “protocol stuff”
    • Keeps UI and state machines cleaner
  • Different handling paths:
    • CryptidMessage goes to: decrypt -> store in message DB -> render in UI -> mabye sync reactions/edits
    • SystemOperation goes to: feed into MLS/group engine -> update permissions/metadata/address mappings -> maybe emit internal events
  • Security and robustness:
    • By having a distinct type, it’s easier to enforce “only MLS-validated, permission-checked commits can change group state”
    • Reject or quarantine bogus SystemOperation payloads without risking the chat message pipeline
  • UX isolation:
    • SystemOperation events are mostly invisible or minimally surfaced
    • Keeping them distinct avoids accidental exposing low-level events as messages
SystemOperation Structure
/// Protocol operation identifier (UUIDv7)
pub struct OperationId(Uuidv7);
/// Protocol/MLS operations envelope
struct SystemOperation {
// UUIDv7 for ordering/sequencing
operation_id: OperationId,
// Device that initiated this operation
sender: DeviceId,
// MLS group this applies to
group_id: GroupId,
// The actual operation
inner: SystemOperationInner,
}
  • operation_id
    • OperationId (wrapper around Uuidv7)
    • Unique identifier for this operation
    • Used for ordering and deduplication
  • sender
    • DeviceId of the device that created this operation
    • Authenticated by MLS group signature
    • Cannot be spoofed
  • group_id
    • GroupId this operation applies to
    • MUST be a valid MLS group
  • inner
    • SystemOperationInner enum variant
    • Determines the type of operation
SystemOperationInner Enum
enum SystemOperationInner {
// MLS commits and welcomes
MLSCommit {
proposals: Vec<Proposal>,
path: Vec<u8>,
},
MLSWelcome { welcome: Vec<u8> },
// Group context extension updates
GroupContextExtension {
permissions: Option<PermissionExtension>,
metadata: Option<GroupMetadataExtension>,
custom_media: Option<CustomMediaExtension>,
thread_metadata: Option<ThreadMetadataExtension>,
},
// Address rotation notification
AddressRotation {
old_addresses: Vec<DeliveryAddress>,
new_addresses: Vec<DeliveryAddress>,
},
// Epoch change notification
EpochChange { new_epoch: u64 },
}

Carries MLS commit messages that add or remove members from the group.

SystemOperationInner::MLSCommit {
proposals: Vec<Proposal>,
path: Vec<u8>,
}
  • proposals: List of proposals (Add, Remove, Update)
  • path: Commit path for ratchet tree updates
  • All commits MUST be validated against group permissions before processing
  • See MLS Integration for MLS details

Carries welcome messages for newly added members.

SystemOperationInner::MLSWelcome { welcome: Vec<u8> }
  • welcome: MLS welcome message ciphertext
  • Used to add new members to the group
  • Contains encrypted group state for the new member

Carries updates to group context extensions.

SystemOperationInner::GroupContextExtension {
permissions: Option<PermissionExtension>,
metadata: Option<GroupMetadataExtension>,
custom_media: Option<CustomMediaExtension>,
thread_metadata: Option<ThreadMetadataExtension>,
}
  • PermissionExtension:
    • Updates to group permissions (see Moderation Architecture)
    • Contains device_id -> Permission mappings
    • Cryptographically enforced via MLS group extensions
  • GroupMetadataExtension:
    • Updates to group name, description, picture
    • Contains group display information
  • CustomMediaExtension:
    • Updates to group’s custom emoji and sticker packs
    • Contains emoji definitions, sticker references
  • ThreadMetadataExtension:
    • Updates to thread metadata
    • Contains thread titles, settings

Notifies group members that a device has rotated its delivery addresses.

SystemOperationInner::AddressRotation {
old_addresses: Vec<DeliveryAddress>,
new_addresses: Vec<DeliveryAddress>,
}
  • old_addresses: Previous delivery addresses (for cleanup)
  • new_addresses: New delivery addresses (for routing)
  • Members update their routing tables accordingly
  • See Identity System for delivery address details

Notifies that the MLS epoch has changed.

SystemOperationInner::EpochChange { new_epoch: u64 }
  • new_epoch: New MLS epoch number
  • Clients update their local group state
  • Triggers key derivation for new epoch

  • Permission Enforcement:

    • Clients MUST verify sender has required permissions before accepting commits
    • Permission checks MUST use the MLS group extension (not local state)
    • Modified clients that skip verification are isolated from honest clients because they’ll brick their own state
  • Commit Validation:

    • All MLSCommit operations MUST be validated against group permissions
    • Unauthorized commits MUST be rejected
    • See Moderation Architecture
  • Message Handling:
    • SystemOperation messages MUST be processed before CryptidMessage messages
    • Group state changse affect message decryption
    • Clients MUST apply SystemOperations before processing messages in the same epoch
  • Ordering:
    • SystemOperation messages provide causal ordering within an epoch
    • Clients MUST process in MLS epoch order
    • Within same epoch, use operation_id for ordering
  • Enforcing UI display of system operations
  • Determining when to show “X joined the group” messages
  • Storing operation history
  • Reverting failed operations (MLS handles this)

{
"operation_id": "019e3eb4-2fbf-7863-9118-8c80709fdce1",
"sender": "admin-device-id",
"group_id": "group-uuid-v4",
"inner": {
"type": "MLSCommit",
"proposals": [
{
"type": "Add",
"new_member": "device-xyz"
}
],
"path": "base64encodedpath..."
}
}
{
"operation_id": "019e3eb4-2fbf-7863-9118-8c80709fdce1",
"sender": "admin-device-id",
"group_id": "group-uuid-v4",
"inner": {
"type": "GroupContextExtension",
"permissions": {
"device_permissions": {
"device-abc": 1,
"device-xyz": 2
},
"founder": "device-abc",
"version": 5
},
"metadata": null,
"custom_media": null,
"thread_metadata": null
}
}
{
"operation_id": "019e3eb4-2fbf-7863-9118-8c80709fdce1",
"sender": "device-xyz",
"group_id": "group-uuid-v4",
"inner": {
"type": "AddressRotation",
"old_addresses": [
{
"prefix": "oldaddress123",
"server": "chat.example.com"
}
],
"new_addresses": [
{
"prefix": "newaddress456",
"server": "chat.example.com"
}
]
}
}