Abstract

This specification documents the use of Messaging Layer Security (MLS) in the ActivityPub API and protocol. MLS is a protocol for end-to-end encryption of 1-1 and group communications. ActivityPub is a federated social networking protocol. This specification describes how to use ActivityPub clients to exchange MLS-encrypted messages.

Introduction

Messaging Layer Security (MLS) [[rfc9420]] is an end-to-end encrypted messaging protocol. It is designed to work with different implementations in terms of "how protected messages are delivered, contents of protected messages, and identity/authentication infrastructures." [[rfc9750]]

[[ActivityPub]] is the W3C social networking standard. It defines an API for client to server interactions and a federation protocol for server to server communications. ActivityPub's native data format is Activity Streams 2.0 (AS2) [[activitystreams-core]], an extensible [[JSON-LD]] vocabulary for common social network objects and activities.

This document describes how ActivityPub can provide the Delivery Service, Authentication Service and extends the AS2 Activity Vocabulary for supporting the features specified in the MLS protocol. In short, ActivityPub servers need only extend support for federated key delivery. All other specified functions are implemented by ActivityPub clients:

Overview of the data structure

The data structure of an ActivityPub message that is end-to-end with MLS would be constructed by the client in the following way from creating the message, to enciphering, to sending:

  1. The encrypted message payload itself then follows ActivityPub post formats with AS2 that can then be rendered by the client.
  2. MLS as an encryption and signature layer for each message. The MLS message objects are embedded as base64-encoded binary objects within the ActivityPub JSON envelopes.
  3. ActivityPub as an envelope data structure, to ensure data routing, persistence, and federation across servers. The JSON envelopes are conveyed directly across the ActivityPub network.

The data structure of ActivityPub posts that support the group management layer of MLS (ActivityPub servers do not manage these objects, and are in fact unaware of their contents or interrelationships -- which is the point of end-to-end encryption, after all):

  1. A limited profile of Activity Streams 2.0 for representing messages and conversations (see application data). The embedded AS2 content objects are intentionally not compliant with ActivityPub rules for objects -- in particular, because object IDs in this profile are not HTTPS URLs, nor even dereferenceable URIs. These AS2 objects are embedded in the application_data fields of MLS PrivateMessage objects.
  2. MLS requires specific posts to be sent that are not messages but that carry information that the client needs in order to maintain cryptographic state of the group such as the formation of a group, adding and removing members of a group, and changes to the shared encryption keys for the group. These changes may or may not appear as system messsages to the users in the group chat. Crucially these messages are not encrypted.
  3. ActivityPub as an envelope data structure, to ensure data routing, persistence, and federation across servers. The JSON envelopes are conveyed directly across the ActivityPub network.

This document provides an overview of the interaction between MLS and ActivityPub and specifies requisite server extensions. However, this is not an implementation manual for MLS in ActivityPub clients. Instead, client implementers should be familiar with both MLS and ActivityPub before attempting an implementation of end-to-end encrypted messages between their users.

Delivery Service

The Delivery Service role in MLS has two main responsibilities:

Message delivery

ActivityPub provides a robust delivery mechanism for AS2 objects. To send an object to others on the network, a user POSTs a Create activity to their own outbox property with the addresses of the recipients in the to or cc properties. The sending actor's server adds an id property to the activity and the object and stores the object before forwarding it to the recipients across the federation protocol.

MLS data is structured in a binary format and includes detailed encryption and signature fields. For this reason, the MLS wire formats are preserved in AS2 objects with mediaType set to message/mls.

Each of the five MLS wire format structures has an equivalent data type defined as an AS2 extension in the MLS context: PublicMessage, PrivateMessage, Welcome, GroupInfo, and KeyPackage.

Because managing group membership is an essential part of the MLS protocol, delivery of MLS objects over the ActivityPub network requires addressing all recipients explicitly. Only actors can be recipients. Clients must not address MLS messages to collections, such as to the actor's followers collection or to the as:Public collection. See Privacy considerations for more details.

Reading incoming messages is done through the actor's inbox property. This is a collection of all activities received by the actor,including but not exclusive to activities related to MLS. ActivityPub does not support push notifications, so MLS-enabled ActivityPub clients have to periodically poll the inbox collection for new activities.

Other activities in the object lifecycle, such as reactions, updates, or deletions, should be handled as part of the application data within MLS private messages, and not as regular ActivityPub activities. So, for example, creating and updating an encrypted Note is modeled as two Create activities -- one for the creation, the second for the update.

Key storage

Each actor in the ActivityPub network has a public profile with important protocol properties defined, such as inbox, following, and preferredUsername.

The set of currently valid KeyPackage objects for an actor are an additional property of the actor object, keyPackages. Its value is an ActivityPub Collection of KeyPackage objects.

A KeyPackage object for an actor goes through 4 steps in its lifecycle:

  1. Create to create the object
  2. Add to add it to the collection of valid key packages
  3. Remove to remove it from the collection
  4. Delete to delete it and make it unavailable

Create and Add must occur in that sequence; it's not possible to add a KeyPackage before creating it. Removal and Deletion are less strictly ordered; a key package can be removed first and deleted later, or vice versa.

The generator property can be used to identify the client application associated with the KeyPackage.

As with all ActivityPub objects, the KeyPackage can be read in full using an HTTP GET request to the id URL.

Authentication Service

The Authentication Service in the MLS framework has the responsibility of confirming the relationship between a KeyPackage object and an identity. In ActivityPub, an identity is expressed as an actor object URL.

In the ActivityPub model shown here, authenticating a KeyPackage requires three steps:

  1. Retrieving the actor with the given ID; this requires an HTTP GET request to the actor ID URL.
  2. Verifying that the actor object has a keyPackages property.
  3. Confirming that the given KeyPackage object is an item in the keyPackages collection.

Application data

MLS is agnostic about application data encrypted and sent over the network. To match the ActivityPub model, this specification defines the application data for use over MLS as Activity Streams 2.0 content objects and activities. Unlike ActivityPub objects, these AS2 objects are not available for download from any server, and do not use HTTPS URLs as id values.

In general, the content of the MLS messages should be self-encapsulated and not dependent on external resources. Client applications cannot rely on a server to save state for the group and the shared application data. This restricts the use of URLs and Link objects in the content.

Content objects

The Activity Vocabulary defines several document types for content. The following types are used in this specification.

There are the following restrictions on the properties of the content objects:

Examples

Activities

Activities are the top-level content in MLS messages.

The following Activity types from the Activity Vocabulary are defined in this document.

Examples

Extensions

Other activity or content types from the Activity Vocabulary, and from Activity Streams 2.0 extensions, may be used in this structure. The use of extended properties or types in the encrypted content of MLS over ActivityPub should be documented on the W3C wiki.

Context

The terms in this document are defined in a context document that can be used in [[JSON-LD]] documents. The context document is available at https://purl.archive.org/socialweb/mls.

To use these terms, documents should include this context URL in the @context property of the JSON-LD document.

The context document defines a namespace prefix mls defined as https://purl.archive.org/socialweb/mls#.

Version-stamped URLs

To ease the use of this context for implementers with strict versioning requirements, additional URL aliases are provided with versions included. A semantic versioning strategy is used to convey the guarantees of the version number.

Version URL Notes
(latest) https://purl.archive.org/socialweb/mls The latest version of the context is always available at this URL. Most implementers can use this URL.
1.0.0 https://purl.archive.org/socialweb/mls/1.0.0 The exact version of the context document. The resource at this URL should be immutable. This URL is useful for implementers that need an exact, byte-wise replicable version of the document.
1.0.x https://purl.archive.org/socialweb/mls/1.0 Backwards-compatible fixes are possible, but no additional types or properties are defined. This is useful for implementers that use multiple extensions and want to ensure that no conflicting terms are added.
1.x.x https://purl.archive.org/socialweb/mls/1 Backwards-compatible fixes, additional types and properties are possible. This is useful for implementers that want to ensure that the properties and types they use are stable and will not change, but do not need to avoid term conflicts.

Using the version-stamped context URLs is similar to the unstamped URL.

If backwards-incompatible changes to this context are made in the future, a new major version (2.x.x) would be added and the existing 1.x.x URLs would continue to be provided.

Terms

These terms are defined in the MLS namespace for ActivityPub. There are five new object types, and one new property.

Types

There are five types defined in this context.

PublicMessage

URI: https://purl.archive.org/socialweb/mls#PublicMessage
mls:PublicMessage
PublicMessage
Notes:

The PublicMessage data type from MLS. The mediaType should be "message/mls", and the content should be base64-encoded binary data matching an MLSMessage structure with a PublicMessage wire type.

Extends: Object
Properties: Inherited from Object

PrivateMessage

URI: https://purl.archive.org/socialweb/mls#PrivateMessage
mls:PrivateMessage
PrivateMessage
Notes:

The PrivateMessage data type from MLS. The mediaType should be "message/mls", and the content should be base64-encoded binary data matching an MLSMessage structure with a PrivateMessage wire type.

Extends: Object
Properties: Inherited from Object

KeyPackage

URI: https://purl.archive.org/socialweb/mls#KeyPackage
mls:KeyPackage
KeyPackage
Notes:

The KeyPackage data type from MLS. The mediaType should be "message/mls", and the content should be base64-encoded binary data matching an MLSMessage structure with a KeyPackage wire type.

Extends: Object
Properties: Inherited from Object

GroupInfo

URI: https://purl.archive.org/socialweb/mls#GroupInfo
mls:GroupInfo
GroupInfo
Notes:

The GroupInfo data type from MLS. The mediaType should be "message/mls", and the content should be base64-encoded binary data matching an MLSMessage structure with a GroupInfo wire type.

Extends: Object
Properties: Inherited from Object

Welcome

URI: https://purl.archive.org/socialweb/mls#Welcome
mls:Welcome
Welcome
Notes:

The Welcome data type from MLS. The mediaType should be "message/mls", and the content should be base64-encoded binary data matching an MLSMessage structure with a Welcome wire type.

Extends: Object
Properties: Inherited from Object

Properties

There are two properties defined in the namespace.

encoding

URI: https://purl.archive.org/socialweb/mls#encoding
mls:encoding
encoding
Notes:

The encoding property represents the encoding for the content property, similar to the Content-Transfer-Encoding header in email and HTTP messages.

Domain: Object
Range: String; values for Content-Transfer-Encoding in [[rfc2045]]
Functional: true

keyPackages

URI: https://purl.archive.org/socialweb/mls#keyPackages
mls:keyPackages
keyPackages
Notes:

The keyPackages property represents the client keys for an actor. As with other JSON-LD @id properties, its value can be a string for the URL of the key, a JSON object with the properties of the key itself, or an array of strings and/or objects.

Domain: Object (an ActivityPub Actor)
Range: Key
Functional: false

messages

URI: https://purl.archive.org/socialweb/mls#messages
mls:messages
messages
Notes:

The value of the messages property is an OrderedCollection of all the MLS-related activities that an actor has received in their inbox. Like the inbox, it is sorted in reverse chronological order (latest activities first).

Without this property, the messaging client needs to scan the inbox for messaging-related activities.

Domain: Object (an ActivityPub Actor)
Range: OrderedCollection
Functional: true

Security considerations

These are notable security considerations with this specification.

HTML Sanitization

Many of the content types included in the application data for this specification use HTML either for the summary or content properties. Attackers can use features of HTML5, like JavaScript and CSS, to cause problems in the users' browsers. One mitigation is to sanitize the HTML, removing elements and attributes that can be problematic for users.

In ActivityPub, many servers will sanitize HTML for content as it arrives at the server, so that clients can use the content without security concerns. Because the encrypted application data in this specification is not visible to the ActivityPub server, it is up to the client application to sanitize the HTML.

Key Substitution

The keyPackages collection used in this document for sharing and confirming cryptographic keys is easy to implement and use. However, because the collection is managed by the actor's server, the collection is subject to a key substitution attack. A malicious server can add one of its own keys to the collection, or replace one of the keys with its own. Sophisticated attackers would present different keyPackages collection contents to different clients.

One mitigation for this attack is key-fingerprint verification, in which participants in a group compare the fingerprints they see for keys for an identity.

Private key storage

The private keys created by clients and used for encryption and signatures in the MLS framework are crucial to the security of the system. Compromise of the key through physical or remote access to the device could expose encrypted data in the server-stored messages. To mitigate this risk, client applications should make use of platform services for secure key storage where available. If keys must be stored on disk, they should be encrypted with a password under the user's control.

Plaintext storage

Rebuilding group state and decrypted message content from server-stored MLS message data in the inbox can be time-consuming. Therefore, many clients will persist that state and decrypted content on the client side. But physical or remote access to the client device could expose that decrypted content to an attacker.

One mitigation for this risk is to store decrypted content locally in an encrypted file or drive volume, with the encryption key stored in the platform's secure storage, or with a password under the user's control.

Privacy considerations

Metadata leakage

The binary MLS objects used in this specification have strong encryption to protect the contents from servers. The ActivityPub envelopes used for their delivery, however, can be inspected by servers along the delivery path -- the sending actor's server and the receiving actors' servers.

There is metadata in the envelopes that can be used by an observer to draw conclusions about the conversations.

Changelog