Skip to content

Commit

Permalink
Add NIP-43 - Fast Authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurfranca committed May 30, 2023
1 parent b12c93c commit e8caf81
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions 43.md
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.

0 comments on commit e8caf81

Please sign in to comment.