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 is80
or protocol iswss
and port is443
- 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 anEVENT
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' eventsprivate
: 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 theAUTH
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 oldcreated_at
date.invalid-url:
: The URL incontent
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
is22241
- that the event was recently signed (~10 minutes, by
created_at
) - that the
content
field matches the relay URL