Note
このドキュメントは2026-02-27 02:39にPLaMo Translation Modelを使用して自動翻訳されました。
FEP-db0e: 非公開グループへのアクセス認証メカニズム
概要
本提案は、非公開グループのコンテンツに対するアクセス認証問題を解決するものである。主にFEP-400eを補完することを目的としている。
Groupアクターがホストするサーバーのみが、当該グループ内のコンテンツに誰がアクセス可能で誰ができないかを確定的に把握できる。しかしながら、各オブジェクトは作成者であるアクターのサーバー上に配置されるため、通常は他のサーバーがそのオブジェクトへのアクセス権を、その内容を閲覧する権限を持つ特定のアクターのみに限定することは困難である。
本FEPでは「アクタートークン」という認証メカニズムを定義する。これにより、あるアクターが他のサーバーに対してグループメンバーシップの一時的な証明として機能するトークンを発行することが可能となる。
要件
本仕様書における「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」といった用語は、[RFC-2119]の規定に従って解釈されるものとする。
グループホストサーバーからのコンテンツ取得方法
グループをホストするサーバー(非公開グループの場合はGroupアクター自身を含む)からオブジェクトを取得する際、要求元サーバーはGETリクエストにHTTP署名を付与しなければならない。この署名には任意のアクターの公開鍵を使用する必要がある。この目的においては、例えばSmithereenにおける/activitypub/serviceActorのようなサーバー全体で共有されるサービスアクターを使用することが推奨される。この理由として、ほとんどのActivityPubサーバーは、当該オブジェクトに関心を持つすべてのユーザーに対して単一のコピーのみを取得・保存する運用形態を取っており、可視性に関する規則が存在する場合、その適用責任も自ら負うためである。
アクタートークンの使用方法
他のサーバーからオブジェクトを取得するプロセスでは、「アクタートークン」が必要となる。アクタートークンとは、グループメンバーシップを証明する暗号学的に署名された一時的な証明書である。失効メカニズムを実装することは現実的ではないため、アクタートークンには有効期限が設けられており、これはメンバーがグループを離脱した場合や強制的に削除された場合などのケースに対応するためである。
アクタートークンの構造
アクタートークンは以下の必須フィールドを含むJSONオブジェクトである:
issuer: このトークンを生成したアクターのIDactor: トークンが発行される対象アクターのID(かつ有効なHTTP署名とともに提示する必要がある)issuedAt: トークン生成時刻を示すISO-8601形式のタイムスタンプvalidUntil: トークンの有効期限を示すISO-8601形式のタイムスタンプsignatures: 現在以下の単一必須要素からなる署名オブジェクト配列:algorithm: 文字列"rsa-sha256"でなければならないkeyId: HTTP署名で使用されるものと同じ鍵ID(例:https://example.com/groups/1#main-key)signature: RSA-SHA256署名そのものをbase64エンコードした形式。詳細は後述
sm:actorTokenエンドポイント
アクタートークンを発行可能なアクターは、endpointsオブジェクト内にsm:actorTokenエンドポイント(ここでsmはJSON-LD名前空間http://smithereen.software/ns#のエイリアス)を備えている。このエンドポイントは署名付きGETリクエストを受け付け、対応するアクタートークンを返す。
アクタートークンの利用方法
オブジェクト取得時にアクタートークンを使用する場合、HTTPヘッダーとしてAuthorization: ActivityPubActorToken {...}形式で指定する。
署名用ソース文字列の生成手順
- アクタートークンJSONオブジェクト内のキーを反復処理し、
signatureフィールドはスキップして、各値を"key: value"形式に変換する。これらの文字列を配列に追加する。 - 得られた配列を辞書順にソートする。
- 改行文字(
\n、U+000A)で文字列を結合する。 - 生成された文字列をUTF-8バイト配列に変換する。
アクタートークンの生成手順
- HTTP署名に基づき、要求元アクターがグループへのアクセス権を有することを確認する(同一ドメインに属するメンバーが存在する場合)。アクセス権限がない場合、直ちに403エラーを返して処理を停止しなければならない。
- 上記のフィールドすべてを含むJSONオブジェクトを作成する(ただし
signatureは除く)。有効期間は30分間を推奨し、最長でも2時間を超えないようにすること。 - 前述の手順に従って署名用ソース文字列を生成し、それを暗号化して
signature,algorithm,keyIdフィールドを持つオブジェクトに格納する。 - このオブジェクトを
signatures配列の単一要素として追加する。 - 生成されたJSONオブジェクトをクライアントに返却する。
アクタートークンの検証手順
- HTTP署名が有効であること、およびトークンオブジェクト内の
actorがHTTP署名中のkeyIdと一致することを確認する。いずれかが不一致の場合、直ちに403エラーを返して処理を停止しなければならない。 signatures配列内でalgorithmフィールドが"rsa-sha256"に設定されているオブジェクトを探し、対応するsignature値を取得する。もし該当するオブジェクトが存在しない場合も403エラーを返し、処理を停止する。- 有効期間を確認する:
issuedAtは過去の時刻でなければならないvalidUntilは未来の時刻でなければならない- 両者の差は2時間を超えてはならない これらのチェックには時計設定の不正確さを考慮したマージンを設けることが推奨される。Smithereenでは5分間の余裕を持たせている。
- 前述の手順に従って署名用ソース文字列を再生成し、署名を検証する。
- 要求元がアクセスしようとしているオブジェクトが、実際に
issuerが所有するコレクションに属していることを確認する。 - 上記すべてのチェックを通過した場合、要求されたオブジェクトを返却する。いずれかのチェックに失敗した場合は、直ちに403エラーを返す。
アクタートークンオブジェクトの具体例
{
"issuer":"https://friends.grishka.me/groups/75",
"actor":"https://activitypub.academy/actor",
"issuedAt":"2024-05-03T14:02:18.680404311Z",
"validUntil":"2024-05-03T14:32:18.680404311Z",
"signatures":[
{
"algorithm":"rsa-sha256",
"keyId":"https://friends.grishka.me/groups/75#main-key",
"signature":"w+W1nNV+XBvXi8sDEUZB7muWSSnv1mEE4tNZJqF5LeoxAstBMiBZi8dtHF+v+vXKVPWBAdZUKLS5CttmgZ4tvnvZAfsBztCjYLyiolVQ71IO2Jxlu00Xo9FDoSTRZ61tXdfWufuzs5lRjG3t+S1t1lLllBFmvPLg6BwmdEPvlZvPYnTJzwNY0ljOjickPqfyvdzIslmdYX6dPC0Ayyi028ZmR2SN1Vooc9vnUQ7GMPrlAZtmXgjCVGw5X/cKlAVvGECxRjJnkKEKiLp3lv/SM1UUhP3VRpBSFhXnRX/1QhTUaFV1MhrfDFgWGPg8ypIf6O/M52+iSpJyIOGepmjmow=="
}
]
}
実装例
参考文献
- Christine Lemmer Webber, Jessica Tallon, ActivityPub, 2018
- Gregory Klyushnikov, Publicly-appendable ActivityPub collections, 2021
- [RFC-2119] S. Bradner, Key words for use in RFCs to Indicate Requirement Levels
著作権
CC0 1.0 Universal(CC0 1.0)パブリックドメイン献呈
法律で許容される範囲内において、本Fediverse Enhancement Proposalの著者らは、当該著作物に関するすべての著作権および関連する権利を放棄する。