Living Standard — June 26, 2019
This section is non-normative.
LitePub and other applications of ActivityStreams are built on top of an object-oriented architecture. Unlike previous specifications concerning this protocol, we present the object model in a flat way, where all objects are derived from the base Object type. It is our hope that this presentation is more easily understood by the reader as well as more reflective of reality.
In production, we have learned that maintaining an artificial partition between the notion of regular objects (which reflect data) and activities (which reflect mutations on data) significantly increases the complexity involved in walking a graph of activities. Accordingly, we have come to see the artificial partition as more harmful than helpful, especially when storing graphs in normalized form inside so-called “NoSQL” and traditional SQL databases.
Handling of Objects
LitePub implementations process ActivityStreams objects and store them and/or interpret them to perform mutations on other objects. To facilitate this, LitePub defines additional vocabulary on top of the ActivityStreams core vocabulary.
Information about handling the full LitePub vocabulary is in available in the LitePub vocabulary section.
Processing of Referenced Objects
Relative IRI references MUST NOT be used inside a LitePub object.
Servers MUST validate the content they receive to avoid content spoofing attacks as well as to verify that processing the object does not induce any mutations which would be disallowed by the server’s configured policy. There are two security models specified by this specification in the security considerations section.
All LitePub objects MUST have the following fields:
id: the object’s identifier (as an IRI)
type: the object’s type
Object Identifiers and Transience
All LitePub objects MUST have unique global identifiers. If an object is received without an identifier, the receiver MAY assign the object an internally generated identifier.
Servers MAY respond with an HTTP 410 response code when fetched by their global identifier to indicate their transcience.
Servers SHOULD replace the deleted object with a
Tombstone to prevent
re-use of the identifier or possible refetching of remote objects.
Servers MUST respond with an HTTP 404 response code when a
object is encountered.
Servers MUST NOT serve the contents of the
Servers SHOULD delete any local copies of an object if refetching the object results in either a 404 or 410 response code being returned.
Note: ActivityPub implementations are allowed to respond with either 404 or 410 as well as serving the underlying
Tombstoneobject. This behaviour is flawed because it results in metadata leakage – namely, it leaks that an object did at one time exist with the given identifier.
Servers SHOULD track which peers they have successfully delivered a given object to.
Servers SHOULD broadcast
Delete messages to all peers they
successfully delivered the message to.
Object Serving and Fetching
Servers MAY require authorization to serve any object, including
objects addressed to
Servers MUST require authorization to serve any object not
Servers SHOULD treat authorized object fetch requests as deliveries to the authorized peer and record them as a successful delivery.
Description of Object Processing Algorithm
This section is non-normative.
A possible algorithm for processing objects according to the above defined rules would be:
Verify the object’s
idis unique and not yet stored in the object graph.
Verify that the object’s
typeis processable by the LitePub implementation.
Iterate over all properties in the object looking for potential children (any property typed as an
idor any included child objects).
For each child object, replace the object with an authoritative local copy of the object. Fetch new authoritative copies of any missing objects.
For all children, return to step 2 with the child object as the processing context.
If authoritative versions of any children are missing, reject the root object if transitive child objects are not allowed for the root object’s
Apply any required side effects or mutations prescribed by the root object’s
Store the root object in the object graph using it’s