☁️

CloudflareがMastodonに対応したActivityPub実装、Wildebeestを作ってたので紹介します。一部有料です

2023/01/10に公開約9,400字

Intro

一応私はActivityPubの専門家として活動しているので、恥じないようActivityPubに関するエゴサーチを毎日しています。
仕事の昼休み中エゴサーチをしていたところ以下のGitHubリポジトリを紹介していたTweetが目に入りました。

https://github.com/cloudflare/wildebeest

おや??????
CloudflareのGitHubリポジトリだ……。

どうやらSven-sanをはじめとしたCloudflareに勤務している5名のチームで始まったプロジェクトのようです。(最初のコミット"Import wildebeest code"にて確認)

ActivityPub実装って難しいよねわかると思いながらコードを読みました。

完成度がヤバい。

ヤバいヤバいヤバい。

マジでヤバいActivityPub実装が登場したので紹介します。

Wildebeest

2023/01/10現在のWildebeestのREADME.mdを読んでみましょう。

WildebeestはActivityPubMastodonに対応したサーバーで、インフラを維持する必要なく、誰でも自分のドメインでFediverseサーバーとアイデンティティを運用でき、最小限の設定とメンテナンスで、数分で動作することを目的としています。
WildebeestはCloudflareのSupercloud上で動作し、WorkersPages、メタデータと設定を保存するD1 database、認証を処理するZero Trust Access、メディア処理を行うImagesを使用します。
現在、Wildebeestは以下の機能をサポートしています。
・認証とプロファイルの自動作成
・メッセージの署名と通知
・受信箱と送信箱のメモ(テキスト、メンション、画像)、フォロー、アナウンス(リブログ)、アクセプト(友達)、いいね
・サーバー間のフェデレーション
・コンテンツ探索のためのウェブクライアント(読み取り専用)
・他のMastodonクライアントとの互換性(モバイルiOS/Androidおよびウェブ)
Cloudflareは、このオープンソースプロジェクトを進化させ、時間をかけて機能を追加し、コミュニティのフィードバックに耳を傾けながら、優先順位を決定していきます。
プルリクエストや課題も歓迎します。

とりあえずMastodon流行っているしいっちょかみしてみるか程度かな? と最初は思ったのですがやる気に満ち溢れており、現時点でもある程度機能が実装されているようです。

何よりCloudflareが提供しているサービスを余すことなく使用されていることに驚くばかりです。
続けてRequirementsを読んでみましょう。

WildebeestはCloudflare Pages上でPages Functionsを使用して動作するフルスタックアプリケーションです。
もちろん、Cloudflareアカウントをお持ちで、Cloudflareを使用したzoneを少なくとも1つお持ちであることを前提としています。
zoneをお持ちでない場合は、Cloudflare Registrarを使用して新しいドメインを登録したり、既存のドメインをtransferしたりすることができます。
データの永続化、アクセス制御、メディアストレージなどの一部の機能は、他のCloudflare製品で扱われます。
・データベースはD1
・オブジェクトキャッシュにはWorkers KVを使用します
Zero Trust Accessは、any identity providerでのユーザー認証とSSOを処理します
・メディアを扱うImages
ほとんどの製品では、ビジネスクリティカルではない個人的なプロジェクトや趣味のプロジェクトで試用できるよう、寛大な無料プランを提供しています。
ただし、Imagesプランのいずれかを有効にする必要があります。

なるほど。
Imagesに関しては別途プランを選択する必要があるんですね。
Cloudflare PagesということはやはりCloudflare Workersを使うのでしょうか。
Getting Startedを読み進めてみましょう(2023/01/12更新)

WildebeestはDeploy to Workersを使用して、インストール プロセスを自動化します。
インストールプロセスに関わるすべてのステップに注意してください。
・WorkersがGitHubアカウントを使用することを承認します
・Account IDと、以前作成したAPI トークンを入力します
・Zone ID、Domain、Title、Admin Email、Descriptionでインスタンス/プロジェクトの設定を行います
・リポジトリをGitHubの個人アカウントにフォークします
・GitHub Actionsを有効にします
・デプロイします

途中"Deploy with Workers"のリンクがありました。
Terraformを使いものすごく簡単にインストール出来るようになっているようです。
インストール後はどのように使うのでしょうか。
Supported Clientsを読みます。

WildebeestはMastodon APIと互換性があるため、ほとんどのウェブ、デスクトップ、モバイル クライアントを使用することができるはずです。
しかし、このプロジェクトは進行中であり、ニュアンスの違いにより機能の一部に影響が出る可能性があります。
以下は、Wildebeestの開発とテストを行う中で、私たちがうまく使っているクライアントのリストです。
Pinaforeウェブクライアント
iOSおよびAndroid用のMastodon officialモバイルクライアント
また、WilebeestはインスタンスURLで読み取り専用のウェブクライアントを提供しており、タイムライン(ローカルおよびフェデレート)、投稿、プロフィールを探索することができます。このウェブクライアントの改良を続け、最終的にはコンテンツの投稿もサポートする予定です。

ひとまずクライアントをMastodon公式アプリやサードパーティクライアントに任せて、最低限の読み取り専用クライアントを用意する点は簡単に低コストで運用できるActivityPub実装、GoToSocialにとても似ていますね。
ただ最終的にはコンテンツの投稿もサポートする予定のためMastodonをはじめとした他のActivityPub実装のようにWebから気軽に使えるものになるようです。

https://github.com/superseriousbusiness/gotosocial

ちなみにWildebeestはApache License 2.0のようです。
多くのActivityPub実装はGNU AGPLv3なので、ライセンスが原因で躊躇していた人も気軽に運用できそうですね。

Code Reading

軽くですがソースコードを読んでみましょう。
まずはpackage.jsonから。

https://github.com/cloudflare/wildebeest/blob/f2611f6cd6f29e362f8d48f7398901688301bb83/package.json

devDependencies以外のパッケージはCookieとHTTP Message Signaturesに関するライブラリのみのようです。
Webアプリケーションフレームワークは使用していないみたいですね。
ただこのHTTP Message Signaturesパッケージは初めて見ました。

https://github.com/dhensby/node-http-message-signatures

どうやら2021年頃から開発されている最新のHTTP Message Signatures仕様も実装しているパッケージのようです。

https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/

Mastodonが使用しているHTTP Message Signatures仕様は非常に古いのですが、もうすぐHTTP Message SignaturesはIETFでRFCとして標準化されるためMastodon以上に「正しい」ActivityPub実装になるかもしれません。

どうやらフロントエンドにもpackage.jsonがあるようですので確認します。

https://github.com/cloudflare/wildebeest/blob/f2611f6cd6f29e362f8d48f7398901688301bb83/frontend/package.json

devDependencies以外のパッケージはCSSリセットを行うModern Normalizeしか依存関係しかないようです。
直接HTMLにコードを書いているのか???

そんなわけないですよね。
devDependenciesにQwikがありました。

https://github.com/cloudflare/wildebeest/tree/f2611f6cd6f29e362f8d48f7398901688301bb83/frontend

フロントエンド"Wildebeest UI"のREADME.mdにはこう書いてあります。

このサイトは、クライアント側のJavaScriptコード、静的アセット、サーバー側のレンダリングを行うCloudflare Pages Functionで構成されるQwikフレームワークを使用して構築されています。

マイクロフロントエンドアーキテクチャと呼ばれるやつですね。
以前読んだことがあります。

https://blog.cloudflare.com/better-micro-frontends/

https://zenn.dev/laiso/articles/972b9d82030542

とにかく最先端技術が使われているこのソースコードですが、ActivityPub実装部分はどうでしょうか。
ActivityPub実装を見てきたり作ってきた経験を活かしSourcegraphで検索してみました。

  • well-known

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+well-known&patternType=standard&sm=1

  • webfinger

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+webfinger&patternType=standard&sm=1

  • jrd+json

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+jrd%2Bjson&patternType=standard&sm=1

  • @context

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+%40context&patternType=standard&sm=1

  • activitystreams

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+activitystreams&patternType=standard&sm=1

  • security

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+security&patternType=standard&sm=1

  • activity+json

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+activity%2Bjson&patternType=standard&sm=1

  • keyid

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+keyid&patternType=standard&sm=1

  • crypto.subtle.sign

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+crypto.subtle.sign&patternType=standard&sm=1

  • crypto.subtle.verify

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+crypto.subtle.verify&patternType=standard&sm=1

Webアプリケーションフレームワークは使用していないのでFetch APIを確認しましょう。
fetch()はServer to ServerのFederationでも使用します。
ちなみに"new Headers"はありませんでした。

  • new Request

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+content:"new+Request"&patternType=standard&sm=1

  • new Response

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+content:"new+Response"&patternType=standard&sm=1

  • fetch

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+fetch&patternType=standard&sm=1

Mastodon APIはv1だけではなくv2も実装されていました。すごい。

  • api/v1

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+api/v1&patternType=standard&sm=1

  • api/v2

https://sourcegraph.com/search?q=context:global+repo:^github\.com/cloudflare/wildebeest%24+api/v2&patternType=standard&sm=1

ただ以下の実装は現時点ではないようです。
今後に期待ですね。

  • nodeinfo
  • ld+json

もっと詳しく知りたい人は私が作ったActivityPub実装Matchboxと比較してみてください。
ちなみにMatchboxはMIT Licenseです。

https://gitlab.com/acefed/matchbox

https://zenn.dev/tkithrta/articles/a33c27d7f895b5

https://zenn.dev/tkithrta/articles/2a524a4b1e4ac8

Outro

Code Readingの最後にも触れましたが私はDenoとHono、BunとHonoでActivityPub実装を作ったことがあります。
ただCloudflare Workersには対応していないんですね。
理由としては、Cloudflare WorkersをはじめとしたCloudflareサービス全てを完全に理解する必要があり、Cloudflareのヘビーユーザーでも難しい話です。
そもそもCloudflareのアカウント持っていないのもあり……。

少し前にCloudflareでセルフホストできるCMS、microfeedがActivityPub実装予定である話を聞きましたがまだサポートされていないようです。
https://github.com/microfeed/microfeed/discussions/34

他にもMinipubという、ポッドキャストのRSSフィード向けに作られたActivityPub実装もあります。
https://minipub.dev/

こちらはDenoflareの開発元が作っているためCloudflare Workers上のDenoで動かすことを想定しているようです。
https://denoflare.dev/

そして今回なんとCloudflareのCloudflareによるCloudflareのためのActivityPub実装が公開されました。
Mastodon公式クライアントアプリと互換性があるためActivityPubやFediverseを知らない人でも簡単に始めることができ、低スペックなVPSやお金がものすごくかかるクラウドサービスとは異なりCloudflareならサービスを維持できるだろうという安心感を感じる人も多いのではないのでしょうか。

Wildebeestを紹介するにあたりSupercloudという単語が出てきました。
https://blog.cloudflare.com/ja-jp/welcome-to-the-supercloud-and-developer-week-2022-ja-jp/

Supercloudによって、牧歌的に個人が開発しているFediverseが色々な意味で変わりそうです。
さて、これからどうなるのでしょうか……。
ぬー。

Discussion

ログインするとコメントできます