Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-43 - Fast Authentication #571

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 04.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ let event = {

## Security Warning

This standard does not go anywhere near what is considered the state-of-the-art in encrypted communication between peers, and it leaks metadata in the events, therefore it must not be used for anything you really need to keep secret, and only with relays that use `AUTH` to restrict who can fetch your `kind:4` events.
This standard does not go anywhere near what is considered the state-of-the-art in encrypted communication between peers, and it leaks metadata in the events, therefore it must not be used for anything you really need to keep secret, and only with relays that use NIP-42/43 authentication to restrict who can fetch your `kind:4` events.

## Client Implementation Warning

Expand Down
2 changes: 1 addition & 1 deletion 11.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ subject to the `max_message_length`, if defined.
- `min_pow_difficulty`: new events will require at least this difficulty of PoW,
based on [NIP-13](13.md), or they will be rejected by this server.

- `auth_required`: this relay requires [NIP-42](42.md) authentication
- `auth_required`: this relay requires [NIP-42](42.md)/[NIP-43](43.md) authentication
to happen before a new connection may perform any other action.
Even if set to False, authentication may be required for specific actions.

Expand Down
69 changes: 69 additions & 0 deletions 43.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
NIP-43
======

Fast Authentication
-------------------

`draft` `optional` `author:arthurfranca`

This is a `client` to `relay` authentication procedure that
happens on connection start by using an `authorization` query parameter.
For example:

`new WebSocket("wss://relay.url?authorization=...")`

## Motivation

`Relays` may want to grant access to specific resources just to authenticated users.

For that, both `clients` and `relays` need to implement authentication. A simple authentication
procedure that `clients` can easily implement (just a query parameter) is better for driving adoption.

## When Clients Authenticate

The `client` should check for [NIP-11](11.md) `relay` document's `"supported_nips"` field in search for NIP-43 support.
If there is support or the document is unavailable, the `client` should connect to the `relay` using NIP-43.
Otherwise, the `client` may choose to connect without NIP-43.

## How Clients Authenticate

The `client` must generate a `kind: 22242` ephemeral event with the current time as `created_at`
and the relay url as a `relay` tag.
Then it has to stringify the JSON event 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') )
```

## How Relay Handles Authentication

`Relays` authenticate users with valid `authorization` query param.

The `authorization` query param must be percent-decoded into a nostr event that 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 hostname, port and path as the connected `relay`.
arthurfranca marked this conversation as resolved.
Show resolved Hide resolved

## Security Measures

The used protocol should be `wss` (WebSocket Secure).

Although not required, the authorization event `id` can be stored by the `relay`
for the same above mentioned time window so that
if the same event `id` is used twice, the `relay` should reject the connection and
also disconnect the user that first used the event to authenticate.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-39: External Identities in Profiles](39.md)
- [NIP-40: Expiration Timestamp](40.md)
- [NIP-42: Authentication of clients to relays](42.md)
- [NIP-43: Fast Authentication](43.md)
- [NIP-45: Counting results](45.md)
- [NIP-46: Nostr Connect](46.md)
- [NIP-47: Wallet Connect](47.md)
Expand Down Expand Up @@ -103,7 +104,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `10001` | Pin List | [51](51.md) |
| `10002` | Relay List Metadata | [65](65.md) |
| `13194` | Wallet Info | [47](47.md) |
| `22242` | Client Authentication | [42](42.md) |
| `22242` | Client Authentication | [42](42.md), [43](43.md) |
| `23194` | Wallet Request | [47](47.md) |
| `23195` | Wallet Response | [47](47.md) |
| `24133` | Nostr Connect | [46](46.md) |
Expand Down Expand Up @@ -191,7 +192,7 @@ Please update these lists when proposing NIPs introducing new event kinds.
| `price` | price | currency, frequency | [99](99.md) |
| `proxy` | external ID | protocol | [48](48.md) |
| `published_at` | unix timestamp (string) | -- | [23](23.md) |
| `relay` | relay url | -- | [42](42.md) |
| `relay` | relay url | -- | [42](42.md), [43](43.md) |
| `relays` | relay list | -- | [57](57.md) |
| `subject` | subject | -- | [14](14.md) |
| `summary` | article summary | -- | [23](23.md) |
Expand Down