Relay authentication, NIP-42 and access without account lock-in
Relay authentication is the difference between an open door, a member door and a paid door. The clever part is that the door can check your Nostr key without making you create a platform account.
Authentication is a door, not a cage
A public relay can allow anonymous reads and writes if it wants. Many do, or at least begin that way. But not every relay is meant to be a public square. Some relays are paid. Some are member-only. Some support wallet traffic. Some host private groups. Some protect certain events from unauthenticated scrapers. Some need to know which key is using bandwidth before they serve a sensitive query. Authentication is how the relay asks: which Nostr key is at the door?
That is different from platform login. The relay is not issuing a username and password that owns your identity. You already have a public key. The relay asks you to prove you control it for this connection or request. If it accepts the proof, it can apply local policy: allow, reject, restrict, require payment, serve protected events or rate-limit. Your key remains portable, and another relay can make a different decision.
This distinction matters because "login" language can mislead new users. If a client says "log in to relay," people may think the relay owns their account. A better framing is "authenticate to this relay." You are proving identity to one server so it can decide local access. You are not handing the relay your identity.
Relay authentication is also not secrecy by itself. If you authenticate to read or write, the relay learns that your key connected and requested something. It may log that. It may link behavior to your public key. That can be fine for a paid relay or private group, but it is still a privacy trade. Authentication gives access control; it does not erase metadata.
The best mental model is a door with a signed knock. The relay issues a challenge. Your client signs a short-lived proof. The relay checks the proof. Then local policy decides what happens.
How the NIP-42 handshake works
The handshake begins when the relay sends an AUTH message with a challenge string. The client may respond with an AUTH message carrying a signed event. That event is ephemeral kind 22242. It includes a relay tag containing the relay URL and a challenge tag containing the exact challenge string the relay sent.
The relay checks the event signature, the kind, the relay URL, the challenge and the freshness of the event. NIP-42 says the created_at timestamp should be within a short recent window. This prevents a signed AUTH event from becoming a reusable login token. The challenge is unique to the relay's request, and the signed event should not be useful elsewhere.
Once authenticated, the relay can associate the connection with the authenticated pubkey. That does not mean the relay must allow everything. Authentication answers "who is this?" It does not answer "what are they allowed to do?" Authorization remains relay policy. A paid relay may authenticate you and still reject writes if you have not paid. A private group relay may authenticate you and still reject messages if you are not a member.
This is why clients must separate authentication state from permission state. "Authenticated" does not mean "accepted." It means "the relay knows which key signed." The next question is whether the key has the right access for the action. If a client treats authentication as a green universal pass, it will confuse users as soon as real policy appears.
NIP-42 can be initiated before or after a client tries to do something. A relay may send a challenge immediately after connection, or it may respond with an error asking the client to authenticate. Good clients handle both flows gracefully. They should not spam signer prompts. They should not sign for every relay without context. They should explain why a relay is asking.
Error language tells you what is really happening
Relay error prefixes matter. If a relay returns auth-required:, it is asking the client to authenticate before the action can continue. If it returns restricted:, the key is authenticated or identifiable but lacks permission. Those two states feel similar to users because both block the action. They are not the same.
auth-required means "prove which key you are using." The client can respond by signing the AUTH event if the user agrees. restricted means "this key is not allowed for this action." The next step might be pay, join, request access, change key, use another relay or accept that the relay is not for you. A client that treats both as "try login again" creates a loop of frustration.
Other error prefixes also interact with authentication. blocked can mean the relay refuses the key or event. rate-limited can mean the key or connection is hitting limits. pow can ask for proof-of-work. invalid can mean the event shape is wrong. Clear error display is not nerd polish. It is how users understand whether the issue is identity, access, abuse, payment, event format or server policy.
Authentication flows should be specific. "This relay wants you to authenticate before writing" is better than "Sign in." "You authenticated, but this relay requires paid write access" is better than "Failed." "This group is member-only" is better than "Restricted." The language should name the relay and the action because the same key may work elsewhere.
If you are debugging relay access, always ask which prefix you saw. No prefix? Silent failure? Timeout? Challenge? Auth required? Restricted? These clues reveal the layer.
Paid, private and local relays need authentication
Paid relays are the obvious case. If a relay charges for writes or premium access, it needs to know which pubkey is using the service. Payment systems can map payment receipts or subscriptions to pubkeys. NIP-42 lets the relay verify that the connecting client controls the key. Without authentication, a paid relay cannot reliably enforce key-based access.
Private relays need it too. A family relay, team relay, local venue relay, club relay, wallet relay or group relay may be readable or writable only by known keys. An allowlist is meaningless if the relay cannot verify the key behind a request. Authentication is the bridge between "this key is allowed" and "the current connection controls that key."
Local relays can use authentication for real-world rooms. A conference relay can let attendees write. A cafe relay can let members access local notes. A retreat relay can host member-only media. A coworking space can maintain room announcements. The relay does not need to become a platform account system. It can use your Nostr key as the portable identity layer and local policy as the door.
Wallet-related relays require extra caution. Nostr Wallet Connect events are sensitive because they can relate to payment permissions and wallet actions. A relay that handles NWC traffic should be narrow, authenticated and clear about what it accepts. Do not treat a wallet relay like a broad social archive. Authentication is one boundary, not the whole security model.
Paid and private relays should expose their access requirements through NIP-11 and clear errors. If a relay requires authentication, say so. If payment is required, say so. If writes are restricted to members, say so. Surprising people with hidden gates makes the relay feel broken even when policy is legitimate.
Protected events and access metadata expand the picture
NIP-70 protected events build on the idea that some events should only be served to authenticated clients. It defines a - tag that marks an event as protected. Relays that support this behavior should only serve protected events to clients authenticated as the author or as a pubkey tagged in the event. This is not full encryption. It is relay-side access control around serving events.
That distinction is important. A protected event stored on a relay is still visible to the relay. The relay can enforce serving rules, but it is not the same as end-to-end encryption. Use protected events when relay access control is the right layer. Use encryption when content secrecy from relays matters.
NIP-43 relay access metadata gives relays a way to publish access rules such as whether authentication or payment is required, and can point to requests or payment information. Together with NIP-11, this helps clients understand the relay before the user hits a wall. A client can show "auth required for writes" or "payment required" before a post fails.
NIP-42, NIP-43 and NIP-70 form a useful trio. Authentication proves the key. Access metadata explains the gate. Protected events define a serving rule for certain events. When clients combine them, private and paid spaces can feel understandable instead of mysterious.
These NIPs do not remove the need for good UI. A user should know when they are authenticating, what key is being used, what relay is asking, what action is gated and what happens if they decline. Protocol support without product clarity becomes another confusing signer popup.
Client UX should make authentication rare and legible
A signer prompt is a moment of trust. If your client asks for signatures constantly, users will stop reading. Relay authentication should be requested only when needed, explained clearly and scoped to the relay action. "relay.example wants proof that you control npub..." is better than a generic signature modal.
The prompt should show the relay URL, the reason, the key, and the expected result. Writing to a paid relay, reading a protected event, joining a group or connecting to a wallet relay are different contexts. The user should not have to inspect raw tags to know why they are signing.
Clients should cache authentication state carefully. Re-authenticating on every tiny action creates fatigue. Caching forever creates risk. The right pattern depends on the relay and the action. A connection-level AUTH event is short-lived. A client can remember that the connection is authenticated, but should not treat that as an eternal account session.
Clients should also avoid authenticating to relays unnecessarily. If a relay is public and does not require auth for the current action, do not prompt. Every unnecessary authentication reveals a little more connection behavior to a relay. Privacy-friendly UX signs when needed, not because it is easy.
Failure states need plain language. If auth fails because the event is stale, say the challenge expired. If the relay URL does not match, say the signed proof was for a different relay. If the signer refuses, say the action was not authenticated. If the key lacks permission, say authenticated but restricted. Those words teach the model.
Operator practice decides whether auth feels trustworthy
If you run a relay that requires authentication, publish the rule. Use NIP-11 metadata and a human policy page if needed. Tell users which actions require auth: read, write, protected event access, search, group membership, wallet traffic or paid features. Do not make every failure discoverable only by trial and error.
Use auth for a reason. Requiring authentication for everything may reduce abuse, but it also reduces privacy and openness. A public read relay may not need auth for ordinary reads. A paid write relay may need auth for writes only. A protected-event relay may need auth for specific filters. A local group relay may need auth for both reads and writes. Match the requirement to the room.
Check challenge freshness. Reject stale AUTH events. Check relay URL. Check signature. Check kind 22242. Check the challenge value exactly. Loose verification turns authentication into theater. If the relay accepts old or mismatched AUTH events, it can be vulnerable to replay or confusion.
Separate authentication from authorization in your code and mental model. First prove the key. Then decide if that key can do the action. Payment, membership, allowlists, event kind restrictions, rate limits and moderation all live after identity proof. If your implementation muddles the steps, your errors will muddle users.
Log enough to debug without collecting everything forever. Authentication failures can reveal client bugs, attacks or expired challenges. But authentication logs also link keys to relay activity. Keep only what you need, protect it, and publish your privacy stance if the relay is sensitive.
Authentication has privacy and security tradeoffs
Authentication tells a relay that a key is present on a connection. That can be useful and necessary. It can also be sensitive. If you authenticate to many relays automatically, those relays can associate your key with connection timing, IP addresses, queries and actions. A public key is public, but your usage pattern may not be something you want sprayed everywhere.
Use separate keys when contexts truly need separation. A public social key, a local group key, a work key and a wallet-related key may not belong in the same relay-auth pattern. Nostr makes key separation possible, but clients should help rather than forcing everything through one identity.
Signer safety matters. An AUTH event should be kind 22242, ephemeral, tied to one relay URL and one challenge. Users should not be asked to sign strange events with broad meaning. A malicious client could disguise another kind of event as authentication if the signer UI is weak. Good signers display event kind, relay tag and challenge context in human terms.
Phishing is possible. A site can ask you to sign something that looks like relay auth but is not. A malicious relay can ask for frequent auth to collect behavior. A careless client can send AUTH events to the wrong relay. The protections are boring and important: verify URL, verify kind, verify challenge, verify recency, show the user what is being signed.
Do not confuse authentication with encryption. An authenticated private relay can restrict who reads stored events, but the relay still has access. For confidential content, use encryption and understand metadata. Relay auth controls access to relay behavior. It is not a privacy force field.
Your relay authentication routine
When a relay asks you to authenticate, pause long enough to understand the reason. Are you writing? Reading protected content? Joining a group? Using a paid relay? Accessing wallet-related traffic? If the client does not tell you, that is a product problem.
Check the relay URL. Authentication should be bound to the relay that asked. If the URL looks wrong, stop. Check the key. If you use multiple keys, make sure the right one signs. Check the expected outcome. Signing should unlock a specific action, not grant vague permanent access.
If authentication succeeds but the action still fails, look for restricted or payment/membership language. You may have proved the key, but the relay may not allow that key. This is normal in paid and private spaces. The next step is not always another signature. It may be membership, payment, invite, different relay or different key.
If you operate a relay, test the auth flow from a normal client. Does the user know why they are signing? Does the relay reject stale auth? Does the relay send useful errors? Does NIP-11 say auth is required? Does payment or membership state update correctly? Does a denied key see a clear reason?
The best version of relay authentication feels calm. You sign when there is a reason. The relay verifies you. The client explains the result. Your key remains yours. The room gets a door without becoming a platform prison.
NIP-42 and NIP-98 solve different doors
NIP-42 is a WebSocket relay authentication flow. The relay sends an AUTH challenge inside the Nostr relay connection, and the client responds with a signed kind 22242 event. NIP-98 is HTTP authentication. It signs an HTTP request with a Nostr event so an HTTP endpoint can verify the key behind the request. They feel similar because both use signed Nostr events, but they guard different doors.
This distinction matters in mixed systems. A NIP-29 group may use NIP-42 for relay access and NIP-98 for a LiveKit token endpoint. A relay management API may use NIP-98 for HTTP admin requests. A media upload service may use NIP-98 while a related relay uses NIP-42. A product that simply says "Nostr login" for all of these hides meaningful differences.
For users, the practical question is: what am I authorizing? If the answer is "this relay connection," you are likely in NIP-42 territory. If the answer is "this HTTP request to this URL," you are likely in NIP-98 territory. A good signer can show both clearly. A bad signer makes both look like random events.
For builders, do not reuse one mental model everywhere. A NIP-42 AUTH event includes relay and challenge tags. A NIP-98 event includes HTTP method, URL, payload hash when needed and its own rules. If you mix them casually, you create auth flows that appear to work during demos and fail under real security review.
For operators, publish which door you are using. If a relay requires NIP-42 for writes, say that. If a companion HTTP endpoint requires NIP-98, say that. If a group live room requires NIP-98 authorization, say that. Users can handle complexity when the labels are honest.
Wallet relays need the least romance
Nostr Wallet Connect makes relays carry sensitive coordination between an app and a wallet. That does not mean every NWC relay is a bank, but it does mean the relay role is narrower and more serious than a public social relay. The relay should not be a place where random public notes, spam and wallet coordination all mix because nobody bothered to define the boundary.
Authentication can help wallet relays know which key is connected and whether a key has access to a session. But wallet safety also depends on encryption, permissions, connection secrets, spending limits, wallet policy and client behavior. Do not let NIP-42 language create a false sense that "authenticated" equals "safe to pay." Auth proves identity for the relay. Payment permission lives elsewhere.
A wallet relay should be explicit about supported event kinds, retention, access rules and privacy. Does it store only NWC-related events? Does it require auth? Does it prune old events? Does it reject broad social traffic? Does it expose NIP-11 metadata? Does it rate-limit? Does it accept writes only from known session participants? These details matter because wallet traffic is a very different room from a public feed.
Clients should also protect users from cross-context confusion. A user should not authenticate a wallet key to a random social relay without understanding why. A social key may not belong in a wallet session. A wallet connection should not reuse a broad social relay list by default. The more valuable the action, the narrower the relay habit should be.
The calm rule is simple: authenticate only to relays that have a reason to know this key. Wallet relays, member relays, paid relays and protected content relays have reasons. Random public read relays often do not.
Multi-relay authentication gets messy fast
Nostr clients often connect to many relays. If several relays require authentication, a naive client might prompt you again and again. That is terrible UX and bad security training. Users will learn to click through signatures blindly. A better client batches explanation, scopes requests and signs only when each relay actually needs proof for the current action.
Each relay challenge is separate. You cannot sign one universal AUTH event and send it everywhere. The event includes the relay URL and challenge. That is the point. It prevents one relay's challenge from becoming a reusable proof somewhere else. A client that tries to "optimize" by reusing AUTH events is breaking the safety model.
Relay URL normalization becomes important. If a relay is known as wss://example.com in one place and wss://example.com/ elsewhere, clients and relays need to handle the exact value carefully. A mismatch can cause valid-looking auth to fail. Error messages should say when the relay tag did not match the expected URL rather than pretending the signature is bad.
Multiple keys make it even more complicated. You may use one key publicly, another for a private group, another for work and another for wallet-related actions. The client should not guess the wrong key. It should show which key is authenticating. If a relay returns restricted after authentication, the problem may be that you signed with a key that is not on the allowlist.
This is why relay auth belongs in connection management, not only posting flow. The client needs a model of which relays require auth, which keys are authenticated on which connections, which actions are gated and which errors need a new signature. Without that model, users experience NIP-42 as random popups.
Concrete failure cases
Failure one: the relay sends a challenge, your client never responds, and every publish returns auth-required. The fix is not to change relays blindly. The client needs to support NIP-42 or the user needs a client that does. The relay should say auth is required in metadata or errors so the user knows what happened.
Failure two: the client signs, but the event is too old by the time the relay checks it. This can happen with slow signers, offline flows, clock problems or cached prompts. The relay should reject stale AUTH events, and the client should request a fresh challenge. The user-facing message should say the challenge expired.
Failure three: the client signs with the wrong key. The relay accepts the signature but then returns restricted because that key is not a member, subscriber or invited participant. The client should not keep asking for auth with the same key. It should say the authenticated key does not have access and let the user switch key or request access.
Failure four: the relay URL in the AUTH event does not match the relay's expected URL. The signature may be valid, the challenge may be right, but the relay tag is wrong. This can happen with aliases, trailing slashes, proxy URLs or sloppy relay normalization. Good clients should preserve the exact relay URL from the connection and display it in diagnostics.
Failure five: the relay authenticates writes but the client tries to read protected events without authenticating the read subscription. The user sees missing events and assumes censorship or downtime. The real issue is access control. A client should retry or explain when a protected event requires authentication.
Failure six: a relay requires payment after authentication. The user signs correctly, but writes still fail with restricted or payment messaging. This is not an auth failure. It is authorization. A polished client should lead to payment or subscription status instead of looping auth prompts.
Anti-patterns to avoid
The first anti-pattern is auto-authentication everywhere. A client connects to twenty relays and signs AUTH events for all of them just in case. That leaks identity activity, trains users to ignore signing, and gives relays unnecessary knowledge. Authenticate only when the relay asks or when policy metadata says the current action requires it.
The second anti-pattern is hiding raw danger behind cute language. "Continue" is not enough for signing an auth event. The prompt should say which relay, which key and what action. Friendly UI is good. Vague UI is dangerous. Users can handle direct language when it is short and concrete.
The third anti-pattern is using auth as a punishment label. "You must authenticate" sounds like suspicion when the relay simply needs key proof for a paid write. Better language is neutral: "This relay requires proof of your key before writing." Then the next line can explain payment, membership or protected access if needed.
The fourth anti-pattern is treating authentication as consent to all future relay policy. It is not. You authenticated for a connection or request. The relay still needs clear rules. A user may prove their key and still disagree with payment, retention, moderation or membership policy. Auth does not mean blanket acceptance of hidden terms.
The fifth anti-pattern is using the same key for everything because it is frictionless. That may be fine for a casual user, but advanced users, organizations, local communities and wallet flows need key separation. Clients should make key choice understandable instead of burying it under one "account" metaphor.
Designing signer prompts for humans
A good signer prompt for relay auth should answer five questions in plain language: which key, which relay, which action, how long this proof matters, and what happens if you decline. You do not need a paragraph. You need the right facts. "Authenticate npub... to wss://relay.example so this client can publish to a member-only relay" is more useful than "Sign event kind 22242."
Still, advanced details should be inspectable. Users who want to see the raw event should be able to check kind 22242, relay tag, challenge tag, timestamp and signature request. Hiding details completely creates trust dependence on the signer UI. Showing only raw JSON creates confusion. The best signers do both: human summary first, raw details one click away.
Signer prompts should distinguish relay auth from posting, profile updates, zap requests, HTTP auth and wallet actions. If every signed event looks identical, users cannot build safe habits. Nostr gives you many signing contexts. The signer is the place where those contexts become legible.
Decline should be safe and understandable. If you reject auth, the client should say the action was not completed because the relay could not verify your key. It should not punish you by disconnecting everything unless the relay demands it. It should let you choose another relay or continue in read-only mode if possible.
Good auth UX respects attention. It does not shout. It does not hide. It tells the truth at the moment the truth matters.
How auth changes relay culture
Authentication shifts relays from anonymous infrastructure toward accountable rooms. That can be good. Paid relays become sustainable. Local relays become usable. Private groups become enforceable. Wallet relays become narrower. Search and archival services can control abuse. But every shift toward accountability also creates more metadata and more gatekeeping.
The healthy culture is explicit choice. Some relays stay open. Some require auth for writes. Some require auth for reads. Some are paid. Some are private. Some serve protected events. Some never ask for auth. Users can choose the relay mix that matches their risk, cost and community needs. The danger is one auth-heavy default becoming invisible norm.
Nostr should not be allergic to doors. Doors make homes, clubs, teams, wallets and venues possible. But doors should have signs. A relay should say what it is, why it asks, who can enter, what is logged and how to leave. Authentication is respectable when it is honest.
For builders, the lesson is to resist lazy metaphors. Do not call every auth flow login. Do not call every restriction censorship. Do not call every paid gate a community. Use precise words: authenticate, authorize, join, pay, access, write, read, protected, restricted. Precise words make users stronger.
That is the promise of NIP-42 done well: access control that does not dissolve portable identity. You can prove who you are to one relay, for one purpose, without surrendering the rest of your Nostr life.
A five-minute auth audit
If you want to know whether a relay auth flow is healthy, test it like a normal person. Connect without authenticating. Try to read. Try to write. Watch the first error. Authenticate with the right key. Try again. Authenticate with the wrong key. Try again. Let the challenge expire. Try again. Switch to another client. If each failure gives a different, accurate explanation, the relay and client are speaking honestly.
Then read the public metadata. Does NIP-11 say auth is required? Does the relay explain payment, membership or protected access? Does it publish contact information? Does it return auth-required when proof is missing and restricted when access is denied? Does it avoid unnecessary prompts on public reads? These small checks reveal whether auth is a designed door or a pile of hidden locks.
For a personal setup, write down which relays ask for auth and why. Paid publishing, wallet traffic, private groups, local rooms and protected archives are legitimate reasons. Random public relay prompts deserve scrutiny. You do not need to fear authentication. You need to know what each signed proof buys you.
Sources worth opening
Open these when you want the exact mechanics and related access-control layers.
- NIP-42: Authentication of clients to relays
- NIP-43: Relay access metadata and requests
- NIP-70: Protected events
- NIP-98: HTTP Auth
- NIP-11: Relay information document
- NIP-29: Relay-based groups
- nostr.wine paid relay as a practical auth/payment reference point
- Alby NWC relay for wallet-specific relay context
