Skip to content

Latest commit

 

History

History
105 lines (74 loc) · 6.49 KB

42.md

File metadata and controls

105 lines (74 loc) · 6.49 KB

NIP-42

リレーに対するクライアントの認証

draft optional

このNIPはクライアントが一時的なイベントに署名することでリレーに対して認証する方法を定義する。

動機

リレーは、制限されたリソースにアクセスしようとするクライアントに認証を要求したくなる場合がある。例えば:

  • リレーはクライアントからのイベントの送信に対して支払いまたはその他の形式のホワイトリスト登録を要求する可能性がある。 -- これは素朴には送信できるイベントをホワイトリストに登録された鍵で署名されたもののみに制限することで達成されるが、このNIPを使用すれば、認証されたユーザから送信されたイベントであればどのようなイベントでもリレーはそれを受け入れるかを選択できる。
  • リレーはkind: 4DMへのアクセスをそれを交換している当事者のみに制限する可能性があり、そしてそのためにクラアントが同kindをクエリする前に認証を要求したいかもしれない。
  • リレーはあらゆる種類の購読を課金ユーザまたは他の何らかの手段でホワイトリスト登録されたユーザのみに限定する可能性があり、そのために認証が必要かもしれない。

定義

クライアント-リレー間の新しいプロトコルメッセージ

このNIPは新しいメッセージAUTHを定義する。このメッセージを、リレーは認証をサポートするときクライアントに、クライアントは認証したいときリレーに送信してもよい (CAN)。リレーによって送信された場合、メッセージは以下の形式を取る:

["AUTH", <challenge-string>]

クライアントによって送信された場合は、以下の形式を取る:

["AUTH", <signed-event-json>]

クライアントによって送信されたAUTHメッセージに対しては、EVENTメッセージに対してそうするように、OKメッセージで応答されなければならない (MUST)。

正規の認証イベント

署名されたイベント (<signed-event-json>) は送信またはクエリされることを意図していない一時的なイベントであり、kind: 22242でなければならず、かつ少なくとも2つのタグ -- すなわちひとつにリレーのURLを、そしてもうひとつにリレーから受け取ったチャレンジ文字列 (<challenge-string>) を持っているべきである。リレーはkind: 22242イベントをクライアントへのブロードキャストから除かなければならない (MUST)。created_atは現在時刻であるべきだ。イベントの例を次に示す:

{
  "kind": 22242,
  "tags": [
    ["relay", "wss://relay.example.com/"],
    ["challenge", "challengestringhere"]
  ],
  // other fields...
}

OKCLOSED における機械可読な接頭辞

このNIPは(クライアントによるイベント書き込みへの応答としての)OKと(クライアントが要求したが拒否された購読への応答としての)CLOSEDの中で使用可能な2つの新しい接頭辞を定義する。

  • "auth-required: " - リレーがクエリまたはイベントの書き込みを受理するため必要であるにも関わらず、クライアントがAUTHを完了していない場合。
  • "restricted: " - クライアントはAUTHを正常に完了したが、認証に使用された鍵がまだリレーに許可されていないか、その認可を超過している場合。

プロトコルの流れ

リレーはいつでもチャレンジ文字列を含むAUTHメッセージをクライアントに送信してもよい。このチャレンジは接続期間中、または異なるチャレンジがリレーから送信されるまで有効である。クライアントはいかなる瞬間に対応するAUTHイベントを送信することを決定してもよく(MAY)、認証されたセッションは接続を通して有効である。

auth-required in response to a REQ message

特定の処理のみ、例えばREQへの応答やEVENT書き込みの受理のみにリレーはクライアントに認証を求める可能性が高いことを加味すれば、これらが期待される一般的な流れとなる:

relay: ["AUTH", "<challenge>"]
client: ["REQ", "sub_1", {"kinds": [4]}]
relay: ["CLOSED", "sub_1", "auth-required: we can't serve DMs to unauthenticated users"]
client: ["AUTH", {"id": "abcdef...", ...}]
relay: ["OK", "abcdef...", true, ""]
client: ["REQ", "sub_1", {"kinds": [4]}]
relay: ["EVENT", "sub_1", {...}]
relay: ["EVENT", "sub_1", {...}]
relay: ["EVENT", "sub_1", {...}]
relay: ["EVENT", "sub_1", {...}]
...

このケースにおいて、リレーからのAUTHメッセージはクライアントが接続した直前に送信されてもよいし、CLOSEDが送信される直前に送信されてもよい。唯一の要件は、auth-requiredCLOSEDメッセージに反応してクライアントが適切に振る舞えるよう、リレーと関連づいたチャレンジを保存しておかなければならない ということである。

EVENTメッセージに対するauth-required

クライアントがEVENTをリレーに書き込みたいときにも同じ流れが有効である。ただし、この場合リレーはCLOSEDメッセージの代わりにOKメッセージで応答する。

relay: ["AUTH", "<challenge>"]
client: ["EVENT", {"id": "012345...", ...}]
relay: ["OK", "012345...", false, "auth-required: we only accept events from registered users"]
client: ["AUTH", {"id": "abcdef...", ...}]
relay: ["OK", "abcdef...", true, ""]
client: ["EVENT", {"id": "012345...", ...}]
relay: ["OK", "012345...", true, ""]

署名されたイベントの検証

AUTHメッセージを検証するため、リレーは以下を確認しなければならない:

  • そのkind22242である
  • そのイベントのcreated_atが現在時刻に近い (例: 10分以内)
  • その"challenge"タグの値が以前送ったチャレンジと合致する
  • その"relay"タグの値がリレーのURLと合致する
    • URL正規化技術が適用されている可能性がある。ほとんどの場合、ドメイン名が正しいかどうかを確認するだけで十分である。