diff options
| author | fiatjaf <fiatjaf@gmail.com> | 2023-01-16 08:28:02 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-16 08:28:02 -0300 |
| commit | be0a426745252eeb420a38e4896b28059b4f7fa5 (patch) | |
| tree | 36e5991a370c60a0f0ccc1d52a7e0b11ffcdd735 | |
| parent | e5ae318984bdc2f28932420be976183c9a0cd3ff (diff) | |
| parent | 60741160535de8137fb7a74bd6561adef974b884 (diff) | |
Merge pull request #141 from nostr-protocol/auth
| -rw-r--r-- | 42.md | 88 | ||||
| -rw-r--r-- | README.md | 14 |
2 files changed, 97 insertions, 5 deletions
| @@ -0,0 +1,88 @@ | |||
| 1 | NIP-42 | ||
| 2 | ====== | ||
| 3 | |||
| 4 | Authentication of clients to relays | ||
| 5 | ----------------------------------- | ||
| 6 | |||
| 7 | `draft` `optional` `author:Semisol` `author:fiatjaf` | ||
| 8 | |||
| 9 | This NIP defines a way for clients to authenticate to relays by signing an ephemeral event. | ||
| 10 | |||
| 11 | ## Motivation | ||
| 12 | |||
| 13 | A relay may want to require clients to authenticate to access restricted resources. For example, | ||
| 14 | |||
| 15 | - A relay may request payment or other forms of whitelisting to publish events -- this can naïvely be achieved by limiting publication | ||
| 16 | to events signed by the whitelisted key, but with this NIP they may choose to accept any events as long as they are published from an | ||
| 17 | authenticated user; | ||
| 18 | - A relay may limit access to `kind: 4` DMs to only the parties involved in the chat exchange, and for that it may require authentication | ||
| 19 | before clients can query for that kind. | ||
| 20 | - A relay may limit subscriptions of any kind to paying users or users whitelisted through any other means, and require authentication. | ||
| 21 | |||
| 22 | ## Definitions | ||
| 23 | |||
| 24 | This NIP defines a new message, `AUTH`, which relays can send when they support authentication and clients can send to relays when they want | ||
| 25 | to authenticate. When sent by relays, the message is of the following form: | ||
| 26 | |||
| 27 | ``` | ||
| 28 | ["AUTH", <challenge-string>] | ||
| 29 | ``` | ||
| 30 | |||
| 31 | And, when sent by clients, of the following form: | ||
| 32 | |||
| 33 | ``` | ||
| 34 | ["AUTH", <signed-event-json>] | ||
| 35 | ``` | ||
| 36 | |||
| 37 | The signed event is an ephemeral event not meant to be published or queried, it must be of `kind: 22242` and it should have at least two tags, | ||
| 38 | one for the relay URL and one for the challenge string as received from the relay. | ||
| 39 | Relays MUST exclude `kind: 22242` events from being broadcasted to any client. | ||
| 40 | `created_at` should be the current time. Example: | ||
| 41 | |||
| 42 | ```json | ||
| 43 | { | ||
| 44 | "id": "...", | ||
| 45 | "pubkey": "...", | ||
| 46 | "created_at": 1669695536, | ||
| 47 | "kind": 22242, | ||
| 48 | "tags": [ | ||
| 49 | ["relay", "wss://relay.example.com/"], | ||
| 50 | ["challenge", "challengestringhere"] | ||
| 51 | ], | ||
| 52 | "content": "", | ||
| 53 | "sig": "..." | ||
| 54 | } | ||
| 55 | ``` | ||
| 56 | |||
| 57 | ## Protocol flow | ||
| 58 | |||
| 59 | At any moment the relay may send an `AUTH` message to the client containing a challenge. After receiving that the client may decide to | ||
| 60 | authenticate itself or not. The challenge is expected to be valid for the duration of the connection or until a next challenge is sent by | ||
| 61 | the relay. | ||
| 62 | |||
| 63 | The client may send an auth message right before performing an action for which it knows authentication will be required -- for example, right | ||
| 64 | before requesting `kind: 4` chat messages --, or it may do right on connection start or at some other moment it deems best. The authentication | ||
| 65 | is expected to last for the duration of the WebSocket connection. | ||
| 66 | |||
| 67 | Upon receiving a message from an unauthenticated user it can't fulfill without authentication, a relay may choose to notify the client. For | ||
| 68 | that it can use a `NOTICE` or `OK` message with a standard prefix `"restricted: "` that is readable both by humans and machines, for example: | ||
| 69 | |||
| 70 | ``` | ||
| 71 | ["NOTICE", "restricted: we can't serve DMs to unauthenticated users, does your client implement NIP-42?"] | ||
| 72 | ``` | ||
| 73 | |||
| 74 | or it can return an `OK` message noting the reason an event was not written using the same prefix: | ||
| 75 | |||
| 76 | ``` | ||
| 77 | ["OK", <event-id>, false, "restricted: we do not accept events from unauthenticated users, please sign up at https://example.com/"] | ||
| 78 | ``` | ||
| 79 | |||
| 80 | ## Signed Event Verification | ||
| 81 | |||
| 82 | To verify `AUTH` messages, relays must ensure: | ||
| 83 | |||
| 84 | - that the `kind` is `22242`; | ||
| 85 | - that the event `created_at` is close (e.g. within ~10 minutes) of the current time; | ||
| 86 | - that the `"challenge"` tag matches the challenge sent before; | ||
| 87 | - that the `"relay"` tag matches the relay URL: | ||
| 88 | - URL normalization techniques can be applied. For most cases just checking if the domain name is correct should be enough. | ||
| @@ -28,6 +28,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh | |||
| 28 | - [NIP-33: Parameterized Replaceable Events](33.md) | 28 | - [NIP-33: Parameterized Replaceable Events](33.md) |
| 29 | - [NIP-36: Sensitive Content](36.md) | 29 | - [NIP-36: Sensitive Content](36.md) |
| 30 | - [NIP-40: Expiration Timestamp](40.md) | 30 | - [NIP-40: Expiration Timestamp](40.md) |
| 31 | - [NIP-42: Authentication of clients to relays](42.md) | ||
| 31 | 32 | ||
| 32 | ## Event Kinds | 33 | ## Event Kinds |
| 33 | 34 | ||
| @@ -47,6 +48,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh | |||
| 47 | | 43 | Channel Hide Message | [28](28.md) | | 48 | | 43 | Channel Hide Message | [28](28.md) | |
| 48 | | 44 | Channel Mute User | [28](28.md) | | 49 | | 44 | Channel Mute User | [28](28.md) | |
| 49 | | 45-49 | Public Chat Reserved | [28](28.md) | | 50 | | 45-49 | Public Chat Reserved | [28](28.md) | |
| 51 | | 22242 | Client Authentication | [42](42.md) | | ||
| 50 | | 10000-19999 | Replaceable Events Reserved | [16](16.md) | | 52 | | 10000-19999 | Replaceable Events Reserved | [16](16.md) | |
| 51 | | 20000-29999 | Ephemeral Events Reserved | [16](16.md) | | 53 | | 20000-29999 | Ephemeral Events Reserved | [16](16.md) | |
| 52 | 54 | ||
| @@ -54,11 +56,12 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh | |||
| 54 | ## Message types | 56 | ## Message types |
| 55 | 57 | ||
| 56 | ### Client to Relay | 58 | ### Client to Relay |
| 57 | | type | description | NIP | | 59 | | type | description | NIP | |
| 58 | |-------|-----------------------------------------------------|------------| | 60 | |-------|-----------------------------------------------------|-------------| |
| 59 | | EVENT | used to publish events | [1](01.md) | | 61 | | EVENT | used to publish events | [1](01.md) | |
| 60 | | REQ | used to request events and subscribe to new updates | [1](01.md) | | 62 | | REQ | used to request events and subscribe to new updates | [1](01.md) | |
| 61 | | CLOSE | used to stop previous subscriptions | [1](01.md) | | 63 | | CLOSE | used to stop previous subscriptions | [1](01.md) | |
| 64 | | AUTH | used to send authentication events | [42](42.md) | | ||
| 62 | 65 | ||
| 63 | ### Relay to Client | 66 | ### Relay to Client |
| 64 | | type | description | NIP | | 67 | | type | description | NIP | |
| @@ -67,6 +70,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh | |||
| 67 | | NOTICE | used to send human-readable messages to clients | [1](01.md) | | 70 | | NOTICE | used to send human-readable messages to clients | [1](01.md) | |
| 68 | | EOSE | used to notify clients all stored events have been sent | [15](15.md) | | 71 | | EOSE | used to notify clients all stored events have been sent | [15](15.md) | |
| 69 | | OK | used to notify clients if an EVENT was successuful | [20](20.md) | | 72 | | OK | used to notify clients if an EVENT was successuful | [20](20.md) | |
| 73 | | AUTH | used to send authentication challenges | [42](42.md) | | ||
| 70 | 74 | ||
| 71 | Please update these lists when proposing NIPs introducing new event kinds. | 75 | Please update these lists when proposing NIPs introducing new event kinds. |
| 72 | 76 | ||