nips/41.md
2023-01-02 16:53:10 -03:00

3.7 KiB

NIP-41

Authentication of clients to relays

draft optional author:Semisol

This NIP defines a way for clients to authenticate to relays by signing an ephemeral event.

Event format

An event should be signed with kind: 22241 and content being the WebSockets URL of the relay. The URL MUST:

  • Have a trailing slash if the path is /
  • Not have a port number if protocol is ws and port is 80 or protocol is wss and port is 443
  • Not include the search/query

An example event is shown below:

{
  "id": "...",
  "pubkey": "...",
  "created_at": 1669695536,
  "kind": 22241,
  "tags": [],
  "content": "wss://relay.example.com/",
  "sig": "..."
}

Commands between the relay and the client

This NIP defines a new command, AUTH, which can be sent by either the relay or the client with different meanings.

A relay may send ["AUTH", <human readable reason>, <data object>] when it needs authentication (examples: accessing kind 4 events, whitelist only, requiring proof of authorship for EVENT).
The human readable reason SHOULD be prefixed with a string in the format <short desc string>: <description>. A list of short descriptions is listed below:

  • restricted: This relay is restricted and requires the pubkey of the client to check if it can access the relay. (requires a whitelist, payment, etc)
  • publish: The relay requests that the client identify who is sending an EVENT command. This can be used for where only the signer of an event can publish it, or a pay-as-you-go relay allowing for you to publish others' events
  • private: The client has attempted to access a restricted set of events (example: kind 4 DMs) and should authenticate with the relay to receive them.
  • other: Any reason not defined here.

data object MUST be a JSON object. It currently has one defined field, but may be extended by amendments to this NIP or other NIPs:

  • subscription_id: The subscription ID that triggered the AUTH request.

A client may send one of the following to the relay:

  • ["AUTH", <signed event>] to indicate it has accepted the request. This may also be sent without an authentication request.
  • ["AUTH", null] to indicate it has rejected the request.

A relay SHOULD send the OK command after they receive a non-rejecting authentication response, and use one of the following message prefixes if the event sent cannot be verified:

  • too-old:: The event signed has a too old created_at date.
  • invalid-url:: The URL in content is not matching.
  • already-used:: This event was already used to authenticate to this relay.
  • bad-signature:: The event has a bad signature.

Please note that the OK message should only be sent as a response to other commands that the client sends instead of the AUTH command if the issue is not related to the authentication event being incorrectly signed (example: not on whitelist).

Relays SHOULD send EOSE when an authentication request is triggered by a REQ command, and not send stored events after the EOSE when authentication is completed. Relays SHOULD send OK as a response when a command triggers authentication with the reason starting with auth:.

Clients SHOULD retry the action (resending event, resubscribing) after they authenticate if they receive an AUTH request.

Signed event verification

Relays when processing AUTH responses SHOULD verify the following before accepting the response:

  • that the kind is 22223
  • that the event was recently signed (~10 minutes, by created_at)
  • that the content field matches the relay URL