<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tim's blog (Posts about jsonld)</title><link>https://blog.thechases.com</link><description></description><atom:link href="https://blog.thechases.com/categories/jsonld.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2025 &lt;a href="mailto:blog@tim.thechases.com"&gt;Tim Chase&lt;/a&gt; </copyright><lastBuildDate>Thu, 02 Oct 2025 19:32:44 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Exploring ActivityPub/ActivityStreams</title><link>https://blog.thechases.com/posts/activitypub-activitystreams/</link><dc:creator>Tim Chase</dc:creator><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;

&lt;p&gt;
 Wanting to dig into
 &lt;a href="https://www.w3.org/TR/activitypub/"&gt;ActivityPub&lt;/a&gt;
 /
 &lt;a href="https://www.w3.org/TR/activitystreams-core/"&gt;ActivityStreams&lt;/a&gt;
 for a while
 I figured I'd read the specs and dive in.
 Having read plenty of
 &lt;a href="https://en.m.wikipedia.org/wiki/Request_for_Comments" title="Request for Comment"&gt;RFC&lt;/a&gt;
 specs before,
 I figured this wouldn't take too long.
 Boy was I wrong.
&lt;/p&gt;

&lt;p&gt;
 This article is currently a
 &lt;abbr title="Work In Progress"&gt;WIP&lt;/abbr&gt;
 so it may get updated
 multiple times as I learn more
 and read deeper into the various specs/RFCs
 and their sub-dependencies.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;
 The whole family of specs
 feels like the authors wanted a grab-bag
 of front-end features
 rather than detailing the protocols
 with the precision of engineers that write
 &lt;abbr title="Request for Comments"&gt;RFCs&lt;/abbr&gt;.
 The observations that follow
 document some of my frustrations along the way.
 Sorry if this comes across a little more ranty &amp;amp; grumbling
 compared to my usual posts.
&lt;/p&gt;

&lt;p&gt;
 On top of all the
 &lt;em&gt;standardized&lt;/em&gt;
 mess,
 &lt;a href="https://docs.joinmastodon.org/spec/activitypub/"&gt;Mastodon
 adds its own layer of non-standardized attributes&lt;/a&gt;
 that other ActivityPub software
 is expected to understand.
 &lt;!--
 Note to self: Mastodon uses the summary: attribute as the CW.
 If the Object has a content: attribute, use that;
 otherwise use the name: attribute

 --&gt;
&lt;/p&gt;

&lt;h2 id="activitypub1"&gt;ActivityPub (part 1)&lt;/h2&gt;

&lt;p&gt;
 Upon embarking,
 the first thing I learned was that
 &lt;a href="https://joinmastodon.org/"&gt;Mastodon&lt;/a&gt;,
 &lt;a href="https://gotosocial.org/"&gt;GoToSocial&lt;/a&gt;,
 &lt;a href="https://pleroma.social/"&gt;Pleroma&lt;/a&gt;,
 &lt;a href="https://pixelfed.org/"&gt;PixelFed&lt;/a&gt;,
 &lt;a href="https://joinpeertube.org"&gt;PeerTube&lt;/a&gt;,
 and other distributed-web services
 all run on a backbone of
 &lt;a href="https://www.w3.org/TR/activitypub/"&gt;ActivityPub&lt;/a&gt;
 so I figured I'd start there.
&lt;/p&gt;

&lt;p&gt;
 The ActivityPub spec clocks in
 at about 36 pages when printed.
 Pretty manageable.
&lt;/p&gt;

&lt;p&gt;
 The very first thing you read there?
 &lt;/p&gt;&lt;blockquote&gt;
  The ActivityPub protocol
  is a decentralized social networking protocol
  based upon the
  &lt;a href="https://www.w3.org/TR/activitystreams-core/"&gt;ActivityStreams&lt;/a&gt;
  2.0 data format.
  It provides a client to server API
  for creating, updating and deleting content,
  as well as a federated server to server API
  for delivering notifications and content.
 &lt;/blockquote&gt;
 Okay, I guess I need to read the ActivityStreams spec first.


&lt;h2 id="activitystreams1"&gt;ActivityStreams (part 1)&lt;/h2&gt;

&lt;p&gt;
 Okay, the ActivityStreams spec adds
 roughly another 46 pages of reading.
&lt;/p&gt;

&lt;p&gt;
 ActivityStreams consist of
 &lt;a href="https://json.org" title="JavaScript Object Notation"&gt;JSON&lt;/a&gt;
 data,
 formally defined as an
 &lt;a href="https://datatracker.ietf.org/doc/html/rfc7159"&gt;RFC-7159&lt;/a&gt;.
 Fortunately, I'm reasonably familiar with JSON
 so I won't go into that here.
&lt;/p&gt;

&lt;p&gt;
 However, barely into the second section
 and we discover that we need to learn about
 &lt;abbr title="JavaScript Object Notation: Linked Data"&gt;JSON-LD&lt;/abbr&gt;
 (another roughly 200 pages).
&lt;/p&gt;

&lt;h2 id="jsonld1"&gt;JSON-LD part 1&lt;/h2&gt;

&lt;p&gt;
 Based on the spec,
 the web-server should serve
 JSON-LD documents with a
 &lt;abbr title="Multipurpose Internet Mail Extensions"&gt;MIME&lt;/abbr&gt;
 type of
 &lt;tt class="term"&gt;application/json&lt;/tt&gt;.
&lt;/p&gt;

&lt;p&gt;
 And one of the first things we learn?
 There's a relationship with
 &lt;abbr title="Resource Description Framework"&gt;RDF
 so time to take a detour
 to learn about
 &lt;a href="https://www.w3.org/TR/rdf11-concepts/"&gt;RDF concepts&lt;/a&gt;.
&lt;/abbr&gt;&lt;/p&gt;

&lt;h2 id="rdf1"&gt;RDF (part 1?)&lt;/h2&gt;

&lt;p&gt;
 Goody, another 41 pages of reading.
 With cross-references to
 othe things like
 RDF-Schema.
 I'll defer digging into that for now.
&lt;/p&gt;

&lt;p&gt;
 The general gist is that
 &lt;abbr title="Resource Description Framework"&gt;RDF&lt;/abbr&gt;
 specifies things in terms of
 Subject→Predicate→Object.
 The Subject may be
 an &lt;abbr title="Internationalized Resource Identifier"&gt;IRI&lt;/abbr&gt;,
 or a "blank node"
 (but
 &lt;strong&gt;not&lt;/strong&gt;
 a literal).
 The Object may be
 an IRI,
 a "blank node",
 or a literal.
 See &lt;a href="https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple"&gt;further documentation&lt;/a&gt;.
 Why can an Object
 be any of them,
 but a Subject can't be a Literal?
 Kinda glossed over.
&lt;/p&gt;

&lt;h2 id="activitystreams2"&gt;ActivityStreams (part 2)&lt;/h2&gt;

&lt;p&gt;
 Popping from the stack,
 we return to ActivityStreams.
 Note that JSON-LD has a
 &lt;abbr title="Multipurpose Internet Mail Extensions"&gt;MIME&lt;/abbr&gt;
 type of
 &lt;tt class="term"&gt;application/json&lt;/tt&gt;
 while ActivityStreams specifies
 &lt;tt class="term"&gt;application/activity+json&lt;/tt&gt;
 so we already have conflicting information.
&lt;/p&gt;

&lt;p&gt;
 However, before getting a paragraph into
 &lt;a href="https://www.w3.org/TR/activitystreams-core/#syntaxconventions"&gt;Serialization&lt;/a&gt;
 we learn the spec defines an entire
 &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/"&gt;ActivityStreams vocabulary&lt;/a&gt;
 so time for another detour.
&lt;/p&gt;

&lt;h2 id="activitystreamsvocab1"&gt;ActivityStreams Vocabulary (part 1)&lt;/h2&gt;

&lt;p&gt;
 The vocabulary definition clocks in
 at roughly another 54 pages.
 For those playing along at home,
 we're up to 200+36+46+54=336 pages
 without counting
 &lt;abbr title="JavaScript Object Notation"&gt;JSON&lt;/abbr&gt;
 specifications or the
 &lt;a href="http://xmlns.com/foaf/spec/" title="Friend of a Friend"&gt;FoaF&lt;/a&gt;
 &amp;amp;
 &lt;a href="http://vocab.org/relationship/"&gt;Relationship&lt;/a&gt;
 specs referenced by the ActivityPub Vocabulary document.
&lt;/p&gt;

&lt;p&gt;
 Looking over this document,
 the particulars will require knowing more
 about ActivityPub/ActivityStreams
 so I'll return to this later.
&lt;/p&gt;

&lt;h2 id="activitystreams3"&gt;ActivityStreams (part 3)&lt;/h2&gt;

&lt;h3 id="activitystreamsgood"&gt;The Good&lt;/h3&gt;

&lt;dl&gt;

 &lt;dt&gt;Encoding&lt;/dt&gt;
 &lt;dd&gt;
  The specification clearly states
  that all data gets serialized as
  &lt;a href="https://en.wikipedia.org/wiki/UTF-8"&gt;UTF-8&lt;/a&gt;.
  This is good.
  I've encountered too many file-formats
  where this doesn't get defined
  and I have to guess the encoding.
  It's nice to be able to identify non-UTF8 text
  and reject malformed requests
  without having to retry some other encoding.
 &lt;/dd&gt;

 &lt;dt&gt;Date formats&lt;/dt&gt;
 &lt;dd&gt;
  Additionally, the spec clearly defines
  &lt;a href="https://www.w3.org/TR/activitystreams-core/#dates"&gt;date formats&lt;/a&gt; 
  according to
  &lt;a href="https://datatracker.ietf.org/doc/html/rfc3339"&gt;RFC-3339&lt;/a&gt;.
  However, I find the
  "time-offset isn't a time-zone" 
  mildly annoying.
 &lt;/dd&gt;

&lt;/dl&gt;

&lt;h3 id="activitystreamsbad"&gt;The Bad&lt;/h3&gt;

&lt;dl&gt;
 &lt;dt&gt;Context data-type&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   What is the data-type of a
   &lt;tt class="term"&gt;@context&lt;/tt&gt;'s
   value?
   According to the
   &lt;a href="https://www.w3.org/TR/json-ld11/#dfn-context"&gt;JSON-LD spec&lt;/a&gt;

   &lt;/p&gt;&lt;blockquote&gt;
    …the value of a term definition
    can either be a simple String, mapping the term to an
    &lt;abbr title="Internationalized Resource Identifier"&gt;IRI,
    or a map.
   &lt;/abbr&gt;&lt;/blockquote&gt;


   In the case of an ActivityStream,
   the String form has the fixed
   &lt;abbr title="Uniform Resource Indicator"&gt;URI&lt;/abbr&gt;
   value of
   "https://www.w3.org/ns/activitystreams".
   In the case of an object/map value,
   the document's type resides
   in the
   &lt;tt class="term"&gt;@vocab&lt;/tt&gt;
   sub-node along with other attributes
   such as the
   &lt;tt class="term"&gt;@language&lt;/tt&gt;
   or namespace definitions.
  

  &lt;p&gt;
   Except when it's a list.
   Wait, the JSON-LD spec clearly said
   &lt;q&gt;a simple String…or a map.&lt;/q&gt;
   Nothing about a list.
   Yet the JSON-LD spec itself
   &lt;a href="https://www.w3.org/TR/json-ld11/#example-20-describing-disconnected-nodes-with-graph"&gt;uses lists as values&lt;/a&gt;
   for the
   &lt;tt class="term"&gt;@context&lt;/tt&gt;.
  &lt;/p&gt;

  &lt;p&gt;
   Fine.
   It can be a list.
   Is it a list of homogeneous elements?
   Of course not.
   &lt;em&gt;Each element&lt;/em&gt;
   can be either a fixed String
   or a JSON object/mapping.
  &lt;/p&gt;

  &lt;p&gt;
   So how do you find the document type?
   Maybe it's the URI String found at
   &lt;tt class="term"&gt;.@context&lt;/tt&gt;
   or at
   &lt;tt class="term"&gt;.@context.@vocab&lt;/tt&gt;
   or at
   &lt;tt class="term"&gt;.@context[0]&lt;/tt&gt;
   or at
   &lt;tt class="term"&gt;.@context[0].@vocab&lt;/tt&gt;
   or maybe someplace else.
   Could it be 
   &lt;tt class="term"&gt;.@context[1]&lt;/tt&gt;
   instead?
   The specs don't have much to say about that.
  &lt;/p&gt;

  &lt;p&gt;
   But the specs
   &lt;em&gt;could&lt;/em&gt;
   have mandated a single way to do it,
   declaring that it's a list of objects,
   each object with a
   &lt;tt class="term"&gt;@vocab&lt;/tt&gt;
   property,
   and that the first one is the document-type.
   One place to look.
   But no.
  &lt;/p&gt;

  &lt;/dd&gt;

 &lt;dt&gt;What type of value should you expect?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   According to
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#object"&gt;section 4.1&lt;/a&gt;
   &lt;/p&gt;&lt;blockquote&gt;
    In addition to the global identifier
    (expressed as an absolute IRI using the
    &lt;tt class="term"&gt;id&lt;/tt&gt;
    property)
    and an "object type"
    (expressed using the
    &lt;tt class="term"&gt;type&lt;/tt&gt;
    property),
    all instances of the
    &lt;tt class="term"&gt;Object&lt;/tt&gt;
    type share a common set of properties
   &lt;/blockquote&gt;
   Okay, so Actors &amp;amp; Objects
   should have a mapping as a value,
   and that mapping should contain
   at least 
   &lt;tt class="term"&gt;id&lt;/tt&gt;
   &amp;amp;
   &lt;tt class="term"&gt;type&lt;/tt&gt;
   attributes.
   Except they don't have to:
   &lt;blockquote&gt;
    All properties are optional
    (including the
    &lt;tt class="term"&gt;id&lt;/tt&gt;
    &amp;amp;
    &lt;tt class="term"&gt;type&lt;/tt&gt;).
   &lt;/blockquote&gt;
   Would it hurt to make those required?
   But even worse, according to
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#examples"&gt;Example 4&lt;/a&gt;
   it looks like those values can be strings
   instead of maps/objects.
   They appear to be
   &lt;abbr title="Uniform Resource Indicator"&gt;URIs&lt;/abbr&gt;
   but it's not documented.
   So if you get a String here,
   all bets are off.
  
 &lt;/dd&gt;

 &lt;dt&gt;Links suffer the same value-type issue&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Similar to above,
   a Link like an
   &lt;tt class="term"&gt;image&lt;/tt&gt;
   can have
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-to-reference-a-single-image-without-any-additional-metadata-a-direct-association-can-be-expressed-as-a-json-String-containing-an-absolute-iri.x"&gt;a String&lt;/a&gt;
   as the value,
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-alternatively-if-additional-metadata-is-required-such-as-the-mime-content-type-of-the-referenced-resource-a-link-can-be-used"&gt;an Object&lt;/a&gt;
   as the value, or
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-example-14-context-https-www.w3.org-ns-activitystreams-type-application-id-http-example.org-application-123-name-exampletron-3000-image-http-example.org-application-abc.gif-type-link-href-http-example.org-application-123.png-mediatype-image-png-rel-thumbnail"&gt;a list&lt;/a&gt;.
   And the list can be composed of heterogeneous types,
   strings, objects, and maybe lists?
   Who knows?
   It's not clearly defined anywhere.
   This could have been defined once
   as a list of objects,
   and everything would fit.
   But no.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt id="hierarchy-inversion"&gt;Hierarchy inversion&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   An
   &lt;tt class="term"&gt;IntransitiveActivity&lt;/tt&gt;
   has an Actor
   but no Object.
   But the ActivityStreams spec
   defines defines an
   &lt;tt class="term"&gt;IntransitiveActivity&lt;/tt&gt;
   as
   &lt;/p&gt;&lt;blockquote&gt;
    specializations of the Activity type
    that represent intransitive actions.
   &lt;/blockquote&gt;
   This means from an object-oriented perspective
   an
   &lt;tt class="term"&gt;IntransitiveActivity&lt;/tt&gt;
   is a sub-class of an Activity.
   However this means that Activity objects
   have an Object,
   but their 
   &lt;tt class="term"&gt;IntransitiveActivity&lt;/tt&gt;
   sub-classes don't.
  
 &lt;/dd&gt;

 &lt;dt&gt;Type of &lt;tt class="term"&gt;type&lt;/tt&gt;&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Normally an object has a single
   &lt;tt class="term"&gt;type&lt;/tt&gt;
   value,
   a String representing the type of the object.
   Cool.
   But sometimes instead of a String,
   the
   &lt;tt class="term"&gt;type&lt;/tt&gt;
   can be a
   &lt;strong&gt;list&lt;/strong&gt;
   of types.
   Again, are the entries in the list homogeneous?
   Nope.
   Composed of strings and objects.
   Can a list-entry be another list?
   Who knows.
   Check out
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-an-activity-with-a-person-actor-extended-with-vcard-properties"&gt;Example 22&lt;/a&gt;
   to see this abomination in play.
   And with disjoint types,
   you can end up with redundant data,
   the same value in multiple keys.
   It's not like this is a specification
   requiring precision or anything.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;How big is a &lt;tt class="term"&gt;Collection&lt;/tt&gt;?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   A
   &lt;tt class="term"&gt;Collection&lt;/tt&gt;
   and its sub-classes
   (&lt;tt class="term"&gt;OrderedCollection&lt;/tt&gt;,
   &lt;tt class="term"&gt;CollectionPage&lt;/tt&gt;,
   and
   &lt;tt class="term"&gt;OrderedCollectionPage&lt;/tt&gt;)
   have both a
   &lt;tt class="term"&gt;totalItems&lt;/tt&gt;
   property and an
   &lt;tt class="term"&gt;items&lt;/tt&gt;
   property.
   But there are no requirements
   that these be disjoint.
   This means that you can have
   both properties
   and they can conflict.
   You could have a list of
   &lt;tt class="term"&gt;items&lt;/tt&gt;
   with 5 elements in it,
   yet have the
   &lt;tt class="term"&gt;totalItems&lt;/tt&gt;
   report 3 or 7 elements.
   Which should be displayed?
   It's not in the spec.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Pagination of an (unordered) &lt;tt class="term"&gt;Collection&lt;/tt&gt;&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   If a collection is unordered,
   pagination through it makes
   &lt;strong&gt;zero sense&lt;/strong&gt;.
   Pagination
   &lt;em&gt;requires&lt;/em&gt;
   ordering.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Should you expect a String vs. a map?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The spec describes
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#naturalLanguageValues"&gt;natural language values&lt;/a&gt;
   as a way to detect whether you should expect
   a String-value
   or a map-value.
   So if you use the
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   attribute, you get a String;
   and if you use the
   &lt;tt class="term"&gt;nameMap&lt;/tt&gt;
   attribute, you get a map/object.
   Not too bad.
   But why not keep that consistent
   across all the fields (above)
   that are sometimes a String
   and sometimes a map?
   Like that
   &lt;tt class="term"&gt;@context&lt;/tt&gt;
   attribute.
   Why not a
   &lt;tt class="term"&gt;@contextMap&lt;/tt&gt;
   then?
   But why start with consistency now?
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Which language wins?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   If you specify the
   &lt;tt class="term"&gt;@context&lt;/tt&gt;
   as an object,
   you can include a
   &lt;tt class="term"&gt;@language&lt;/tt&gt;
   property to specify the default language
   of the object.
   Alternatively, you can specify various languages
   in certain
   &lt;tt class="term"&gt;*Map&lt;/tt&gt;
   attributes such as
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-multiple-language-specific-values"&gt;Example 15&lt;/a&gt;.
   However, it also specifies
   &lt;/p&gt;&lt;blockquote&gt;
    The special language tag
    "&lt;tt class="term"&gt;und&lt;/tt&gt;"
    [undefined]
    can be used within the object form
    to explicitly identify a value
    whose language is unknown or undetermined.
   &lt;/blockquote&gt;
   So if you've specified a default language using
   &lt;tt class="term"&gt;@language&lt;/tt&gt;,
   what language should
   "&lt;tt class="term"&gt;und&lt;/tt&gt;"
   text be rendered as?
  
 &lt;/dd&gt;

 &lt;dt&gt;Markup? What flavor is it?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Some values
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#h-biditext"&gt;contain markup&lt;/a&gt;.
   Some values don't.
   The
   &lt;tt class="term"&gt;content&lt;/tt&gt;
   &amp;amp;
   &lt;tt class="term"&gt;summary&lt;/tt&gt;
   do;
   the
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/#dfn-name"&gt;doesn't&lt;/a&gt;.
   Which other fields do?
   Who knows.
   It's not well documented.
   What markup flavor?
   There are hints that markup in the
   &lt;tt class="term"&gt;content&lt;/tt&gt;
   field is
   &lt;abbr title="Hypertext Markup Language"&gt;HTML&lt;/abbr&gt;,
   But is that explicitly required?
   And if it is,
   what DocType?
   HTML5?
   HTML4.01?
   XHTML?
   Why not use Markdown?
  &lt;/p&gt;

  &lt;p&gt;
   As we'll discover later,
   ActivityPub specifies a
   &lt;tt class="term"&gt;source&lt;/tt&gt;
   attribute/extension
   that can have any flavor of source markup
   contingent on the
   &lt;tt class="term"&gt;mediaType&lt;/tt&gt;
   attribute.
   That then gets converted to the markup in the
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   (or whatever other fields support markup).
   But that's a level higher than ActivityStreams
   which we're reading about here.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;HTML markup part Ⅱ&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Additionally, if the content is HTML,
   this makes it easy to bypass user-agent filters.
   If I want to filter out posts containing "emacs"
   but someone posts
   &lt;code&gt;em&amp;lt;span&amp;gt;a&amp;lt;/span&amp;gt;cs&lt;/code&gt;,
   a simple filter can't find "emacs" in there.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;HTML markup part Ⅲ&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Furthermore, inline
   &lt;abbr title="Cascading Style Sheets"&gt;CSS&lt;/abbr&gt;
   can trigger strange effects
   if not sanitized.
   A
   &lt;tt class="term"&gt;content&lt;/tt&gt;
   value containing something like
   &lt;code&gt;&amp;lt;span style="position:absolute;
   left:0; top:0;
   width:100vw; height:100vh;
   background-color:black; color:red"&amp;gt;Hah!&amp;lt;/span&amp;gt;&lt;/code&gt;
   can throw off the rendering of the whole interface.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;HTML markup part Ⅳ&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   How about other markup concerns like
   &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;
   input in your posts?
   Should this be allowed?
   How should it be sanitized?
   🤷 &lt;!-- shrug --&gt;
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;HTML markup part Ⅴ&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   If we're sticking arbitrary blobs of HTML
   in fields such as the
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   what security considerations have been taken into effect?
   What happens if some
   &lt;code&gt;&amp;lt;script&amp;gt;nefarious code&amp;lt;script&amp;gt;&lt;/code&gt;
   shows up in a field's value?
   If improperly sanitized,
   it can still allow &amp;lt;script&amp;gt; tags through.
   The spec is notably silent on these issues.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Security handwaving&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   In the section on
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#security-considerations"&gt;Security Considerations&lt;/a&gt;,
   the spec advises consumers to take care
   with malicious user-input
   and when re-emitting ingested content.
   What sort of care?
   🦗 &lt;!-- cricket --&gt;
   And the exhortation to beware
   of potential spoofing attacks?
   What assurances does the spec have
   for determining the integrity
   of an ActivityStreams?
   None.
   We'll revisit this when we get to ActivityPub
   where there's some effort here,
   but it hasn't been standardized.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Privacy handwaving&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Similar to the Security issue, the
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#privacy"&gt;Privacy Considerations&lt;/a&gt;
   section does a lot of handwaving.
   There's no standardization of users
   or audience-groups
   vs. public
   vs. private
   postings.
   The spec talks of "opting in" to disclosure of posts,
   but doesn't detail how.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;HTML markup part Ⅲ&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   If we're sticking arbitrary blobs of HTML
   in fields such as the
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   what security considerations have been taken into effect?
   What happens if some
   &lt;code&gt;&amp;lt;script&amp;gt;nefarious code&amp;lt;/script&amp;gt;&lt;/code&gt;
   shows up in a field's value?
   If improperly sanitized,
   it can still allow &amp;lt;script&amp;gt; tags through.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Security handwaving&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   In the section on
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#security-considerations"&gt;Security Considerations&lt;/a&gt;,
   the spec advises consumers to take care
   with malicious user-input
   and when re-emitting ingested content.
   What sort of care?
   :crickets:
   And the exhortation to beware
   of potential spoofing attacks?
   What assurances does the spec have
   for determining the integrity
   of an ActivityStreams?
   None.
   We'll revisit this when we get to ActivityPub
   where there's some effort here,
   but it hasn't been standardized.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Privacy handwaving&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Similar to the Security issue,
   the 
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#privacy"&gt;Privacy Considerations&lt;/a&gt;
   section does a lot of handwaving.
   There's no standardization of users
   or audience-groups
   vs. public
   vs. private
   postings.
   The spec talks of "opting in" to disclosure of posts,
   but doesn't detail how.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Namespaces vs. things in that namespace&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   A
   &lt;tt class="term"&gt;@context&lt;/tt&gt;
   can have a map as a value,
   including attributes that don't begin with an
   &lt;tt class="term"&gt;@&lt;/tt&gt;
   mapping to a 
   &lt;abbr title="Uniform Resource Indicator"&gt;URI&lt;/abbr&gt;.
   According to
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-document-providing-context-as-an-array-and-including-an-alias-for-an-additional-term.x"&gt;Example 3&lt;/a&gt;
   we have
   &lt;tt class="term"&gt;css&lt;/tt&gt;
   defined as a URI
   and then used directly as
   "&lt;tt class="term"&gt;css&lt;/tt&gt;"
   in the object.
   However in
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#fig-an-object-that-is-both-a-place-and-a-gr-location"&gt;Example 3&lt;/a&gt;
   the same syntax defines
   &lt;tt class="term"&gt;gr&lt;/tt&gt;
   as a namespace,
   and it then gets used as
   &lt;tt class="term"&gt;gr:catgegory&lt;/tt&gt;
   further down,
   rather than using just
   &lt;tt class="term"&gt;gr&lt;/tt&gt;.
   When is it a stand-alone attribute,
   and when is it a namespace-prefix?
   From the context it looks like something comes after the
   &lt;tt&gt;#&lt;/tt&gt;
   in the URI.
   But it doesn't appear to be explicitly documented
   from what I can tell.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Compact URI namespaces are a nightmare&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   While this is a JSON-LD thing,
   it make it particularly challenging
   to re-serialize an Object.
  &lt;/p&gt;
 &lt;/dd&gt;

&lt;/dl&gt;

&lt;p&gt;
 So an ActivityStream consists of
 maybe an action with an Actor
 and an optional object,
 or maybe it's just an object.
 And the
 &lt;tt class="term"&gt;id&lt;/tt&gt;
 might be present or it might not,
 and properties might be strings or objects or lists,
 and some might have external schema links
 with corresponding namespaces,
 or they use properties from those namespaces directly
 without a namespace prefix,
 and sometimes values consist of mappings
 from language-to-(possibly-unknown-)value,
 where those values might have some sort of undefined markup
 (that might or might not have unspecified
 security or privacy concerns),
 and to find the
 &lt;tt class="term"&gt;@context&lt;/tt&gt;,
 you have to look in multiple place.
&lt;/p&gt;

&lt;p&gt;
 Got it.
 That's ActivityStreams.
&lt;/p&gt;

&lt;p&gt;
 Except we should investigate the
 &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/"&gt;ActivityStreams vocabulary&lt;/a&gt;
 before we return to ActivityPub.
&lt;/p&gt;

&lt;h2 id="activitystreamsvocab2"&gt;ActivityStreams Vocabulary (part 2)&lt;/h2&gt;

&lt;h3 id="activitystreamsvocabgood"&gt;The Good&lt;/h3&gt;

&lt;p&gt;
 The vocabulary
 seem to cover
 a reasonable range
 of activities
 and objects,
 and the attributes mostly make sense.
&lt;/p&gt;

&lt;p&gt;
 We also get
 &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/#properties"&gt;a
 bit of clarification&lt;/a&gt; here.
 All those
 "it can be a String,
 or it can be an Object,
 or it could be a List"
 confusions in the ActivityStreams spec
 get clarified here.
 &lt;/p&gt;&lt;blockquote&gt;
  Properties marked as being "Functional" can have only one value.
  Items not marked as "Functional" can have multiple values.
 &lt;/blockquote&gt;
 If a "Functional" attribute
 has a String as the value
 and the type allows for a Link,
 it will be a URI,
 otherwise the String
 will be the particular value
 (such as the
 &lt;tt class="term"&gt;latitude&lt;/tt&gt;
 or
 &lt;tt class="term"&gt;radius&lt;/tt&gt;).
 If an attribute is
 &lt;strong&gt;not&lt;/strong&gt;
 labeled as "Functional",
 it can be a heterogeneous list
 of Links, Objects, and Strings
 (where String values are usually URIs).
 Mildly annoying
 to have to deal with all three possible value-types
 for most attributes.
 But at least this makes a bit more sense.


&lt;h3 id="activitystreamsvocabbad"&gt;The Bad&lt;/h3&gt;

&lt;p&gt;
 Okay, this is a bit of a disaster.
&lt;/p&gt;

&lt;dl&gt;

 &lt;dt&gt;Alphabetization&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   There are several large tables here
   consisting of object-types
   and properties.
   But the tables aren't sorted alphabetically.
   This makes it next to impossible
   to find things in my print-outs.
   Sure, they have internal HTML links
   but that's useless on paper.
   I get that they're grouped
   by similar functionality,
   but that doesn't make it any easier to find things
   because you have to know the groupings
   &lt;span lang="lat"&gt;a priori&lt;/span&gt;
   to know where to find them.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Same issues with ActivityStreams&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Again we see the
   &lt;a href="https://blog.thechases.com/posts/activitypub-activitystreams/hierarchy-inversion"&gt;hierarchy-inversion&lt;/a&gt;
   of
   &lt;tt class="term"&gt;Activity&lt;/tt&gt;
   and
   &lt;tt class="term"&gt;IntransitiveActivity&lt;/tt&gt;,
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Handling out-of-spec items&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The spec declares that a
   &lt;tt class="term"&gt;Question&lt;/tt&gt;
   may have a
   &lt;tt class="term"&gt;oneOf&lt;/tt&gt;
   or an
   &lt;tt class="term"&gt;anyOf&lt;/tt&gt;,
   but not both.
   However, if a malformed activity provides both,
   what is the correct response?
   Reject the activity?
   Choose one arbitrarily?
   There were a couple other places
   where such requirements 
   left open-ended the handling
   of errors and non-conformance.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Simple carelessness/inconsistency?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Sometimes the Vocabulary spec declares attributes as
   &lt;tt class="term"&gt;Object/Link&lt;/tt&gt;
   and other times it 
   &lt;tt class="term"&gt;Link/Object&lt;/tt&gt;.
   Does the order matter?
   Why are they different?
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Similarly, why are
  &lt;tt class="term"&gt;items&lt;/tt&gt;
  explicitly called out
  to accept a List?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   As cited above,
   if an attribute is not labeled as "Functional"
   (the 
   &lt;tt class="term"&gt;items&lt;/tt&gt;
   attribute isn't),
   it can take a List of values.
   Yet the spec for
   &lt;tt class="term"&gt;items&lt;/tt&gt;
   explicitly spells out that it can take a List of
   &lt;tt class="term"&gt;Object/Link&lt;/tt&gt;.
   What makes this special?
   Why not annotate that
   &lt;em&gt;every&lt;/em&gt;
   non-Functional attribute can take a List?
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Speaking of redundant attributes,
  how about the
  &lt;tt class="term"&gt;url&lt;/tt&gt;?
  &lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The spec defines a
   &lt;tt class="term"&gt;url&lt;/tt&gt;
   as accepting a Link
   &lt;strong&gt;or&lt;/strong&gt;
   an
   &lt;tt class="term"&gt;xsd:anyURI&lt;/tt&gt;.
   But based on everything I've seen in the spec,
   &lt;strong&gt;any&lt;/strong&gt;
   Link can just be a String containing the URI.
   Why the redundancy?
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Codify ambiguity&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Reading about the
   &lt;tt class="term"&gt;context&lt;/tt&gt;
   attribute,
   &lt;/p&gt;&lt;blockquote&gt;
    The notion of "context" used
    is intentionally vague.
    The intended function
    is to serve as a means of grouping
    objects and activities
    that share a common organizing context or purpose.
   &lt;/blockquote&gt;
   If your spec says something is
   &lt;q&gt;intentionally vague&lt;/q&gt;,
   the spec has issues.
  
 &lt;/dd&gt;

 &lt;dt&gt;Is HTML allowed in String values?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   A
   &lt;tt class="term"&gt;content&lt;/tt&gt;
   and
   &lt;tt class="term"&gt;summary&lt;/tt&gt;
   attributes state that the data defaults to HTML markup.
   However, the
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   can also contain text,
   but the spec explicitly disallows HTML.
   This feels irrationally inconsistent.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Some attributes take a "Map" suffix, others don't&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   If you have a
   &lt;tt class="term"&gt;content&lt;/tt&gt;,
   &lt;tt class="term"&gt;name&lt;/tt&gt;,
   or
   &lt;tt class="term"&gt;summary&lt;/tt&gt;
   attribute,
   and you want to specify multiple languages,
   you use the
   &lt;tt class="term"&gt;contentMap&lt;/tt&gt;,
   &lt;tt class="term"&gt;nameMap&lt;/tt&gt;,
   and
   &lt;tt class="term"&gt;summaryMap&lt;/tt&gt;
   variants.
   It feels like this should have been used across the board.
   Use one attribute-name for a String value,
   a different name for an Object value,
   and yet a third different name for a a List value.
  &lt;/p&gt;

  &lt;p&gt;
   However, the ActivityStreams vocabulary specification
   &lt;strong&gt;doesn't detail these *Map&lt;/strong&gt;
   fields beyond a passing reference to
   &lt;a href="https://www.w3.org/TR/activitystreams-core/#naturalLanguageValues"&gt;Natural Language Values&lt;/a&gt;.
   The only reference to
   "Natural Language Values"
   in the ActivityStreams Vocabulary
   is the
   &lt;tt class="term"&gt;summary&lt;/tt&gt;/&lt;tt class="term"&gt;summaryMap&lt;/tt&gt;
   and nothing is mentioned
   regarding 
   &lt;tt class="term"&gt;name&lt;/tt&gt;/&lt;tt class="term"&gt;nameMap&lt;/tt&gt;
   or
   &lt;tt class="term"&gt;content&lt;/tt&gt;/&lt;tt class="term"&gt;contentMap&lt;/tt&gt;
   being "Natural Language Vocabulary".
   They only allude to 
   &lt;tt class="term"&gt;nameMap&lt;/tt&gt;
   and
   &lt;tt class="term"&gt;contentMap&lt;/tt&gt;
   without documenting why/how.
  &lt;/p&gt;

  &lt;p&gt;
   Additionally, can an object have
   &lt;strong&gt;both&lt;/strong&gt;
   the single version
   and the Map version?
   The spec only shows the exclusive cases,
   but the doesn't say whether an object can have both a
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   and a
   &lt;tt class="term"&gt;nameMap&lt;/tt&gt;
   attribute.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Start a new Relationship wit' you&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The
   &lt;tt class="term"&gt;Relationship&lt;/tt&gt;
   attribute accepts multiple
   (and semi-arbitrary)
   values,
   some from the
   &lt;a href="http://xmlns.com/foaf/spec/" title="Friend of a Friend"&gt;FoaF&lt;/a&gt;
   spec, and some from the
   &lt;a href="http://vocab.org/relationship/"&gt;Relationship&lt;/a&gt;
   spec
   (side rant: the
   &lt;a href="http://vocab.org"&gt;vocab.org&lt;/a&gt;
   site does a redirect and requires JavaScript enabled
   just to view the spec;
   A spec is a
   ████ &lt;!-- full-height block, censoring --&gt;
   text document).
   Are those the only values?
   What happens if they conflict or overlap?
   It's just kinda handwavey here.
   Yet more specs to read, I guess.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;In a Relationship? Says who?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The documentation for
   &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/#h-modeling-friend-requests"&gt;modeling a friend request&lt;/a&gt;
   references four different actors:
   &lt;/p&gt;&lt;ul&gt;
    &lt;li&gt;the &lt;tt class="term"&gt;actor&lt;/tt&gt; offering the friend-request&lt;/li&gt;
    &lt;li&gt;the &lt;tt class="term"&gt;target&lt;/tt&gt; receiving the friend-request&lt;/li&gt;
    &lt;li&gt;the &lt;tt class="term"&gt;object.subject&lt;/tt&gt; (the person seeking friendship)&lt;/li&gt;
    &lt;li&gt;the &lt;tt class="term"&gt;object.object&lt;/tt&gt; (the friend-to-be)&lt;/li&gt;
   &lt;/ul&gt;
   However, nothing in this example
   requires that the
   &lt;tt class="term"&gt;actor&lt;/tt&gt;
   &amp;amp;
   &lt;tt class="term"&gt;object.subject&lt;/tt&gt;
   be the same;
   nor does anything require that the
   &lt;tt class="term"&gt;target&lt;/tt&gt;
   &amp;amp;
   &lt;tt class="term"&gt;object.object&lt;/tt&gt;
   be the same.
   This means that Alice could send a request to Bob
   asking if Dave would accept Carol's relationship.
   Or Mallory could ask Bob
   if Bob would like to accept a relationship with Alice.
   This seems fraught with potential concerns
   that the spec leaves unaddressed.
  
 &lt;/dd&gt;

 &lt;dt&gt;Random &lt;tt&gt;acct:&lt;/tt&gt; prefix&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Continuing with the
   &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/#h-modeling-friend-requests"&gt;modeling a friend request&lt;/a&gt;,
   all four of those accounts use a
   &lt;tt class="term"&gt;acct:&lt;/tt&gt;
   prefix on a username.
   Why?
   Where is this defined?
   Not in the ActivityPub,
   ActivityStreams,
   ActivityStreams-Vocabulary,
   or the JSON-LD spec.
   Digging a bit,
   it looks like
   &lt;a href="https://www.rfc-editor.org/rfc/rfc7565.html"&gt;RFC-7565&lt;/a&gt;
   defines this
   &lt;tt class="term"&gt;acct:&lt;/tt&gt;
   but none of the ActivityPub-related specs
   reference this scheme.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Just like, Like and Unlike?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The vocabulary only defines a
   &lt;tt class="term"&gt;Like&lt;/tt&gt;/&lt;tt class="term"&gt;Dislike&lt;/tt&gt;
   activity.
   A post might elicit a whole range of reactions
   beyond like/dislike.
   It might make me laugh,
   or cry,
   or angry,
   or high-five,
   or any of a number of other emotions/emoji.
   As swell as it is to
   &lt;tt class="term"&gt;Like&lt;/tt&gt;/&lt;tt class="term"&gt;Dislike&lt;/tt&gt;
   things,
   it really needs a generic
   &lt;tt class="term"&gt;React&lt;/tt&gt;
   action.
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;I reject your answers and substitute my own&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   When responding to a
   &lt;tt class="term"&gt;Question&lt;/tt&gt;
   it's entirely possible to provide an
   &lt;tt class="term"&gt;inReplyTo&lt;/tt&gt;
   with a
   &lt;tt class="term"&gt;name&lt;/tt&gt;
   (answer to the survey)
   that doesn't correspond
   to any of the answers
   in the original 
   &lt;tt class="term"&gt;Question&lt;/tt&gt;.
   What should happen in this case?
   Reject the answer/reply?
   Add the answer/reply
   to the list
   of existing answers?
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;Survey-respondent privacy?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Looking at
   &lt;a href="https://www.w3.org/TR/activitystreams-vocabulary/#ex192-jsonld" )example 154&lt; a&gt;
   the
   &lt;tt class="term"&gt;result&lt;/tt&gt;
   of a
   &lt;tt class="term"&gt;Question&lt;/tt&gt;
   appears to return each vote
   &lt;em&gt;along with the ID of everyone who cast each vote&lt;/em&gt;
   leaked in the
   &lt;tt class="term"&gt;attributedTo&lt;/tt&gt;
   attribute.
   Is this expected?
   Is this required,
   lest folks want their answers kept private?
  &lt;/a&gt;&lt;/p&gt;
 &lt;/dd&gt;

&lt;/dl&gt;


&lt;h2 id="activitypub3"&gt;ActivityPub (part 3)&lt;/h2&gt;

&lt;p&gt;
 Okay, now we can finally return to ActivityPub.
&lt;/p&gt;

&lt;dl&gt;

 &lt;dt&gt;Naked Objects/Links&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   If you submit a naked Object/Link
   (one that doesn't have an activity associated with it)
   the server is supposed to
   automatically convert it into a
   &lt;tt class="term"&gt;Create&lt;/tt&gt;
   activity.
  &lt;/p&gt;

  &lt;p&gt;
   However, if the message
   has been cryptographically signed
   for authentication,
   changing from a naked Object
   to an Activity also changes
   the message's cryptographic signature.
  &lt;/p&gt;

  &lt;p&gt;
   Additionally, having two source fields
   (the
   &lt;tt class="term"&gt;Create.actor&lt;/tt&gt;
   and the
   &lt;tt class="term"&gt;Create.object.attributedTo&lt;/tt&gt;)
   leaves room for a bad actor to
   create objects with mis-attribution.
   E.g. Mallory publishes a Create action
   of Bob picking his nose,
   and attributes it to Alice,
   causing Bob to get mad at Alice
   rather than Mallory.
   The spec acknowledges this as a possible issue
   &lt;/p&gt;&lt;blockquote&gt;
    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
    &lt;a href="https://www.w3.org/TR/activitypub/#obj"&gt;this example
     [Example 7]&lt;/a&gt;,
    Mallory could be spoofing
    an object allegedly posted by Alice).
   &lt;/blockquote&gt;
   However, the spec doesn't detail
   &lt;strong&gt;how&lt;/strong&gt;
   to secure against this.
   Dereferencing the ID
   only checks that
   &lt;em&gt;something&lt;/em&gt;
   exists at that URI.
   Unless it's
   &lt;em&gt;exactly the same&lt;/em&gt;
   Object content
   (which can likely change
   since we're already munging with objects,
   normalizing things, etc)
   it means we can't likely do an exact-match comparison.
   Furthermore, because objects can be Links
   and Links can consist of a URI,
   that means that the linked object-ID
   could be some protocol
   &lt;a href="https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml"&gt;other
   than HTTP or HTTPS&lt;/a&gt;.
   Does my
   &lt;q&gt;dereference the id&lt;/q&gt;
   code need to support
   &lt;tt class="term"&gt;gopher:&lt;/tt&gt;,
   &lt;tt class="term"&gt;ftp:&lt;/tt&gt;,
   &lt;tt class="term"&gt;git:&lt;/tt&gt;,
   &lt;tt class="term"&gt;svn:&lt;/tt&gt;,
   &lt;tt class="term"&gt;imap:&lt;/tt&gt;,
   &lt;tt class="term"&gt;smtp:&lt;/tt&gt;,
   &lt;tt class="term"&gt;irc:&lt;/tt&gt;,
   &lt;tt class="term"&gt;ldap:&lt;/tt&gt;,
   &lt;tt class="term"&gt;smb:&lt;/tt&gt;,
   or whatever scheme?
   Maybe the object
   refers to other URIs/resources
   that exist,
   but aren't properly attributed.
   Determining if something is
   &lt;q&gt;misrepresenting the object&lt;/q&gt;
   seems handwavey.
  
 &lt;/dd&gt;

 &lt;dt&gt;Security/authentication/authorization&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   Standards, schmandards.
   &lt;/p&gt;&lt;blockquote&gt;
    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,
    &lt;strong&gt;there are no strongly agreed upon mechanisms
    for authentication&lt;/strong&gt;.
   &lt;/blockquote&gt;
   (&lt;a href="https://www.w3.org/TR/activitypub/#authorization"&gt;source&lt;/a&gt;)
   Couldn't have made this
   &lt;a href="https://blog.thechases.com/posts/activitypub-activitystreams/#auth1"&gt;part of the initial requirements&lt;/a&gt;?
   Security is best left for an afterthought…
  
 &lt;/dd&gt;

 &lt;dt&gt;Serve it as what MIME-type now?&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
   The JSON-LD spec says to serve as
   &lt;tt class="term"&gt;application/json&lt;/tt&gt;
   while the ActivityStreams spec calls for
   &lt;tt class="term"&gt;application/activity+json&lt;/tt&gt;
   so just to be ornery,
   the ActivityPub spec mandates
   &lt;tt class="term"&gt;application/ld+json;profile="https://www.w3.org/ns/activitystreams"&lt;/tt&gt;
   as the MIME-type.
   Sure, you
   &lt;em&gt;can&lt;/em&gt;
   accept other types,
   but why not make the spec
   consistent to begin with?
  &lt;/p&gt;
 &lt;/dd&gt;


 &lt;dt&gt;&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
  &lt;/p&gt;
 &lt;/dd&gt;

 &lt;dt&gt;&lt;/dt&gt;
 &lt;dd&gt;
  &lt;p&gt;
  &lt;/p&gt;
 &lt;/dd&gt;

&lt;/dl&gt;

&lt;h2 id="activitypub4"&gt;ActivityPub (part 4)&lt;/h2&gt;

&lt;p&gt;
 So how do you go about starting the whole process?
 You use
 &lt;a href="https://datatracker.ietf.org/doc/html/rfc7033"&gt;WebFinger&lt;/a&gt;
 (which the ActivityPub,
 ActivityStreams,
 ActivityStreams Vocabulary,
 and JSON-LD specs don't mention).
 You start by hitting a
 &lt;a href="https://datatracker.ietf.org/doc/html/rfc5785"&gt;well-known&lt;/a&gt;
 URL like
 &lt;kbd&gt;https://example.com/.well-known/webfinger?resource=acct%3A&lt;var&gt;username%40example.com&lt;/var&gt;&lt;/kbd&gt;.
 This should return an initial JSON object
 describing the person,
 including their
 &lt;tt class="term"&gt;name&lt;/tt&gt;,
 &lt;tt class="term"&gt;id&lt;/tt&gt; (URI),
 &lt;tt class="term"&gt;Inbox&lt;/tt&gt;,
 &lt;tt class="term"&gt;Outbox&lt;/tt&gt;,
 cryptographic public keys,
 as well as various other properties.
 And for what it's worth,
 because we haven't already
 had enough MIME-types
 for ActivityPub data from other specs,
 WebFinger returns as
 &lt;tt class="term"&gt;application/jrd+json&lt;/tt&gt;,
 yet one more.
&lt;/p&gt;

&lt;p&gt;
 Additionally, because the well-known WebFinger URL
 &lt;strong&gt;must&lt;/strong&gt;
 be rooted at
 &lt;tt class="term"&gt;/.well-known/webfinger&lt;/tt&gt;,
 it prevents the ActivityPub server
 from being rooted in some subdirectory.
 So either the ActivityPub server needs to largely control the web-root;
 or it needs two distinct processes,
 one listening for the WebFinger request,
 and another one rooted off a name-spacing sub-resource.
&lt;/p&gt;

&lt;h2 id="auth1"&gt;Authentication, authorization, and signing&lt;/h2&gt;
&lt;p&gt;
 There's some discussion of
 &lt;a href="https://www.w3.org/wiki/SocialCG/ActivityPub/Authentication_Authorization"&gt;Authentication and Authorization&lt;/a&gt;
 but only descriptive aspects in the context of
 "this is what Mastodon does,"
 not a prescriptive
 "this is how everybody should do it."
&lt;/p&gt;
&lt;strong&gt;TODO: WIP&lt;/strong&gt;</description><category>activitypub</category><category>activitystreams</category><category>jsonld</category><category>rant</category><guid>https://blog.thechases.com/posts/activitypub-activitystreams/</guid><pubDate>Thu, 01 Feb 2024 19:35:08 GMT</pubDate></item></channel></rss>