nostr-relay implements authentication according to NIP-42.
The specification allows clients to authenticate whenever they want, using an authentication event of kind 22242. Authentication will persist for the duration of the websocket connection.
The relay may send NOTICE
messages if authentication is required for certain actions.
Currently, this implementation defines actions
and roles
. The actions are save
and query
, corresponding to EVENT
and REQ
message types.
There can be an arbitrary number of roles. The only role used internally is a
-- corresponding to an anonymous, logged-out user.
You can associate public keys with whichever (single-letter) roles you want. In the future, there may be more actions and fine-grained permissions per role.
Configuration
To enable, add this to your configuration file:
authentication:
relay_urls:
- wss://my.relay.url
enabled: true
actions:
save: w
query: ra
This would require the w
role to add events, but anyone with the r
role or anyone logged-out (who implictly get the a
role) would be allowed to query.
If there are no public keys assigned to roles, this configuration would allow access for anyone:
authentication:
relay_urls:
- wss://my.relay.url
enabled: true
actions:
save: a
query: a
You must add the url(s) that your relay answers to, in order to validate the authentication event.
How to assign roles
nostr-relay -c /your/config/file.yaml role set -p <public_key> -r <roles>
To get roles:
nostr-relay -c /your/config/file.yaml role get -p <public_key>
User Throttling
You can slow down certain classes of users, based on their role. For instance, to slow down all unauthenticated users for 10 seconds every time they issue an EVENT or REQ:
authentication:
relay_urls:
- wss://my.relay.url
enabled: true
throttle:
unauthenticated: 10.0
Here's a more complete example, with different roles:
authentication:
relay_urls:
- wss://my.relay.url
enabled: true
throttle:
unauthenticated: 10.0
a: 1.5
t: 5.0
Anyone with the "t" role will be throttled for 5 seconds, while authenticated (but unknown) users will be throttled for 1.5 seconds.
Extending Authentication
To implement custom authentication or roles, create your own class somewhere with these methods:
async def authenticate(auth_event_dict)
This method should return an opaque token containing auth roles.
and
async def can_do(auth_token, action: str, target=None)
This should return True/False if the auth token can perform the action.
Currently, target
can be an event or a subscription object.
and
async def should_throttle(auth_token)
This should return a float number of seconds.
Then, in your configuration:
authentication:
enabled: true
authenticator_class: my.custom.module.MyAuthenticator
actions:
save: w
query: ra
Your class will be initialized like this:
MyAuthenticator(storage, authentication_config: dict)
Future Work
There will be fine-grained, configurable permission checks -- for instance, to allow pubkeys to save only their own events, or events of pubkeys that follow them, etc.
Another check could evaluate the contents of a REQ
filter to determine whether to show the results.