Problem
NIP-42 defines how a client authenticates its identity to a relay, but says nothing about what happens after authentication. Today, relay operators who want to restrict access — for example, to paying subscribers or token holders — must either:
- Hard-code an allowlist of pubkeys into relay configuration, or
- Build custom relay software with embedded access logic.
Both approaches are brittle and couple access policy to relay implementation. Every relay that wants gated access reinvents its own solution.
Proposal
Standardize a protocol for relays to delegate access control decisions to an external Access Control Service (ACS) via HTTP callbacks after NIP-42 authentication.
The flow:
- Client connects and completes NIP-42 auth (kind
22242 signed event)
- Relay verifies the signature, extracts the pubkey
- Relay calls
POST /check-access on the ACS with the authenticated pubkey and action (connect, read, or write)
- ACS responds with
{ "allowed": true/false, "reason": "...", "expires_at": ... }
- Relay grants or restricts access, using
restricted: prefixed messages per NIP-42
The ACS response can optionally include accessible_pubkeys (restrict to events from specific authors) and restricted_kinds (restrict to specific event kinds), enabling fine-grained per-user filtering.
Use Cases
- Subscription-gated relays — a creator platform checks a billing database to verify the subscriber has an active subscription before granting read access to premium content
- Token-gated relays — a community relay verifies the user holds ecash tokens from a specific Cashu mint
- Group membership — a relay checks an external directory to verify the user belongs to a specific organization
- Tiered access — different users see different content on the same relay based on their subscription tier or role
Relation to Existing NIPs
| NIP |
Relation |
| NIP-42 |
This proposal extends NIP-42. Auth handles identity; this NIP standardizes the authorization step that follows. Uses the existing restricted: prefix. |
| NIP-43 |
Complementary. NIP-43 manages relay access via Nostr events (membership lists). This NIP delegates to HTTP services. Better suited when authorization depends on external state (billing, payments, tokens) that doesn't naturally live on a relay. A relay could use NIP-43 for membership data and this NIP for enforcement. |
| NIP-86 |
Opposite direction. NIP-86 is admin → relay (push model for management). This NIP is relay → auth service (pull model for per-user runtime authorization). They coexist naturally. |
Reference Implementation
A working implementation of the ACS is open-source at Nostreon/relay-auth. It is running in production as part of a creator platform with:
- Dual-relay architecture: public relay (open read) + gated relay (NIP-42 required for read and write)
- ACS endpoints:
POST /check-access for boolean subscription checks, POST /accessible-creators for per-creator filtering
- Reverse proxy connecting the relay and ACS
The repo includes the full ACS service, Docker setup, and example relay/proxy configuration.
Draft Spec
A full draft specification is available and will be submitted as a PR once this issue has an assigned number. It covers:
- ACS HTTP API (
POST /check-access request/response format)
- Relay behavior for connection, read, and write gating
- Response caching via
expires_at
- NIP-11
access_control field for client discovery
- Client behavior guidelines
- Security considerations
Problem
NIP-42 defines how a client authenticates its identity to a relay, but says nothing about what happens after authentication. Today, relay operators who want to restrict access — for example, to paying subscribers or token holders — must either:
Both approaches are brittle and couple access policy to relay implementation. Every relay that wants gated access reinvents its own solution.
Proposal
Standardize a protocol for relays to delegate access control decisions to an external Access Control Service (ACS) via HTTP callbacks after NIP-42 authentication.
The flow:
22242signed event)POST /check-accesson the ACS with the authenticated pubkey and action (connect,read, orwrite){ "allowed": true/false, "reason": "...", "expires_at": ... }restricted:prefixed messages per NIP-42The ACS response can optionally include
accessible_pubkeys(restrict to events from specific authors) andrestricted_kinds(restrict to specific event kinds), enabling fine-grained per-user filtering.Use Cases
Relation to Existing NIPs
restricted:prefix.Reference Implementation
A working implementation of the ACS is open-source at Nostreon/relay-auth. It is running in production as part of a creator platform with:
POST /check-accessfor boolean subscription checks,POST /accessible-creatorsfor per-creator filteringThe repo includes the full ACS service, Docker setup, and example relay/proxy configuration.
Draft Spec
A full draft specification is available and will be submitted as a PR once this issue has an assigned number. It covers:
POST /check-accessrequest/response format)expires_ataccess_controlfield for client discovery