-
Notifications
You must be signed in to change notification settings - Fork 586
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b12c93c
commit e8caf81
Showing
1 changed file
with
80 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
NIP-43 | ||
====== | ||
|
||
Fast Authentication | ||
------------------- | ||
|
||
`draft` `optional` `author:arthurfranca` | ||
|
||
This is a `client` to `relay` authentication procedure similar to [NIP-42](42.md). | ||
It's faster and easier to implement because it's non-interactive, so NIP-43 should be preferred instead of NIP-42. | ||
|
||
The main difference is that authentication happens on connection start. | ||
|
||
See [Extra Relay Security Measures](#extra-relay-security-measures) for important | ||
`relay` security considerations. | ||
|
||
## How to Authenticate | ||
|
||
The `client` must generate the same `kind: 22242` ephemeral event from NIP-42 but **without** a challenge tag. | ||
Then it has to stringify the event JSON and [percent-encode](https://www.rfc-editor.org/rfc/rfc3986#page-12) it. | ||
The resulting string is used as `authorization` query param when connecting to the relay. | ||
|
||
### Javascript Example | ||
|
||
```js | ||
const relayUrl = 'wss://relay.example.com' | ||
// add id and signature as usual | ||
const jsonEvent = generateNostrEvent({ | ||
pubkey: "...", | ||
created_at: Math.floor(Date.now() / 1000), | ||
kind: 22242, | ||
tags: [['relay', relayUrl]], | ||
content: "" | ||
}) | ||
const auth = window.encodeURIComponent(JSON.stringify(jsonEvent)) | ||
const ws = new WebSocket(`${relayUrl}?authorization=${auth}`) | ||
ws.addEventListener('open', () => console.log('auth accepted')) | ||
ws.addEventListener('close', () => console.log('disconnected') ) | ||
``` | ||
|
||
## Relay Handling | ||
|
||
`Relays` that require users to authenticate before performing atleast one action, must authenticate user on connection request. | ||
The authorization query param must be decoded and validated. A valid event must: | ||
- be of `kind` `22242`; | ||
- have `created_at` within a small time window relative to the current date (e.g. 60 seconds); | ||
- have the `relay` tag url value with the same domain name as the relay. | ||
|
||
If the event is valid, its `pubkey` identifies the authenticated user. | ||
|
||
The `relay` may end the socket right away if the user is not authorized to access the `relay`. | ||
|
||
The `relay` should send a `NOTICE` or `OK` message (as per [NIP-20](20.md)) with a standard prefix `"restricted: "` (readable both by humans and machines) | ||
when blocking authenticated user from accessing some resources. | ||
|
||
For example, if an already authenticated user A requests DMs not sent by him and meant to be read only by user B, | ||
relay should send a `NOTICE` like this one: | ||
|
||
``` | ||
["NOTICE", "restricted: not authorized to access this user's DMs, please login with NIP-43"] | ||
``` | ||
|
||
### Extra Relay Security Measures | ||
|
||
The used protocol must be `wss` (WebSocket Secure). | ||
|
||
The authorization event `id` should be stored for the same above mentioned time window so that | ||
if the same event `id` is used twice, the `relay` should reject the connection immediately and | ||
should also disconnect the user that first used the event to authenticate. | ||
In this case the `relay` may send a `NOTICE` message with `"restricted: "` prefix informing | ||
the first user before disconnecting him, for example: | ||
|
||
``` | ||
["NOTICE", "restricted: your client is misbehaving, authorization event can't be reused."] | ||
``` | ||
|
||
NIP-43 is safe for "EVENT" messages because such messages require signed events even after authentication. | ||
|
||
For "REQ" messages requesting sensitive data, such as wallet balance, | ||
optionally consider using encrypted events similar to [NIP-04](04.md) for additional security. |