mastodon
ActivityPub

ActivityPubの概要

この記事はドワンゴ Advent Calendar 2017Mastodon Advent Calendar 2017の三日目の記事です。
本当は「で、結局Mastodonって何だったの?」をアドベントカレンダーに載せたかったのですが、先に公開してしまったものを載せても仕方がないので軽くMastodonの連合の仕組みを説明したいと思います。

ActivityPub: Mastodonの連合を支えるプロトコル

前述のとおり、Mastodonの最大の特徴は連合です。連合とは、Mastodonインスタンスという敷居を跨いだユーザー同士のやりとりを可能にする仕組みのことです。 Mastodonインスタンス同士はOStatusやActivityPubといった特定のプロトコルを介してつながっています。

Mastodonは、バージョン1.6以前はOStatusと呼ばれるGNU social互換のプロトコルのみで他インスタンスとの連合を行っていました。しかし、OStatusでは投稿の公開範囲に関して細かな規定がなされておらず、一人でもGNU socialのインスタンスに所属している人がフォロワーにいた場合、プライベートな投稿の内容がそちら経由で漏れてしまうなどの問題が発生していました。そこで、Mastodon 1.6.0からメインの連合プロトコルをActivityPubへと転換し、2.0.0からはOStatus経由ではプライベートな投稿が連合されなくなりました。

ActivityPubとは?

ActivityPubは、分散ソーシャルネットワーキングのプロトコルの1つで、以下の2つを定義しています。

  1. サーバー⇔サーバー間の連合プロトコル - 分散SNSの実装がどのようにデータをやりとりするのか
  2. クライアント⇔サーバー間のプロトコル - ユーザーやその代行者としての(デスクトップ|スマートフォン|Web)アプリがActivityPub対応のサーバーとどうやり取りするのか

Mastodonでは現状、連合プロトコルにはActivityPubを使用していますが、クライアント⇔サーバー間の通信に関しては独自のAPIを採用しています。

ActivityPubでは、すべてのデータは基本的にはActivity Streams 2.0のオブジェクトとして扱い、サーバー間ではJSON-LD互換の形式にエンコードしてやり取りされています。一時的に必要となるだけの(transientな)オブジェクトを除いて、すべてのオブジェクトにはURI/IRIによるIDが割り振られています。Activity Streams 2.0のオブジェクトには、以下のようなものがあります:

  • Object

    • 投稿など、一般的なオブジェクト

      Type 説明
      Article ブログ記事など、複数段落にわたるような長い文章
      Audio 音声データ
      Document ドキュメント
      Event イベント
      Image 画像
      Note TwitterやMastodonの投稿など、短い文章
      Page Webページ
      Place 論理的(例: 仕事)/物理的(例: 35°41'54.0"N 139°46'18.3"E)な場所
      Profile ほかのオブジェクトを説明するコンテンツ
      Relationship 2つの個人間の関係を説明するオブジェクト
      Tombstone Collection内などで、削除されたオブジェクトのかわりに置かれる
      Video 動画
    • Actor (ユーザーなど)

      Type 説明
      Application ソフトウェアアプリケーション
      Group Actorの集合
      Organization 組織
      Person 個人
      Service あらゆるサービス
    • Activity (新しい投稿をする、投稿をお気に入りに登録する、フォローリクエストするなどアクターの起こしたアクション)

      Type 説明
      Accept actorobject(例: Invite)を承認したことを示す
      Add actortargetobjectを追加したことを示す
      Announce actortargetobjectを見てほしいと思っていることを示す (= ブースト)
      Arrive actorlocationに到着したことを示す
      Block actorobjectをブロックしたことを示す。ActivityPubではサーバー間で連合されないことになっている
      Create actorobjectを作成した(=投稿した)ことを示す
      Delete actorobjectを削除したことを示す
      Dislike actorobjectを「よくないね」と思っていることを示す
      Flag actorobjectを通報したことを示す
      Follow actorobjectをフォローしたことを示す
      Ignore actorobjectを無視すること(おそらくミュート)を示す
      Invite actorobjectへの招待をtargetに送ったことを示す。Offerの特殊版
      Join actorobjectへ参加したことを示す
      Leave actorobjectから離脱したことを示す (どうやらArrive, Joinの両方の逆の意味を持っているらしい?)
      Like actorobjectを「いいね」と思っていることを示す
      Listen actorobjectを聞いたことを示す
      Move actorobjectoriginからtargetへ移動したことを示す
      Offer actorobjecttargetにオファーしていることを示す
      Question 質問を表現している。anyOf, oneOfで選択肢を提示することができる (両方同時に存在してはならない)
      Reject actorobjectを拒絶したことを示す
      Read actorobjectを読んだことを示す
      Remove actorobjectを削除したことを示す。originが指定することによってどこからobjectが削除されるのかを指定することができる
      TentativeReject Rejectの特殊版。actorobjectを仮拒絶したことを示す
      TentativeAccept Acceptの特殊版。actorobjectを仮承諾したことを示す
      Travel actororiginからtargetへ旅をしていることを示す
      Undo actorobjectをアンドゥしたことを示す。objectは大体Actorの1つである (例: ふぁぼを取り消す時はLikeアクティビティをUndoする)
      Update actorobjectを更新したことを示す。Activity Streams 2.0では特段どのように更新されたかなどの取り決めはなされていないが、ActivityPubによって規定がなされている
      View actorobjectを見たことを示す
    • Collection (投稿やフォロワーの一覧、inboxやoutboxなど)

ここで興味深いのは、ユーザーの起こしたアクションなどもすべてオブジェクトの一種として扱われることです。このオブジェクトとして表現されたアクティビティをあらかじめ定められたルールに従って他インスタンスへ転送することによって、Mastodonは連合という仕組みを実現しています。これらの転送の仕組みを定義しているのがActivityPubです。

では実際、ActivityPubでアクティビティの転送はどのように定義されているのでしょうか。

ActivityPubによるサーバー間のデータ転送

ActivityPubでは、すべてのActorオブジェクトにinbox, outboxという2つのプロパティを定義することを要件づけています。inboxはActorが受け取ったすべてのアクティビティのOrderdCollection、outboxはActorが行ったすべてのアクティビティのOrderedCollectionです。

他インスタンスのアクターへアクティビティを転送する際には、転送先のアクターのinboxへHTTP POSTを行うことによって転送を行います。大規模なインスタンスでは複数のサーバーで動いている場合もありますし、ブーストを行う場合など、送信側・受信側のどちらでもない第三のインスタンスのアクティビティを転送する必要がある場合もあるので、Activity StreamsではLinked Data Signatureを用いたオブジェクトへの署名と検証を行うことが推奨されています。

おわりに

執筆時間が短かったせいもあって、結構駆け足になってしまいました。しかし、ActivityPubでどのようなものが表現できるかもしれないかということについては少しご理解いただけたかと思います。

ActivityPubはまだ未完成な規格です。特に認証周りやコンテンツをどのように表現してやりとりをするか、ユーザーのIDをどのようにルックアップするのかといった部分があまりはっきりと定まっていないイメージが感じられます。Mastodonでは認証周りはほぼ投げてしまっていますし、コンテンツは許可タグ以外のエスケープ処理がなされたHTMLが使われていますし、ユーザーIDはOStatusだった頃の仕様を引きずってWebFingerを用いています。ActivityPubの将来に期待しましょう。