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.
Why Separate from CryptidMessage
Section titled “Why Separate from CryptidMessage”We separate SystemOperation from CryptidMessage for:
- Clarity of semantics:
- Clients can treat
CryptidMessageas “chat stuff” andSystemOperationas “protocol stuff” - Keeps UI and state machines cleaner
- Clients can treat
- Different handling paths:
CryptidMessagegoes to: decrypt -> store in message DB -> render in UI -> mabye sync reactions/editsSystemOperationgoes 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
SystemOperationpayloads without risking the chat message pipeline
- UX isolation:
SystemOperationevents are mostly invisible or minimally surfaced- Keeping them distinct avoids accidental exposing low-level events as messages
SystemOperation Structure
Section titled “SystemOperation Structure”/// Protocol operation identifier (UUIDv7)pub struct OperationId(Uuidv7);
/// Protocol/MLS operations envelopestruct 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,}Field Specification
Section titled “Field Specification”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
innerSystemOperationInnerenum variant- Determines the type of operation
SystemOperationInner Structure
Section titled “SystemOperationInner Structure”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 },}SystemOperationInner Variants
Section titled “SystemOperationInner Variants”MLSCommit
Section titled “MLSCommit”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
MLSWelcome
Section titled “MLSWelcome”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
GroupContextExtension
Section titled “GroupContextExtension”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
AddressRotation
Section titled “AddressRotation”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
EpochChange
Section titled “EpochChange”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
Requirements
Section titled “Requirements”Security Requirements
Section titled “Security Requirements”-
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
Processing Requirements
Section titled “Processing Requirements”- 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
NOT Protocol Responsibilities
Section titled “NOT Protocol Responsibilities”- Enforcing UI display of system operations
- Determining when to show “X joined the group” messages
- Storing operation history
- Reverting failed operations (MLS handles this)
Example Operations
Section titled “Example Operations”Member Added
Section titled “Member Added”{ "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..." }}Group Permissions Updated
Section titled “Group Permissions Updated”{ "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 }}Address Rotation
Section titled “Address Rotation”{ "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" } ] }}