1 Overview
By default, anyone can copy a signed event and publish it to any relay. The signature stays valid everywhere. This NIP adds a brake. An event that carries the ["-"] tag is a protected event. A protected event can only be published to relays by its author.
Relays enforce this rule. A relay checks that the publisher is the author before it stores the event. The check uses NIP-42 authentication. A relay may also refuse all protected events instead. Refusal is the required default.
The tag is a clear signal from the author: do not republish this event to other relays. A relay that sees the tag knows the event is not intended for third-party redistribution.
Protection is not encryption. A protected event is still readable by anyone the relay serves it to. To hide content, use NIP-17 private messages or NIP-44 encryption. NIP-70 only limits who can publish, not who can read.
2 The Protected Tag
The tag is a simple tag with a single item: ["-"]. The tag name is the single character -. The tag has no value. A client may add the tag to any event of any kind.
{
"id": <computed as in NIP-01>
"pubkey": <author public key>
"kind": <any kind>
"tags": [["-"]]
"content": <arbitrary string>
...
}
| Tag | Shape | Meaning |
|---|---|---|
| - | ["-"] — name only, no value | The event is protected. Only its author may publish it to relays. |
The tag name - is not an English letter. Under NIP-01 rules, relays index only single-letter tags a-z and A-Z. So there is no standard #- filter, and the spec defines no way to query for protected events. Relays must inspect the tags array directly at publish time.
3 Relay Rules
The default behavior of a relay MUST be to reject any event that contains ["-"]. A relay that does not implement this NIP still complies by rejecting the tag outright.
A relay that wants to accept protected events MUST follow this procedure:
- Require the client to complete the NIP-42
AUTHflow first. - Compare the authenticated client's pubkey with the
pubkeyfield of the published event. - Accept the event only when the two pubkeys are the same. Reject it otherwise.
| Condition | Relay action |
|---|---|
Event has ["-"], relay does not support this NIP | Reject. This is the required default. |
Event has ["-"], client is not authenticated | Send an AUTH challenge and reject with an auth-required: message. |
Event has ["-"], authenticated pubkey matches event.pubkey | Accept and store the event. |
Event has ["-"], authenticated pubkey differs from event.pubkey | Reject the event. |
| Repost embeds a protected event | Reject the repost. See §4. |
Protection works only on cooperating relays. Any reader can still copy a protected event and push it to a relay that ignores this NIP. The tag expresses the author's intent; it cannot make republication impossible.
4 Reposts
Reposts of protected events MUST NOT embed the reposted event. A NIP-18 repost normally carries the full reposted event as stringified JSON in content. For a protected event, the repost must leave that copy out.
If a repost embeds a protected event anyway, relays SHOULD summarily reject the repost. An embedded copy would smuggle the protected event past the author-only publish rule.
5 Worked Example
User 79be667e…f81798 publishes a protected kind-1 note to wss://example.com. The relay demands authentication first. Orange lines go to the relay. Blue lines come from the relay.
-- client publishes a protected note -- → ["EVENT", {"id":"cb8feca582…9eef6f2","pubkey":"79be667ef9…f81798", "created_at":1707409439,"kind":1,"tags":[["-"]], "content":"hello members of the secret group","sig":"fa163f5c…9fa684c"}] -- relay refuses and challenges -- ← ["AUTH", "<challenge>"] ← ["OK", "cb8feca582…9eef6f2", false, "auth-required: this event may only be published by its author"] -- client authenticates (signed kind-22242 event, see NIP-42) -- → ["AUTH", {…signed auth event…}] -- client sends the same event again -- → ["EVENT", {"id":"cb8feca582…9eef6f2", …, "tags":[["-"]], …}] ← ["OK", "cb8feca582…9eef6f2", true, ""]
6 Why It Exists
Sometimes an author does not want an event to spread to every relay imaginable. The author may target a certain demographic, or a semi-closed community relay. Even public information can make sense to keep compartmentalized across different relays.
The tag also enables closed-access feeds. The publisher has a relationship with one relay and trusts it not to release the published events to anyone. Only the author can place those events there.
It is ultimately impossible to restrict the spread of information on the internet. A member of a closed group can copy a restricted event and republish it elsewhere. But most relays are happy to not help these so-called "pirates". Given a clear signal, they gladly reject the republish attempt out of respect for the author's decision. This NIP is that signal.
7 Version History
NIP-70 is a short spec and has stayed close to its original form. Notable changes, newest first:
- 20262026-05Added the repost rule: reposts must not embed protected events, and relays should reject reposts that do.
- 20252025-12Tagged the NIP with the
relaycategory to mark it as relay-enforced behavior. - 20242024-2026Housekeeping: relative links and code-fence formatting.
- Origin2024-07fiatjaf proposed relay-based event access control with the
["-"]tag.
Original Proposal - Credits
| Author | fiatjaf |
| First commit | 2024-07-10 — “relay-based event access-control with the ["-"] tag” (PR #1030) |
| Status | draft - optional — relays reject the tag by default |
| Source | 70.md on GitHub - full change history |
8 See Also
- NIP-01 — the event object, tags, and the
OKmessage this NIP builds on. - NIP-42 — the
AUTHflow relays use to verify the author's pubkey. - NIP-18 — reposts; for protected events they must not embed the event.
- NIP-17 — private direct messages, when you need secrecy rather than publish control.
- NIP-29 — relay-based groups; another pattern for community-scoped content.