this is aaronland

things I have written about elsewhere #20240312

Holding Hands with the "Fediverse" – ActivityPub at SFO Museum

Customer service agent scarf: Pan American World Airways. Silk. Gift of the Pan Am Association, SFO Museum Collection. 2000.058.0173

This was originally published on the SFO Museum Mills Field weblog, in March 2024.

Generally, it's not a good sign when a blog post needs to start with a glossary. This post does because it's still difficult to discuss the subject at hand with people who are unfamiliar with the terms mentioned below before they inevitably (and justifiably) stop you to say things like "Wait, the...what?!" With that in mind here are the two sentences that sum up this blog post immediately followed by a brief glossary of terms if you find yourself wondering what it all means.

SFO Museum has joined the “Fediverse”. We have begun to operate a series of automated “bot” accounts that are published using the ActivityPub protocols and that can be subscribed to from any client, like Mastodon, that support those standards.

The rest of this blog post is divided in to four sections:

  1. A brief glossary of terms which attempts to decipher and make sense of some of the technical jargon that has evolved around this thing called "ActivityPub". Unfortunately it's still not really possible to talk about why ActivityPub exists and what makes it important without these terms creeping in to the conversation.
  2. Why are we doing this? which outlines the historical context, the vision and goals for adopting ActivityPub at SFO Museum.
  3. What are we doing? which describes our initial experiments integrating ActivityPub with SFO Museum's digital initiatives. If you already understand ActivityPub and are more interested in just seeing what we're doing, before understanding why, you can start here.
  4. How are we doing this? is the technical section describing how all of this works "under the hood" and which can safely be skipped if those details don't interest you.

A brief glossary of terms

The terms that follow tend to evoke strong opinions and are not infrequently the subject of vigorous debate but these names are, as I write this, the lingua franca of the topic at hand.

If you are curious to read more The Verge's "The fediverse, explained" and Tom Coates' "How Threads will integrate with the Fediverse" are good places to start. With that out of the way, onwards!

Why are we doing this?

In the spring of 2012 I got access to a list of 50,000 artworks, and their corresponding webpages, from the collection of the Museum of Modern Art (MoMA) in New York City. Shortly afterwards I emailed the support team at Foursquare, at the time still a social location-sharing website, and asked whether they would have any concerns if I used that list to create 50,000 "venues" on their platform; one venue for each artwork in the MoMA collection. If people were already actively competing to become "mayor" of their local coffee shop it didn't seem like much a stretch to imagine that people would do the same for their favorite works of art on display at MoMA. Foursquare politely asked me not to do that. I was disappointed but not entirely surprised. Aside from all the other considerations having that many "venues" all clustered within the space of a single building, even a building as large as MoMA, likely would have introduced a host of interface problems for the service.

A couple years later, when I was working at the Cooper Hewitt Smithsonian National Design Museum, I was out with a friend who worked for Twitter and I asked them whether it would be possible for the museum to "create 200,000 Twitter accounts, one for each object in the Cooper Hewitt's collection". My friend looked at me for a moment, laughed, and then simply said: No.

Employee manual: Virgin America, social media. Paper, ink. Gift of Alaska Airlines, SFO Museum Collection. 2018.083.133

At around the same time there were already nascent efforts to try and imagine what "social messaging" would look like, untethered from the big centralized platforms like Twitter or Facebook. People asked why the kinds of messages that people exchanged on those platforms couldn't be shared in a manner similar to the way that email messages are sent and delivered to a variety of different service providers (Gmail, Hotmail, your local ISP) using a range of different clients (Gmail, Apple Mail, Outlook, etc.)

Those efforts, to imagine the protocols and the services, that would enable "decentralized" messaging picked up speed in the years after 2016 with two projects in particular garnering the bulk of people's attention: ActivityPub, the underlying protocol for social messaging that became a W3C Recommendation in 2018, and Mastodon an open-source software project that allows people to run social networking websites for communities of their choosing and which can interoperate with other Mastodon instances because they implement the ActivityPub protocols. Eventually the buzz around both ActivityPub and Mastodon quieted down but both projects kept improving, slowly and incrementally, and were ready and waiting when the interest in alternatives to large and centralized services resurfaced again in 2022.

Travel information brochure: United Air Lines, National Air Taxi Service. Paper, ink. Gift of the William Hough Collection, SFO Museum Collection. 2006.010.748

In 2023 SFO Museum spent some time experimenting with Mastodon to see where and whether it could both be integrated with our existing social media and collections-related efforts. Mastodon is a complex and sophisticated application in its own right and its software and hardware dependencies reflect that. These requirements are magnified by the complexities of the ActivityPub specifications and everything that needs to be happens in order to implement them. In the end there were always enough reasons why SFO Museum running its own Mastodon instance would be too complicated and it never came to pass. We are not the only organization pulling at these threads. In July, 2023 the BBC announced that they were experimenting with Mastodon on a trial basis and recently announced that they were extending that trial:

We were aiming to learn about how much work and cost this involved, how many people we’d reach, what levels of engagement we would get and to explore the risks and benefits of the federated model. The trial so far has been really effective in helping us learn about how the Fediverse is evolving, what technical support a Mastodon server needs, what the costs are, and how a large media organisation like the BBC can engage with the many different overlapping communities that exist in this rapidly changing space.

During our own initial invesigations I would sometimes be asked why SFO Museum was interested in pursuing Mastodon, or something ActivityPub-related. I told people that we wanted to:

1) Establish a social-media presence and platform that the Museum controls which can play nicely with larger commercial social media platforms but is independent of those same platforms. This is important because those platforms can (and often do) make decisions which adversely affect the Museum’s ability to reach its audiences and/or pursue policies that do not square with the goals and values of the airport or the City.

2) Provide a platform where the Museum can experiment with the ability to create targeted or subject-specific social media accounts for individual staff members, entire departments, artists or lenders whose work is on display or even inanimate objects like galleries or public art works, all under the “umbrella” of the Museum’s own Mastodon, or equivalent ActivityPub, instance. For example, people who travel in and out of T2 could subscribe to which, in turn, would broadcast an announcement when a new exhibition is installed. Note: The "" account does not exist...yet.

Ultimately the goal is to expand and broaden the “surface area of interests” allowing us to reach a broader audience and increasing awareness of the Museum’s programming and offerings throughout the airport and over time. To that end having a platform-agnostic means by which our visitors can subscribe to all the individual things which interest them and, simultaenously, having a multiplicity of channels through which we can send people updates about the Museum's programming is an attractive proposition.

Roll of toilet paper: EVA Air, Hello Kitty. Paper, ink. Gift of Vincent Ma, SFO Museum Collection. 2021.020.0359

Twenty-ish years in to the contemporary "social media" landscape (social networking, social messaging and sharing, social objects) it seems reasonable to ask: If people see value and meaning interacting with things that aren't "people", like venues or brands or services, then why wouldn't that same behaviour extend to individual objects in a museum? And why wouldn't a museum embrace that opportunity as a chance to share what it knows, understands and appreciates about an object beyond the limited space afforded by a wall label or an exhibition catalog, both in the moment and in the future? What happens when a new and exciting essay about an object is published and how is it shared with all the people who've seen that object in an exhibition and love it just as much the curator who chose it? Usually, if we're being honest, nothing happens.

At a very practical level, then, ActivityPub is simply the mechanical means by which that essay (or a commentary about that essay or, really, whatever) can be shared with a diverse audience without having to enter in to one or more Faustian bargains that the large (centralized) social media platforms increasingly demand. Importantly, these means can serve as a kind of vehicle by which we are able to guarantee that the objects in our collection, which by virtue of their inclusion we argue means they are worthy of repeated consideration, can enjoy a kind of repeat visitation. Even if that revisitation is virtual it fosters the practice of seeing, and re-seeing, the objects in our collections more than once.

Cargo delivery label: Transocean Air Lines. Paper, ink. Gift of the Frank J. Lichtanski Collection, SFO Museum Collection. 2011.061.0996

What are we doing?

SFO Museum has joined the "Fediverse". We have begun to operate a series of automated "bot" accounts that are published (broadcast) using the ActivityPub protocols and can be subscribed to from any client that supports those standards. In 2024 the most commonly used client is Mastodon, or third-party Mastodon clients like Phanpy or Ivory, but Meta has announced that its Threads application will start supporting ActivityPub shortly. This is the goal of the "Fediverse": For SFO Museum to be able host and publish these accounts from our own servers and for people to be able to subscribe to them from the clients and platforms of their choosing.

As mentioned these are automated, low-frequency, accounts and, currently, only a limited set of interactions are supported: Accounts can be followed or unfollowed, individual posts can be "liked", "boosted" or replied to but those replies will not be answered (yet) or published on the SFO Museum websites. To get started we've created three "groups" of accounts. They are: Things which have happened recently involving the SFO Museum Aviation Collection; Things which have happened in the terminals (new and old) and; Things from the collection which are related to flights in and out of SFO.

Things which have happened recently

These accounts republish individual objects from already existing webpages on the SFO Museum Aviation Collection website. They are:

Things which have happened in the terminals

We have also set up accounts for the individual terminals, past and present, at SFO. These accounts will publish installation photos of the over 40 years worth of exhibitions that have been mounted in their respective terminals. They are:

Things involving flights in and out of SFO

SFO Museum has been harvesting data for flights in and out of SFO since 2006. We have collected records for over 7 million individual flights and since 2019 that data has usually included the unique registration number (commonly referred to as the "tail number") assigned to each aircraft resulting in flight data for approximately 6,000 individual aircraft that have arrived at or departed from SFO.

The obvious thing to do is to create an ActivyPub account for each one of those airplanes, right? So we did! For example:

Although we haven't yet automated the addition of new aircraft the chances are good that when you look out the window at SFO most, if not all, of the airplanes you see will have their own ActivityPub account. There are 6,000 (and counting) accounts so I won't list them all here. We do have webpages for all the aircraft as well as each individual tail number and every one of those webpages includes the relevant ActivityPub address for aircraft in question.

Each aircraft account will publish a new post every day describing a flight it took and include an item from the SFO Museum Aviation Collection related to the original airport, the destination airport or the airline operating that flight. If this sounds a lot like the work described in the Browsing the SFO Museum Aviation Collection Through Real Time Flight Data blog post that's because it is, but seen through the filter of historical rather than real time flights.

We have also created ActivityPub accounts for all the airports that intersect with the Aviation Collection and airlines are soon to follow. Airport accounts take the form of "three-letter airport code" + "airport" (for example but as of this writing they are still inactive while we determine what they will "do".

If you are starting to wonder whether we are going to create individual ActivityPub accounts for each and every object in the SFO Museum Aviation Collection the answer is quite simply: Yes, but we've started with aircraft tail numbers to better understand the mechanics and operational concerns of servicing a large number of automated accounts before moving on to the collection itself. If you are starting to wonder whether there is anything we won't create an ActivityPub account for (galleries, individual exhibitions, gates at the airport...) the answer is: Probably not.

The rest of this blog post gets is about some of the technical details of how we implemented this work. If you aren't interested in that this is a good place to stop reading and we invite you to subscribe to any or all of the accounts listed above and follow along as we explore what it means for a museum to hold hands with the Fediverse.

How are we doing this?

I've already mentioned that Mastodon has proven to be too involved for SFO Museum to want to run its own dedicated instance. The same is true of other software packages that only implement the ActivityPub standards without any user interface. Importantly, there is nothing wrong with any of these projects, they just haven't been the right "fit" for SFO Museum. So what did we do? We built our own minimal implementation of the ActivityPub protocols initially targeting automated "bot" accounts designed to share objects and other materials already available on the SFO Museum Aviation Collection and Mills Field websites. We did this to better understand the ActivityPub specifications, from end to end, and to consider design and architectural approaches to minimize the operational costs and maintenance of running our own ActivityPub services.

So, what actually needs to happen to make it possible for two, or more, people to exchange messages using ActivityPub? Let's say there are two people, Bob and Alice, who want to exchange messages. A "message" might be text or images or video of some combination of all three. An "exchange" is the act of sending those messages from one person to another using an email-like addressing scheme but instead of using an email-specific protocol messages are sent over HTTP(S).

  1. There needs to be one or more web servers (services) to broker the exchange of messages between Bob and Alice.
  2. Those web services need to have the concept of "member" accounts, in this case Bob or Alice, each of which has their own public and private encryption keys.
  3. Each web service needs to implement an endpoint for looking up other ActivityPub-specific endpoints for each member account, namely there ActivityPub "inbox" and "outbox".
  4. Some kind of persistent database for the web service to store information about member accounts, relationships between individual members and the people they want to send and receive messages from, the messages that have been sent and the messages that have been received.
  5. Though not required an additional database to track accounts that an individual member does not want to interact with, referred to here as "blocking", is generally considered to be an unfortunate necessity in 2024.
  6. A delivery mechanism to send messages published by Alice to all the people who have "followed" them (in this case Bob). The act of delivering a message consists of Alice sending that message to their "outbox" with a list of recipients. The "outbox" is resposible for coordinating the process of relaying that message to each recipient's ActivityPub (web service) "inbox".
  7. In practice you will also need somewhere to store and serve account icon images from. This might be a filesystem, a remote hosting storage system (like AWS S3) or even by storing the images as base64-encoded blobs in one or your databases. The point is that there is a requirement for this whole other layer of generating, storing, tracking and serving account icon images.
Photograph: Pan American Airways, Boeing 314. Photograph. Gift of M.D. Klaas, SFO Museum Collection. 2018.112.0557

To recap, we've got:

  1. A web server with a minimum of four endpoints: webfinger, actor, inbox and outbox.
  2. A database with the following tables: accounts, followers, following, posts, messages, blocks.
  3. Two member accounts: Bob and Alice.
  4. A delivery mechanism for sending messages; this might be an in-process loop or an asynchronous message queue but the point is that it is a sufficiently unique part of the process that it deserves to be thought of as distinct from the web server or the database.
  5. A web server, or equivalent platform, for storing and serving account icon images.

For the purposes of these examples and for testing the assumption is that Bob and Alice have member accounts on the same server. Importantly, please note that there is no mention of how Bob or Alice are authenticated or authorized on the web server itself. The public-private key pairs, mentioned above, that are assigned to each member are solely for the purposes of signing and verifying messages send between one or more ActivityPub endpoints. In practice, once you've finished supporting additional features such as "liking" or "boosting" you end up with upwards of not just four but actually eleven separate database tables and all the code necessary to manage them. While far from impossible it is still, as the expression goes, a "non-trivial" setup. That's the bad news.

Menu: Pan American World Airways, Rainbow (economy) class. Paper, ink. Gift of Thomas G. Dragges, SFO Museum Collection. 2014.095.201

The good news is that we have managed to implement all of this functionality in a low-cost, "serverless" deployment using a small number of AWS services consisting of:

  1. A set of DynamoDB tables that function as the database layer.
  2. A Lambda function that implements all of the server logic.
  3. An S3 bucket for hosting and serving account profile icons.
  4. An SQS messaging queue to handle dispatching messages to individual followers.
  5. A second Lambda function that handles the work of dispatching an individual message to a specific address.

I've left out the code and the infrastructure which generates messages since that is SFO Museum specific. Here are some important characteristics of what we've built:

Most importantly the code itself is not dependent on AWS infrastructure. That's just a configuration option. The same code can be run on a bare-metal Linux server running a relational database, like MySQL (or even your laptop and SQLite) using a messaging queue of your own choosing. This is code designed to provide a simple and cost-effective way to deploy the minimal subset of ActivityPub-related functionality required to service a large number of automated accounts. We have open-sourced this code and you can see it at:

The documentation for this code is incomplete reflecting the nature of our work to first understand the mechanics, and second explore the tolerances, of the ActivityPub protocols. In advance of more comprehensive documentation we have set a GitHub "Discussions" group where people can ask questions or offer suggestions:

This is code that was written by and for SFO Museum but has hopefully been designed in a way that any other museum could use it to spin up a large number of ActivityPub accounts for their own collections and programming. If that happened we would then be faced with the challenge and opportunity of making all those accounts "talk" to one another which feels like it would be a good problem to have.

Postcard: Virgin America. Paper, ink. Gift of Sirena Lam, SFO Museum Collection. 2019.032.106