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-109: Pubkey Deletion #377

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

alexgleason
Copy link
Member

@alexgleason alexgleason commented Mar 17, 2023

This NIP provides a way for users to delete their own account. Supported relays would delete all events from the pubkey and prevent new ones from being added. This option enhances user privacy and helps with disaster recovery.

Currently events can only be deleted one-at-a-time. However, users expect a "delete account" option, which I believe will be necessary for mainstream adoption of Nostr.

Precedent

If an attacker steals your private key, you can already protect against them submitting new events by monitoring relays and submitting deletion requests automatically. Here is an example of such a bot: https://gitlab.com/alexgleason/plan-b

A better solution would be for relays to become friendlier about deleting user content. I propose Event<5> on a pubkey. When this happens, relays excommunicate the pubkey as described in this document:

➡️ NIP-109 https://github.com/alexgleason/nips/blob/delete-pubkey/109.md

FAQ

  • Shouldn't relays handle this? That's exactly what this NIP proposes.
  • Why 109? Event deletions are defined in NIP-09. 109 is the smallest available NIP ending in "9".
  • Why extend kind 5 instead of a new kind? Relays already implement special behavior for kind 5 events. That behavior is desired, in addition to it making sense semantically.

P.S. I'm not the only one thinking about this.

@pjv
Copy link

pjv commented Mar 18, 2023

This seems like the best pragmatic mitigation for what will certainly be a real problem in a decentralized social media protocol.

Question: @alexgleason the only difference between a kind 5 event that deletes one or more events and a kind 5 event that signals account (pubkey) deletion is that the latter includes a ‘p’ tag? Given the unrecoverable severity of pubkey “cancelation”, should there be something / anything else in the event and/or does the extreme nature of this functionality beg creating a different kind (not 5) altogether?

If not a new kind, should there be additional constraints on the NIP-69 kind 5 event such as if it has a ‘p’ tag it can have one and only one ‘p’ tag and/or if it has a ‘p’ tag it must not have any ‘e’ tags?

@shafemtol
Copy link
Contributor

shafemtol commented Mar 18, 2023

Suggestions/ideas:

  • Use the term revocation rather than deletion. The term revocation more clearly communicates the intent and that this action is irreversible.
  • Relays should probably continue to accept kind 5 events, but reject and ignore any kind 5 event that attempts to delete another kind 5 event.
  • NIP-03 OTS integration could let the user revoke the pubkey without invalidating their historical events (or risking that an attacker can do so). Events with an OTS attestation can be assumed to be legitimate and kept around as long as the pubkey revocation event does not have an OTS attestation earlier than the event (possibly with some extra security margin). To support this, I suggest that relays with NIP-03 support do not delete OTS-attested events upon a pubkey revocation, to reject/ignore deletion events on OTS-attested events where the deletion event does not itself have an OTS attestation that proves its legitimacy, and to let clients decide whether and how to show such OTS-attested events.

PS: Some issues regarding event deletion and account compromise were also brought up in #343.

@arthurfranca
Copy link
Contributor

Relays receiving a pubkey deletion event MUST mark the pubkey as deleted, and MUST stop delivering events from this pubkey to clients

I think, as NIP-09, these MUSTs should be atleast SHOULDs cause if a relay keep these deletion events around forever while also marking pubkeys as deleted, one may flood a relay with deletion events with a zillion different pubkeys, just so to fill the relay's DB.

Relays MAY delete events by this pubkey from their database

Now I think MUST delete is better for a relay that wishes to support this NIP, as this should be the main goal of this NIP.

Copy link
Collaborator

@Semisol Semisol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This should be renamed to "Public Key Revocation", since that is a more fitting name and represents what this actually is.
  2. Content should not be used since attackers that obtained the private key may use this maliciously.
  3. The NIP should specify that pubkey deletions from delegated keys should be ignored since that is an issue
  4. Maybe add support for delegation
  5. NIP-69 is already occupied by 1-2 other proposals

69.md Outdated Show resolved Hide resolved
69.md Outdated Show resolved Hide resolved
69.md Outdated Show resolved Hide resolved
69.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Co-authored-by: Semisol <45574030+Semisol@users.noreply.github.com>
@alexgleason alexgleason changed the title NIP-69: Deleting a Pubkey NIP-69: Public Key Revocation Mar 21, 2023
@alexgleason
Copy link
Member Author

@Semisol Thank you!

@alexgleason alexgleason changed the title NIP-69: Public Key Revocation NIP-109: Public Key Revocation Mar 21, 2023
@alexgleason
Copy link
Member Author

I've renamed it from NIP-69 to NIP-109 to not conflict with the proposed NIP for polls. 109 still seems appropriate.

@alexgleason
Copy link
Member Author

creating a different kind (not 5) altogether?

The reason to reuse kind 5 is because relays already implement special behavior for kind 5 events, and we want to preserve that behavior for this feature. It therefore decreases complexity while also making sense semantically. I did make a conscious choice to make this a new NIP rather than extend NIP-09, so clients can check the supported_nips field of relays when deciding how and when to utilize this feature.

Copy link
Collaborator

@Semisol Semisol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a rejection, but would be great to specify if you are revoking your key or deleting your account (true deletion doesn't exist) or something else


### Client behavior

Clients which recieve a pubkey revocation event SHOULD treat all events from that pubkey as if they were deleted in accordance with [NIP-09](09.md).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Clients which recieve a pubkey revocation event SHOULD treat all events from that pubkey as if they were deleted in accordance with [NIP-09](09.md).
Clients which recieve a pubkey revocation event SHOULD treat all events from that pubkey as if they were deleted in accordance with [NIP-09](09.md). If a client receives multiple events, it SHOULD use the highest priority intent as specified above. Clients SHOULD show a message based off the intent such as account deletion or key compromise.


`draft` `optional` `author:alexgleason`

Events of [kind `5`](09.md) may contain a "p" tag instead of "e" tags. The "p" tag MUST match the `pubkey` of the signed event, and this event indicates that the author wishes for relays and clients to stop showing events for this pubkey, and to reject future events from the pubkey.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Events of [kind `5`](09.md) may contain a "p" tag instead of "e" tags. The "p" tag MUST match the `pubkey` of the signed event, and this event indicates that the author wishes for relays and clients to stop showing events for this pubkey, and to reject future events from the pubkey.
Events of [kind `5`](09.md) may contain a "p" tag instead of "e" tags. The "p" tag MUST match the `pubkey` of the signed event, and this event indicates that the author wishes for relays and clients to stop showing events for this pubkey, and to reject future events from the pubkey.
They SHOULD also contain a `intent` tag, which may currently be one of the following:
- compromised
- delete
- other
The order above also specifies how different intents override each other.

"kind": 5,
"pubkey": "6027adac157831dfe9d2f988c1b8b7a75d9296a7d42a0f9ed056a320925b0e13",
"tags": [
["p", "6027adac157831dfe9d2f988c1b8b7a75d9296a7d42a0f9ed056a320925b0e13"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
["p", "6027adac157831dfe9d2f988c1b8b7a75d9296a7d42a0f9ed056a320925b0e13"],
["p", "6027adac157831dfe9d2f988c1b8b7a75d9296a7d42a0f9ed056a320925b0e13"],
["intent", "delete"]

Copy link
Member Author

@alexgleason alexgleason Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the user has been compromised? Then we can't really trust the intent. I think simplicity is important here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, what you do is publish a higher intent level. If you see both a compromised and delete you pick compromised.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡

That makes sense.

Is the intent tag already used anywhere else?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No.


### Relay behavior

Relays receiving a pubkey revocation event MUST mark the pubkey as revoked, and MUST stop delivering events from this pubkey to clients, EXCEPT for events of kind `5`. Relays MAY delete events by this pubkey from their database, and SHOULD reject future events from the pubkey.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Relays receiving a pubkey revocation event MUST mark the pubkey as revoked, and MUST stop delivering events from this pubkey to clients, EXCEPT for events of kind `5`. Relays MAY delete events by this pubkey from their database, and SHOULD reject future events from the pubkey.
Relays receiving a pubkey revocation event MUST mark the pubkey as revoked, and MUST stop delivering events from this pubkey to clients, EXCEPT for events of kind `5`. Relays MAY delete events by this pubkey from their database, and SHOULD reject future non-kind `5` events from the pubkey.

@mikedilger
Copy link
Contributor

My understanding of MAY, SHOULD, and MUST is in relation to whether or not your implementation will be compatible with everything else. So if you say a client MUST not show content because that could be nasty content from the attacker, technically it wouldn't cause incompatibility. I'd revisit them with that in mind.

My understanding of these words MAY be wrong and SHOULD be corrected if wrong.

@fiatjaf
Copy link
Member

fiatjaf commented Mar 22, 2023

The problem with this NIP is the persistent state requirement it introduces.

NIP-41, for example, states that a public key that was invalidated must be forgotten and removed from follow lists of clients, but it doesn't say relays must ban them or anything like that -- because it didn't want to introduce the persistent state requirement.

But if this NIP is adopted then NIP-41 can also include a clause to apply the same effects of this NIP.

@fiatjaf
Copy link
Member

fiatjaf commented Mar 22, 2023

Also I think the name "revocation" is not appropriate here. It has the connotation of a guaranteed and global revocation state, which this NIP cannot guarantee.

For example, if I want to scam people without ruining my reputation I can do it, then issue a backdated "revocation" event and then claim it wasn't me. And since the NIP says "revocation" I may get away with that, and blame the victims for not having known about my "revocation".

@alexgleason
Copy link
Member Author

@fiatjaf NIP-41 only applies to keys you generated with a seed though, right? We need the ability to invalidate a pubkey regardless of how it was generated.

@Semisol
Copy link
Collaborator

Semisol commented Mar 26, 2023

Unsure what to call it

@powershellshock
Copy link

powershellshock commented Apr 6, 2023

Call them Burn Notices

Sorry, all. I know I am new to this conversation (at jared on nostr) but I have also been thinking about this alot and working on a NIP for this, too. I won't shill my whole NIP draft on you all, since we are mostly on the same path. Rather, I suggest the following with details available in my proposal below.

  1. Name for this NIP should be "Burn Notices"
  2. Include reason codes in the p tag: unspecified, migration, mishandling, compromise
  3. Optionally, include a new npub hint in the burn notice, so users can burn their keys without burning their network
  4. Clients / relays can detect new or conflicting burn notices for npubs with which they want to moderate interaction accordingly. For example, clients might only allow follower migration (hence the new npub hint), DM's, and zapping to npub hints of burnt npubs after trust problems and conflicts can be resolved by the following client+user.
  5. New services might form around nostr to provide npub trust scoring/alerting services, in the future.

---BEGIN PROPOSAL DRAFT---

NIP Proposal: Burn Notices
author: Jared Poeppelman
“Let the users burn their keys without burning their network!”

This NIP helps improve the nostr network’s security and user experience for key deprecation scenarios such as key migration, mishandling, and compromise.

Currently, key compromise, mishandling, and migration can only be handled ad-hoc, with user’s notifying their network with a social post “Hey, I stopped using this old npub, here is my new npub. Don’t zap anyone pretending to be me with the old npub.” Hopefully, followers/zappers take on the cumbersome task of moving to the new npub and avoiding the old npub.
Burn notices simply formalize this announcement to an event structure for users to self-sign and report “burnt” keys by informing the network of the key’s deprecation and, optionally, a hint to a new npub that clients / relays can use to help the user’s followers/zappers migrate to the new npub.
Of course, if a key is compromised, a malicious actor with the key could issue pre-emptive or conflicting burn notices for DoS or follower-hijacking purposes, so recent burn notices and conflicting burn notices for one key but with conflicting npub hints should be handled mindfully.

Nostr is rapidly growing not just in network size but also in functionality and application. The user-controlled public-private keypairs underpin the security of the network and with the potential of nostr-based decentralized identity (NIP-42, NIP-46, etc.) usage to expand, key lifecycle management will become more important as the network grows.
NIP-56 (Reporting) has provided ability for users to report other users, but does not cover self-reporting key deprecation, as described in this NIP.

A burn notice is simply a kind 10187 event that is used to notify the nostr network that a pubkey is compromised. It is a regular event (vs replaceable event) so that more than one burn notice can be issued per pubkey. This is important so that a user can issue a corrective burn notice, if an attacker issued a pre-emptive
Additional services may also arise to provide pubkey trust analysis / monitoring services based on burn notices, recent profile updates, and NIP-56 impersonation reports.

Tags
The burn notice event MUST include a p tag with the pubkey being burnt (and it must be signed by the same key)
A report type string MUST be included in the p tag being reported, which consists of the following report types:
• unspecified – no reason provided
• migration – no unauthorized key disclosure or mishandling suspected
• mishandling – no unauthorized key disclosure, but improper handling may have occurred
• compromise – unauthorized key disclosure confirmed or highly likely
The p tag CAN include a hint to the new npub, unless the user does not wish to specify a new npub hint.
If no pubkey hint will be provided, the reason SHOULD be ‘unspecified’.

Example burn notice
{
"kind": 10187,
"tags": [
[ "p", burntPubkey, "compromise", targetNpubHint]
]
}

Relay behavior
Relays MUST NOT publish any burn notices not signed by the private key being burnt.
Relays SHOULD store only the most recent burn notice for some limited number (2-5 perhaps) of unique combinations of npub and npub hint. This enables the nostr network to be able to determine the age and conflict state of burn notices for any given npub, as well as what target npubs are proposed by the hints in the burn notices.
Combined with NIP-56 reports, npub activity analysis, and likely other techniques, the nostr network will be able to build a stronger web of trust.

Client behavior
Clients SHOULD warn users before they send DM’s or zaps to “burnt” pubkeys.
Clients SHOULD alert the user if their own npub has been “burnt” recently and allow them to issue a corrective burn notice with a hint to a new npub, if necessary.
Clients SHOULD present followers/zappers with burn notice conflict warnings and/or deconfliction choices, so they can potentially identify the correct target npub via other (non-nostr) comms channels.
Clients MAY choose to prompt users when conflicting new npub hints are provided (such as a real one from the user and a spoofed one from an attacker) so that the follower/zapper must deconflict (perhaps via other channels) before proceeding.
If the burn notice provides an npub hint and is sufficiently aged and deconflicted, clients MAY choose to auto-follow the new npub / auto-unfollow the old, but the user SHOULD be informed in some way.

@alexgleason
Copy link
Member Author

@powershellshock thank you for chiming in! I'm open to the implementation being different, I just want the problem to be solved. I think it's critical for the Nostr network.

@powershellshock
Copy link

powershellshock commented Apr 10, 2023

thanks, @alexgleason. i too feel this is critical for Nostr. and i appreciate your willingness to collaborate on this which i also share. i am always willing to be convinced against my own opinions. so if my tone ever seems otherwise, please understand that. my expertise lies in cybersecurity and identity (IAM, as its called in the enterprise identity space), more than as a developer.

my concern is more about the proposed behavior than specific implementation details of the json event/tag data structures. i am concerned with any bulk deletion of events or blocking any interaction with the burnt npub, as this presents an advantage for a malicious party in that they can easily burn down the network of the user with little notice or recourse for the user. instead, i think we need to look at options that give useful information to clients, relays, and users for identifying trust/reputational factors about npubs. (this will also likely lead to nostr-based services around providing and monitoring trust factors for npubs.)

Threat Model:
when we think about the threat model in this scenario, we have a situation where two parties have a copy of a private key. party A is the authorized user who likely generated the keypair. party B is the unauthorized holder of the private key who may have obtained the key in a variety of ways.

if B wants to abuse the private key, there are basically two key threats (applying the STRIDE threat model):

  1. Spoofing - B wants to pretend to be A from a social network or financial payment perspective
  2. Denial-of-Service - B wants to burn down A's social network or identity

Behavior Recommendations:
Instead of hard-blocking anything, we should allow conflicting burn notices to exist, so that other users can be aware of the potential trust issues with the burnt npub.

When a new burn notice is issued, it should be considered "suspect" until it reaches a sufficient age without a conflicting burn notice being issued. This gives time for A to login to a client that alerts them that their npub was burnt (by B) and allows them to issue a new burn notice (with a hint to the new legitimate npub).

When a conflicting burn notice is issued for an npub, it should be treated like a fork in the road for the user C that is a follower/zapper of A. If the client cannot resolve the conflict with available information (age and number of burn notices, NIP-56 impersonation reports, etc), then it can simply present C with relevant details of both (timestamp of burn notices and what the new npub hint is). The user should be ultimately identifying the right burn notice to follow. (Clients could then report the not-followed burn notice via NIP-56 reporting it as an "impersonation". As the clock and blocks ticks by, the network will become "aware" of which burn notice was actually issued by A, as those followers closest to A are able de-conflict the burn notices outside of nostr.

Hopefully, my logic makes sense here. It is just really hard to take active measures based on a single burn notice without creating an advantage for adversaries over the users.

Thoughts?

@alexgleason
Copy link
Member Author

@fiatjaf Can you review this proposal again?

@alexgleason
Copy link
Member Author

Also I think the name "revocation" is not appropriate here. It has the connotation of a guaranteed and global revocation state, which this NIP cannot guarantee.

Kind 5 is called "deletion" even though it's not guaranteed, and has basically the same semantics as this MR, so I think calling it "Pubkey Deletion" like it was originally is appropriate and makes it consistent with other parts of the spec.

"Deletion" is the term users understand. This is what we call it in the ActivityPub world too, even though it's also not guaranteed there. Whether it's perfectly semantically correct doesn't matter.

@alexgleason alexgleason changed the title NIP-109: Public Key Revocation NIP-109: Pubkey Deletion Apr 23, 2023
@fiatjaf
Copy link
Member

fiatjaf commented Apr 23, 2023

I am fine with this NIP, it is simple and useful (as long as you like the idea of we incrementing it with NIP-41 later, or some other deletion methods that may appear).

I just think it should be a NIP under the number 100 (yes, I am hoping we will have just 100 NIPs and then we can move to some decentralized NIP registry with no inherent sequence).

However I won't merge until other implementors signal their approval and some implementations happen.

@Semisol
Copy link
Collaborator

Semisol commented Apr 24, 2023

The intent tag is not used anywhere, and the usage of it in other events mostly doesn't matter for this context, for your information.

@cameri
Copy link
Member

cameri commented May 7, 2023

@alexgleason looking into this

@cameri
Copy link
Member

cameri commented May 7, 2023

@alexgleason I like the simplicity, but I am concerned that it only takes 1 kind 5 event to burn a key.
I would prefer if we could have a second confirmation event that includes the ID of the kind 5 event to confirm you really want to burn that key after like a 24 hour period. Perhaps the period could be specified in the first kind 5 event.

There's no tech support in Nostr, some people are going to make mistakes... it's happened already and it's really tough for the unfortunate user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants