Abstract

The ActivityPub protocol is a social networking protocol based upon the ActivityStreams 2.0 data format. It is based upon experience gained from implementing and working with the OStatus and Pump.io protocols.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document is a proposed submission to the W3C Social working group.

This document was published by the Social Web Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-socialweb@w3.org (subscribe, archives). All comments are welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

1. Overview

The ActivityPub protocol is broadly based on the distribution of activities, described using [ActivityStreams]; these activities are produced in response to a user performing an activity. Most activities are purely responsive in nature - they are produced as a response to a user having done something. In addition, certain activities posted by a user to their outbox may trigger certain operations on the user's behalf. Finally, activities may have side effects as they propagate throughout the social graph. As an example of this:

  1. A user posts the like activity to their outbox. This activity causes the user's server to perform an activity on behalf of the user; in particular, it adds the specified object to the collection of objects the user has liked.
  2. A consequence of the above activity (per 8.1 Targeting) is that the server hosting the liked object will be notified of the operation, and will normally add the activity to the list of "likes" the object has received.
  3. Finally, the server receiving the like will distribute this activity to everyone it distributed the original object to.

1.1 Social Web Working Group

ActivityPub is one of several related specifications being produced by the Social Web Working Group. Implementers interested in alternative approaches and complementary protocols should review Micropub and the overview document Social Web Protocols.

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, REQUIRED, SHALL, SHALL NOT, SHOULD, and SHOULD NOT are to be interpreted as described in [RFC2119].

Conformance

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", " SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

2.1 Specification Profiles

This specification defines two closely related and interacting protocols:

A client to server protocol, or "Social API"
This protocol permits a client to act on behalf of a user. For example, this protocol is used by a mobile phone application to interact with the user's social stream.
A server to server protocol, or "Federation Protocol"
This protocol is used to distribute activities between users on different servers, tying them into one social graph.

All servers claiming conformance to this specification are required to implement the former protocol, and may optionally implement the latter. This gives three conformance classes:

ActivityPub conformant Client
This designation applies to any implementation of the entirety of the client portion of the client to server protocol.
ActivityPub conformant Server
This designation applies to any implementation of the entirety of the server portion of the client to server protocol.
ActivityPub conformant Federated Server
This designation applies to any implementation of the entirety of the server portion of both the client to server and federation protocols.

It is called out whenever a portion of the specification only applies to implementation of the federation protocol. In addition, whenever requirements are specified, it is called out whether they apply to the client or server (for the client-to-server protocol) or which of a pair of servers in the server-to-server protocol.

2.2 Candidate Recommendation Exit Criteria

For this specification to advance to Proposed Recommendation, there must be at least two independent, interoperable implementations of each feature. Each feature may be implemented by a different set of products. There is no requirement that all features be implemented by a single product.

For the purposes of evaluating exit criteria, each of the following is considered a feature:

2.3 At Risk features

The Working Group has marked the following features as At Risk and may seek to advance the specification with the removal of these features if insufficient implementation experience can be gathered.

3. Objects

Objects are the core concept around which both [ActivityStreams] and ActivityPub are built. Objects are often wrapped in Activities and are contained in streams of Collections, which are themselves subclasses of Objects. See the ActivityStreams Vocabulary document, particularly the Core Classes, to get a sense of how this lays out; ActivityPub follows the mapping of this vocabulary very closely.

ActivityPub defines some terms in addition to those provided by ActivityStreams. These terms are provided in the ActivityPub JSON-LD context at https://www.w3.org/ns/activitypub. Implementers SHOULD include the ActivityPub context in their object definitions. Implementers MAY include additional context as appropriate.

Servers SHOULD validate the content they receive to avoid content spoofing attacks. In particular, servers SHOULD NOT trust client submitted content, and federated servers also SHOULD NOT trust content received from a server other than the content's origin without some form of verification. No particular mechanism for verification is authoritively specified by this document, though some possible directions are discussed in 9. Authentication and Authorization. (A server should do something at least as robust as checking that the object appears as received at its origin, but better mechanisms such as checking signatures would be better if available.)

As an example, if example.com receives the activity
Example 1
{
  "@context": "https://www.w3.org/ns/activitypub",
  "type": "Like",
  "actor": "https://example.net/~mallory",
  "to": ["https://hatchat.example/sarah/",
         "https://example.com/peeps/john/"],
  "object": {
    "@context": {"@language": "en"},
    "id": "https://example.org/~alice/note/23",
    "type": "Note",
    "author": "https://example.org/~alice",
    "content": "I'm a goat"
  }
}
it should dereference the id both to ensure that it exists and is a valid object, and that it is not misrepresenting the object. (In this example, Mallory could be spoofing an object allegedly posted by Alice.)

3.1 Object Identifiers

All Objects in [ActivityStreams] should have unique global identifiers. ActivityPub extends this requirement; all objects distributed by the ActivityPub protocol MUST have unique global identifiers; these identifiers must fall into one of the following groups:

  1. Publicly dereferencable URIs, such as HTTPS URIs, with their authority belonging to that of their originating server. (Publicly facing content SHOULD use HTTPS URIs.)
  2. An ID explicitly specified as the JSON null object, which implies an anonymous object (a part of its parent context)

Identifiers MUST be provided for activities posted in server to server communication. However, for client to server communication, a server receiving an object with no specified id SHOULD allocate an object ID in the user's namespace and attach it to the posted object.

All objects must have the following properties:

id
The object's unique global identifier
type
The type of the object

3.2 Methods on objects

The HTTP GET method may be dereferenced against an object's id property to retrieve the activity. Servers MAY use HTTP content negotiation as defined in [RFC7231] to select the type of data to return in response to a request, but MUST present the ActivityStreams object representation in response to application/ld+json; profile="https://www.w3.org/ns/activitystreams#", and SHOULD also present the ActivityStreams representation in response to application/activity+json as well. The client MUST specify an Accept header with the application/ld+json; profile="https://www.w3.org/ns/activitystreams#" media type in order to retrieve the activity.

Servers MAY implement other behavior for requests which do not comply with the above requirement. (For example, servers may implement additional legacy protocols, or may use the same URI for both HTML and ActivityStreams representations of a resource)

Servers MAY require authorization as specified in 9. Authentication and Authorization, and may additionally implement their own authorization rules. Servers SHOULD fail requests which do not pass their authorization checks with the appropriate HTTP error code, or the 404 Not Found error code where the existence of the object is considered private.

3.3 The source property

In addition to all the properties defined by the ActivityStreams Vocabulary, ActivityPub extends the Object by supplying the source property. The source property is intended to convey some sort of source from which the content markup was derived, as a form of provenance, or to support future editing by clients. In general, clients do the conversion from source to content, not the other way around.

The value of source is itself an object which uses its own content and mediaType fields to supply source information.

Example 2
{
  "@context": "https://www.w3.org/ns/activitypub",
  "object": "Note",
  "id": "http://postparty.example/p/2415",
  "content": "<p>I <em>really</em> like strawberries!</p>",
  "source": {
    "content": "I *really* like strawberries!",
    "mediaType": "text/markdown"},
}
Note: What to do when clients can't meaningfully handle a mediaType?

In general, it's best to let a user edit their original post in the same source format they originally composed it in. But not all clients can reliably provide a nice interface for all source types, and since clients are expected to do the conversion from source to content, some clients may work with a media type that another client does not know how to work with. While a client could feasibly provide the content markup to be edited and ignore the source, this means that the user will lose the more desirable form of the original source in any future revisions. A client doing so should thus provide a minimally obtrusive warning cautioning that the original source format is not understood and is thus being ignored.

For example, Alyssa P. Hacker likes to post to her ActivityPub powered blog via an Emacs client she has written, leveraging Org mode. Later she switches to editing on her phone's client, which has no idea what text/x-org is or how to render it to HTML, so it provides a text box to edit the original content instead. A helpful warning displays above the edit area saying, "This was originally written in another markup language we don't know how to handle. If you edit, you'll lose your original source!" Alyssa decides the small typo fix isn't worth losing her nice org-mode markup and decides to make the update when whe gets home.

4. Actors

Actors in ActivityPub are represented by HTTP URI. When entered directly into a user interface (for example on a login form), it is desirable to support simplified naming. For this purpose cases, ID normalization SHOULD be performed as follows:

  1. If the entered ID is a valid URI, then it is to be used directly.
  2. If it appears that the user neglected to add a scheme for a URI that would otherwise be considered valid, such as example.org/alice/, clients MAY attempt to provide a default scheme, preferably https.
  3. Otherwise, the entered value should be considered invalid.

Once the actor's URI has been identified, it should be dereferenced.

4.1 Actor objects

Actor objects are ActivityStreams objects which are subclasses of the Actor type. Actor objects MUST have, in addition to the properties mandated by 3.1 Object Identifiers, the following properties:

inbox
A reference to an [ActivityStreams] collection comprising of all the messages received by the actor; see 5.5 Inbox.
outbox
An [ActivityStreams] collection comprising of all the messages produced by the actor; see 5.4 Outbox.

Implementations SHOULD, in addition, provide the following properties:

url
A link to the actor's "profile web page", if it is not equal to the value of id.
following
An [ActivityStreams] collection of the actors that this actor is following.
followers
An [ActivityStreams] collection of the actors that follow this actor.
name
The preferred "nickname" or "display name" of the actor.
Example 3
{
  "@context": "https://www.w3.org/ns/activitypub",
  "type": "Person",
  "id": "https://johnsmith.example.com/",
  "following": "https://johnsmith.example.com/following.json",
  "followers": "https://johnsmith.example.com/followers.json",
  "inbox": "https://johnsmith.example.com/inbox.json",
  "outbox": "https://johnsmith.example.com/feed.json",
  "preferredUsername": "johnsmith",
  "name": "John Smith",
  "summary": "Just an example guy",
  "icon": [
    "https://johnsmith.example.com/image/165987aklre4"
  ]
}

Implementations MAY, in addition, provide the following properties:

streams
A list of supplementary Collections which may be of interest.
preferredUsername
A short username which may be used to refer to the actor, with no uniqueness guarantees.
summary
A quick summary or bio by the user about themselves.
icon
A media link to the user's profile picture (this may be a thumbnail).
endpoints
A mapping of additional endpoints which may be useful either for this actor or someone referencing this actor.

The endpoints mapping MAY include the following properties:

uploadMedia
Upload endpoint URI for this user for binary data.
proxyUrl
Endpoint URI so this actor's clients may access remote ActivityStreams objects which require authentication to access.
oauthClientAuthorize
If OAuth 2.0 bearer tokens are being used for authenticating client to server interactions, this endpoint specifies a URI at which a browser-authenticated user may obtain a new access token.
provideClientKey
If Linked Data Signatures and HTTP Signatures are being used for authentication and authorization, this endpoint specifies a URI at which browser-authenticated users may authorize a client's public key for client to server interactions.
signClientKey
If Linked Data Signatures and HTTP Signatures are being used for authentication and authorization, this endpoint specifies a URI at which a client key may be signed by the actor's key for a time window to act on behalf of the actor in interacting with foreign servers.

5. Collections

[ActivityStreams] defines the collection concept; ActivityPub defines several collections with special behavior. Note that ActivityPub makes use of ActivityStreams paging to traverse large sets of objects.

Note that some of these collections are specified to be of type OrderedCollection specifically, while others are permitted to be either a Collection or an OrderedCollection. An OrderedCollection MUST be presented consistently in reverse chronological order.

Note

What property is used to determine the reverse chronological order is intentionally left as an implementation detail. For example, many SQL-style databases use an incrementing integer as an identifier, which can be reasonably used for handling insertion order in most cases. In other databases, an insertion time timestamp may be preferred. What is used isn't important, but the ordering of elements must remain intact, with newer items first. A property which changes regularly, such a "last updated" timestamp, should not be used.

5.1 Followers Collection

Every actor SHOULD have a followers collection. This is a list of everyone who has sent a Follow activity for the user, added as a side effect. This is where one would find a list of all the users that are following the actor. The followers collection MUST be either an OrderedCollection or a Collection.

Note: Default for notification targeting

The follow activity generally is a request to see the objects a user creates. This makes the Followers collection an appropriate default target for delivery of notifications.

5.2 Following Collection

Every actor MAY have a Following collection. This is a list of everybody that the actor has followed, added as a side effect. The following collection MUST be either an OrderedCollection or a Collection.

5.3 Likes Collection

Every actor MAY have a Likes collection. This is a list of every object from all of the actor's Like activities, added as a side effect. The following collection MUST be either an OrderedCollection or a Collection.

5.4 Outbox

The outbox is discovered through the outbox property of an actor's profile. The outbox MUST be an OrderedCollection.

The outbox stream contains objects the user has published, subject to the ability of the requestor to retrieve the object (that is, the contents of the outbox are filtered by the permissions of the person reading it). If a user submits a request without Authorization the server should respond with all of the Public posts. This could potentially be all relevant objects published by the user, though the number of available items is left to the discretion of those implementing and deploying the server.

The outbox accepts HTTP POST requests, with behaviour described in Client to Server Interactions.

5.5 Inbox

The inbox is discovered through the inbox property of an actor's profile. The inbox MUST be an OrderedCollection.

The inbox stream contains all objects received by the user. The server SHOULD filter content according to the requester's permission. In general, the owner of an inbox is likely to be able to access all of their inbox contents. Depending on access control, some other content may be public, whereas other content may require authentication for non-owner users, if they can access the inbox at all.

The server MUST perform de-duplication of activities returned by the inbox. Duplication can occur if an activity is addressed both to a user's followers, and a specific user who also follows the recipient user, and the server has failed to de-duplicate the recipients list. Such deduplication MUST be performed by comparing the id of the activities and dropping any activities already seen.

The inbox accepts HTTP POST requests, with behaviour described in Delivery.

5.6 Public Addressing

In addition to [ActivityStreams] collections and objects, Activities may additionally be addressed to the special "public" collection denoted by:

Example 4
{
  "@context": "https://www.w3.org/ns/activitypub",
  "id": "https://www.w3.org/ns/activitypub/Public",
  "type": "Collection"
}

Activities addressed to this special URI shall be accessible to all users, without authentication.

Note: TODO: namespace

New URI for AP? Or can we get as:public?

6. Binary Data

There is the ability to submit binary data such as images, video or other binary data you wish to use in ActivityPub. This is done by means of submitting the binary data to the user's uploadMedia on their ActivityStreams profile object. The request MUST contain the HTTP headers Content-Type and Content-Length. A client should expect that it must be properly authenticated in order to be able to upload media. Upon successful submission a response containing the object with an ID is returned that can be posted to the users outbox.

An example response for an image I might upload is:

Example 5
{
  "@context": "https://www.w3.org/ns/activitypub",
  "id": "https://example.com/~erik/photos/1",
  "type": "Image",
  "to": ["https://example.com/~erik/public",
         "https://example.org/~sarah/"],
  "cc": ["https://example.com/~erik/followers"],
  "url": [
    {
      "type": "Link",
      "href": "https://example.com/~erik/photos/1.png",
      "mediaType": "image/png"
    }
  ]
}

7. Client to Server Interactions

Activities as defined by [ActivityStreams] are the core mechanism for creating, modifying and sharing content within the social graph. Client to server interaction takes place through clients posting activities to a user's outbox.

Clients are responsible for addressing new Activites appropriately. To some extent, this is dependent upon the particular client implementation, but clients must be aware that the server will only forward new Activities to addressees in the to, cc and bcc fields.

Clients MAY address new Activities to the user's Followers Collection or the Public Collection by default.

Clients SHOULD check any objects attached to the Activity via the object, target, inReplyTo and/or tag fields, retrieve their actor or attributedTo properties, and MAY also retrieve their addressing properties, and add these to the to or cc fields of the new Activity being created. Clients MAY recurse through attached objects, but if doing so, SHOULD set a limit for this recursion.

Clients MAY give the user the chance to amend this addressing in the UI.

For example, when Chris likes the following article by Amy:

Example 6: An Article
{
  "@context": "https://www.w3.org/ns/activitypub",
  "id": "https://rhiaro.co.uk/2016/05/minimal-activitypub",
  "type": "Article",
  "name": "Minimal ActivityPub update client",
  "content": "Today I finished morph, a client for posting ActivityStreams2...",
  "attributedTo": "https://rhiaro.co.uk/#amy",
  "to": "https://rhiaro.co.uk/followers/", 
  "cc": "https://e14n.com/evan"
}

the like is generated by the client as:

Example 7: A Like of the Article
{
  "@context": "https://www.w3.org/ns/activitypub",
  "type": "Like",
  "actor": "https://dustycloud.org/chris/"
  "name": "Chris liked 'Minimal ActivityPub update client'",
  "object": "https://rhiaro.co.uk/2016/05/minimal-activitypub",
  "to": ["https://rhiaro.co.uk/#amy",
         "https://dustycloud.org/followers",
         "https://rhiaro.co.uk/followers/"],
  "cc": "https://e14n.com/evan"
}

The receiving outbox can then perform delivery to not only the followers of Chris (the liker), but also to Amy, and Amy's followers and Evan, both of whom received the original article.

To submit new Activities to a user's server, clients MUST discover the URL of the user's outbox from their profile and then MUST make an HTTP POST request to to this URL with the Content-Type of application/ld+json; profile="https://www.w3.org/ns/activitystreams#". The request MUST be authenticated with the credentials of the user to whom the outbox belongs. The body of the POST request MUST contain a single Activity (which MAY contain embedded objects), or a single non-Activity object which will be wrapped in a Create activity by the server.

Example 8: Submitting an Activity to the Outbox
POST /outbox/ HTTP/1.1
Host: dustycloud.org
Authorization: Bearer XXXXXXXXXXX
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams#"

{
  "@context": "https://www.w3.org/ns/activitypub",
  "type": "Like",
  "actor": "https://dustycloud.org/chris/"
  "name": "Chris liked 'Minimal ActivityPub update client'",
  "object": "https://rhiaro.co.uk/2016/05/minimal-activitypub",
  "to": ["https://dustycloud.org/followers", "https://rhiaro.co.uk/followers/"],
  "cc": "https://e14n.com/evan"
}

If an Activity is submitted with a value in the id property, servers MUST ignore this and generate a new id for the Activity. Servers MUST return a 201 Created HTTP code with the new URL in the Location header.

Example 9: Outbox response to submitted Activity
HTTP/1.1 201 Created
Location: https://dustycloud.org/likes/345

The server adds this new Activity to the outbox collection. Depending on the type of Activity, servers may then be required to carry out further side effects. These are described per individual Activity below.

7.1 Create Activity

The Create activity is used to when posting a new object. This has the side effect that the object embedded within the Activity (in the object property) is created.

When a Create activity is posted, the actor of the activity SHOULD be copied onto the object's attributedTo field.

A mismatch between addressing of the Create activity and its object is likely to lead to confusion. As such, a server SHOULD copy any recipients of the Create activity to its object upon initial distribution, and likewise with copying recipients from the object to the wrapping Create activity. Note that it is acceptable for the object's addressing may be changed later without changing the Create's addressing (for example via an Update activity).

7.1.1 Object creation without a Create Activity

For client to server posting, it is possible to create a new object without a surrounding activity. The server MUST accept a valid [ActivityStreams] object that isn't a subtype of Activity in the POST request to the outbox. The server then MUST attach this object as the object of a Create Activity.

Note

The Location value returned by the server should be the URL of the new Create activity (rather than the object).

The audience specified on the object MUST be copied over to the new Create activity by the server.

Example 10: Object with audience targeting
{
  "@context": "https://www.w3.org/ns/activitypub",
  "type": "Note",
  "content": "This is a note",
  "published": "2015-02-10T15:04:55Z",
  "to": ["https://example.org/~john/"],
  "cc": ["https://example.com/~erik/followers"]
}
The above example could be converted to this:
Example 11: Create Activity wrapper generated by the server
{
  "@context": "https://www.w3.org/ns/activitypub",
  "type": "Create"
  "id": "https://example.net/~mallory/87374"
  "actor": "https://example.net/~mallory",
  "object": {
    "id": "https://example.com/~mallory/note/72",
    "type": "Note",
    "attributedTo": "https://example.net/~mallory",
    "content": "This is a note",
    "published": "2015-02-10T15:04:55Z",
    "to": ["https://example.org/~john/"],
    "cc": ["https://example.com/~erik/followers"]
  },
  "published": "2015-02-10T15:04:55Z",
  "to": ["https://example.org/~john/"],
  "cc": ["https://example.com/~erik/followers"]
}

7.2 Update Activity

The Update activity is used when updating an already existing object. The side effect of this is that the object MUST be modified to reflect the new structure as defined in the update activity, assuming the actor has permission to update this object. For client to server interactions, updates are partial; rather than updating the document all at once, any key value pair supplied is used to replace the existing value with the new value. A special exception is for when the value is the json null type; this means that this field should be removed from the server's representation of the object.

Note that this behavior is for client to server interaction where the client is posting to the server only. Server to server interaction and updates from the server to the client should contain the entire new representation of the object, after the partial update application has been applied. See the description of the Update activity for server to server interactions for more details.

7.3 Delete Activity

The Delete activity is used to delete an already existing object. The side effect of this is that the server MAY replace the object with a Tombstone of the object that will be displayed in activities which reference the deleted object. If the deleted object is requested the server SHOULD respond with either the HTTP 410 Gone status code if a Tombstone is used, otherwise respond with a HTTP 404 Not Found.

A deleted object:

Example 12
{
  "@context": "https://www.w3.org/ns/activitypub",
  "id": "https://example.com/~alice/note/72",
  "type": "Tombstone",
  "published": "2015-02-10T15:04:55Z",
  "updated": "2015-02-10T15:04:55Z",
  "deleted": "2015-02-10T15:04:55Z",
}

7.4 Follow Activity

The Follow activity is used to subscribe to the activities of another user.

The side effect of receiving this in an outbox is that the server SHOULD add the object to the actor's Following Collection.

7.5 Add Activity

Upon receipt of an Add activity into the outbox, the server SHOULD add the object to the collection specified in the target property, unless:

7.6 Remove Activity

Upon receipt of a Remove activity into the outbox, the server SHOULD remove the object from the collection specified in the target property, unless:

7.7 Like Activity

The Like activity indicates the actor likes the object.

The side effect of receiving this in an outbox is that the server MAY add the object to the actor's Likes Collection.

7.8 Block Activity

The Block activity is used to indicate that the actor does not want a user (defined in the object property) to be able to interact with objects posted by the user. The server SHOULD prevent the user from interacting with any object posted by the actor.

Servers SHOULD NOT deliver Block Activities to their object.

7.9 Undo Activity

The Undo activity is used to undo a previous activity. For example, Undo may be used to undo a previous Like or Follow. The undo activity and the activity being undone MUST both have the same author. Side effects (such as adding activities to a user's inbox after a Follow) should be undone, to the extent possible.

There are some exceptions where there is an existing and explicit "inverse activity" which should be used instead. Create based activities should instead use Delete, and Add activities should use Remove.

7.10 Delivery

Federated servers MUST perform delivery on all Activities posted to the outbox according to outbox delivery.

8. Server to Server Interactions

Servers communicate with other servers and propagate information across the social graph by posting activities to actors' inbox endpoints. An Activity sent over over the network SHOULD have an id, unless it is intended to be transient (in which case it MAY omit the id or use a fragment identifier).

In order to propagate updates throughout the social graph, Activities are sent to the appropriate recipients. First, these recipients are determined through following the appropriate links between objects until you reach an agent (targeting), and then the Activity is inserted into the agent's inbox (delivery). This allows recipient servers to:

Delivery is usually triggered by, for example:

8.1 Targeting

Primary targeting is per the audience targeting properties from the [ ActivityStreams] specification. Notification targeting ensures the owners of all linked objects are notified of a new Activity that relates to them. Thus, the target(s) for delivery of an Activity may be:

If the entry is a collection, then the server MUST dereference the collection (with the user's credentials) and discover inboxes for each item in the collection. Servers MUST limit the number of layers of indirections through collections which will be performed, which MAY be one.

Servers MUST de-duplicate the final recipient list. Servers MUST also exclude actors from the list which are the same as the actor of the Activity being notified about.

Note: Silent and private activities

What to do when there are no recipients specified is not defined, however it's recommended that if no recipients are specified the object remains completely private and access controls restrict the access to object. If the object is just sent to the "public" collection the object is not delivered to any users but is publicly viewable in the actor's outbox.

8.2 Delivery

Once the target(s) for delivery have been determined, discovery of the recipient inbox(es), and delivery, are performed according to [LDN].

In summary, the inbox is determined through the inbox property in the actor's profile. An HTTP POST request (with authorization of the submitting user) is then made to to the inbox, with the Activity as the body of the request. This Activity is added by the receiver as an item in the inbox OrderedCollection.

For federated servers performing delivery to a 3rd party server, delivery SHOULD be performed asynchronously to completion of the original activity submission request, and SHOULD additionally retry delivery to recipients if it fails due to network error.

8.2.1 Outbox Delivery

When objects are received in the outbox, the server MUST target and deliver to:

  • The to, cc or bcc fields if their values are individuals, or Collections owned by the server.

These fields will have been populated appropriately by the client which posted the Activity to the outbox.

8.2.2 Inbox Delivery

When Activities are received in the inbox, the server needs to forward these to recipients that the origin was unable to deliver them to. To do this, the server MUST target and deliver to the values of to, cc and/or bcc if and only if all of the following are true:

  • This is the first time the server has seen this Activity.
  • The values of to, cc and/or bcc contain a Collection owned by the server.
  • The values of inReplyTo, object, target and/or tag are objects owned by the server. The server SHOULD recurse through these values to look for linked objects owned by the server, and SHOULD set a maximum limit for recursion (ie. the point at which the thread is so deep the recipients followers may not mind if they are no longer getting updates that don't directly involve the recipient). The server MUST only target the values of to, cc and/or bcc on the original object being forwarded, and not pick up any new addressees whilst recursing through the linked objects (in case these addressees were purposefully amended by or via the client).

The server MAY filter its delivery targets according to implementation-specific rules, for example, spam filtering.

8.3 Follow Activity

The side effect of receving this in an inbox is that the server SHOULD add the actor to the object user's Followers Collection.

8.4 Like Activity

The side effect of receving this in an inbox is that the server MAY increment the object's count of likes.

8.5 Add Activity

Upon receipt of an Add activity into the inbox, the server SHOULD add the object to the collection specified in the target property, unless:

8.6 Remove Activity

Upon receipt of a Remove activity into the inbox, the server SHOULD remove the object from the collection specified in the target property, unless:

8.7 Update Activity

For server to server interactions, an Update activity means that the receiving server SHOULD update its copy of the object of the same id to the copy supplied in the Update activity. Unlike the client to server handling of the Update activity, this is not a partial update but a complete replacement of the object.

The receiving server MUST take care to be sure that the Update is authorized to modify its object. At minimum, this may be done by ensuring that the Update and its object are of same origin.

9. Authentication and Authorization

This section is non-normative.

ActivityPub uses authentication for two purposes; first, to authenticate clients to servers, and secondly in federated implementations to authenticate servers to each other.

Unfortunately at the time of standardization, there are no strongly agreed upon mechanisms for authentication. Some possible directions for authentication are laid out as follows.

9.1 OAuth 2.0 and JSON Web Signatures

ActivityPub implementations MAY use OAuth 2.0 with JSON Web Signatures for authentication and authorization. This has the advantage of wide deployment of OAuth 2.0 technologies. However, OAuth 2.0 technologies are frequently incompatible, and the agreed upon mechanisms for deploying via OAuth 2.0 are still in flux, so it is not feasible to recommend a general pattern for OAuth 2.0 based deployments at this time.

9.1.1 Client to Origin Server Authentication

For client to server interactions where the client is interacting directly to the actor's server, clients MAY use OAuth 2.0 bearer tokens to authenticate.

9.1.2 Client to Foreign Server Authentication

For client to server interactions where the client is interacting with servers beyond the user's origin server, clients and servers MAY support use of OAuth 2.0 with JSON Web Signatures.

9.1.3 Servers Acting on Behalf of Users

Servers performing operations on behalf of a user (e.g. delivery to a recipient) MAY use OAuth 2.0 with JSON Web Signatures to authenticate with a 3rd party server.

9.2 Linked Data Signatures and HTTP Signatures

ActivityPub implementations MAY use Linked Data Signatures and signed HTTP messages for authentication and authorization. (Linked Data Signatures are best used when authentication is meant to be "long lived" and attached to an object, such as verifying that an object truly was posted by this actor, and signed HTTP messages should be used when authentication or authorization is ephemeral.) This has the advantage of clean integration with existing json-ld based technologies already used by ActivityPub. However, at the time of specification, Linked Data Signatures and HTTP signatures are very young, particularly in adoption.

When Linked Data Signatures in combined with ActivityPub, the server should assign an actor a public and private key pair, and link the public key to the actor's profile object, which may later be used with the Linked Data Signatures verification algorithm to validate the authenticity of messages passed along the network.

9.2.1 Client to Origin Server Authentication

For client to server interactions where the client is interacting directly with the actor's server, a client MAY use HTTP signatures by registering their client's public key with the actor on the server, and then subsequently signing HTTP requests made with this key.

9.2.2 Client to Foreign Server Authentication

For client to server interactions where the client is interacting with servers beyond the user's origin server, clients MAY use a combination of HTTP signatures and Linked Data Signatures.

In this scenario, a client would have their client key authorized for a limited window of time by the key listed on their actor profile. The client key would then be used to sign HTTP requests made to the foreign server while also providing the signature of the client public key, signed by and linked to the key on their actor profile.

9.2.3 Servers Acting on Behalf of Users

Servers performing operations on behalf of a user (e.g. delivery to a recipient) MAY use Linked Data Signatures to authenticate with a 3rd party server. This may be achieved by attaching the linked data signature to the activity posted to the remote inbox, signed by the actor's public key.

Servers receiving activities verified via Linked Data Signatures SHOULD NOT process an object with a nonce they have seen before, so as to prevent replay attacks.

A. Security Considerations

This section is non-normative.

A.1 Verification and authorization

Servers should be careful to verify that new content is really posted by the author that claims to be posting it, and that the author has permission to update the resources it claims to. Discussion of how to accomplish this is laid out in the 3. Objects and 9. Authentication and Authorization sections.

A.2 Accessing localhost URIs

It is often convenient while developing to test against a process running on localhost. However, permitting accessing localhost in a production client or server instance can be dangerous. Accessing URIs on localhost which do not require authorization may unintentionally access or modify resources assumed to be protected to be usable by localhost-only.

If your ActivityPub server or client does permit accessing localhost URIs for development purposes, consider making it a configuration option which defaults to off.

A.3 URI Schemes

There are many types of URIs aside from just http and https. Some libraries which handle fetching requests at various URI schemes may try to be smart and reference schemes which may be undesirable, such as file. Client and server authors should carefully check how their libraries handle requests, and potentially whitelist only certain safe URI types, such as http and https.

A.4 Spam

Spam is a problem in any network, perhaps especially so in federated networks. While no specific mechanism for combating spam is provided in ActivityPub, it is recommended that servers filter incoming content both by local untrusted users and any remote users through some sort of spam filter.

B. Acknowledgements

This section is non-normative.

This specification comes from years of hard work and experience by a number of communities exploring the space of federation on the web. In particular, much of this specification is informed by OStatus and the Pump API, as pioneered by StatusNet (now GNU Social) and Pump.io. Both of those initiatives were the product of many developers' hard work, but more than anyone, Evan Prodromou has been a constant leader in this space, and it is unlikely that ActivityPub would exist in something resembling its current state without his hard work.

Owen Shepherd built the initial version of this specification, borrowed from the ideas in the Pump API document, mostly as a complete rewrite of text, but sharing most of the primary ideas while switching from ActivityStreams 1 to ActivityStreams 2. Jessica Tallon and Christopher Allan Webber took over as editors when the standard moved to the W3C Social Working Group and did the majority of transition from Owen's document to its current state as ActivityPub.

ActivityPub has been shaped by the careful input of many members in the W3C Social Working Group. ActivityPub especially owes a great debt to Amy Guy, who has done more than anyone to map the ideas across the different Social Working Group documents through her work on the Social Web Protocols overview document. Amy also laid out the foundations for a significant refactoring of the ActivityPub spec while sprinting for four days with Christopher Allan Webber. These revisions lead to cleaner separation between the client to server and server components, along with clarity about ActivityPub's relationship to [LDN], among many other improvements.

C. Security and Privacy Review

This section is non-normative.

These questions provide an overview of security and privacy considerations for this specification as guided by Self-Review Questionnaire: Security and Privacy (W3C Working Group Note 10 December 2015).

Does this specification deal with personally-identifiable information?
ActivityPub's actors may contain information about the associated user. At minimum, the actor profile contains an identifier which also provides a mechanism for contacting the actor, through the exposed actor's inbox. Aside from this, ActivityPub does not mandate that any personally identifiable information to operate, though depending on the implementation, any number of details may be exposed on the actor's profile, particularly user names and real names. Additionally, a notification payload could include personally identifiable information, depending on the implementation and use, but it is again not required for the core functionality to operate.
Does this specification deal with high-value data?
Same implications as personally-identifiable information in notification payload (as mentioned above). The application supplies no normative mechanism for authentication from clients to servers, but depending on what mechanism is used, OAuth tokens may be exposed, particularly if HTTP is used without TLS/SSL support. Similarly, no normative mechanism for authentication between servers is exposed, though similar issues with exposure of data such as OAuth tokens could be exposed.
Does this specification introduce new state for an origin that persists across browsing sessions?
No. Clients may choose to cache server state information supplied through the application, though this is not mandated or specified.
Does this specification expose persistent, cross-origin state to the web?
Yes. Clients, if appropriately authorized, may read some inbox / outbox information from other actors on the web. Additionally, servers both read and submit activities to other servers on the network.
Does this specification expose any other data to an origin that it doesn’t currently have access to?
No. (Or at least, not as far as the person filling out this section can tell.)
Does this specification enable new script execution/loading mechanisms?
No.
Does this specification allow an origin access to a user’s location?
No.
Does this specification allow an origin access to sensors on a user’s device?
No.
Does this specification allow an origin access to aspects of a user’s local computing environment?
No.
Does this specification allow an origin access to other devices?
No.
Does this specification allow an origin some measure of control over a user agent’s native UI?
No.
Does this specification expose temporary identifiers to the web?
Not directly. However, mechanisms to authenticate an actor or authorize behavior might.
Does this specification distinguish between behavior in first-party and third-party contexts?
No.
How should this specification work in the context of a user agent’s "incognito" mode?
Works in such a way that the website would not be able to determine that the user was in "incognito".
Does this specification persist data to a user’s local device?
This depends on implementation. Clients might choose to cache activities they have previously seen, but this is not a normative requirement.
Does this specification have a "Security Considerations" and "Privacy Considerations" section?
You're looking at it!
Does this specification allow downgrading default security characteristics?
No.

D. Change Log

This section is non-normative.

D.1 Changes from 13 September 2016 to 23 October 2016

D.2 Changes from 23 August 2016 to 13 September 2016

D.3 Changes from 13 June 2016 to 23 August 2016

D.4 Changes from 28 January 2016 WD to 13 June 2016

E. References

E.1 Normative references

[ActivityStreams]
J. Snell. ActivityStreams Working Group. Activity Streams 2.0. Editors Draft. URL: https://www.w3.org/TR/activitystreams-core/
[LDN]
Sarven Capadisli; Amy Guy. W3C. Linked Data Notifications. 26 September 2016. W3C Working Draft. URL: https://www.w3.org/TR/ldn/
[RFC2119]
S. Bradner. IETF. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC7231]
R. Fielding, Ed.; J. Reschke, Ed.. IETF. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7231