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

Add "z" as authorized deletion pubkey tag #539

Closed

Conversation

arthurfranca
Copy link
Contributor

@arthurfranca arthurfranca commented May 18, 2023

Edit: It was ! tag but now it is z tag.

This describes that in addition to being able to delete one own events, one can authorize someone else to delete some of his events.

It works by publishing any event like this:

{
   "id": "id1",
   "kind": 111, // any kind
   "author": "me", 
   "tags": [
      ["!", "pubkey of someone else"] // now me OR this guy can delete the event with id == "id1"
   ]
   // ... other fields
}

This is useful when you want to be able to delete an event someone sent you (e.g.: with a p tag with your pubkey) after you have already comsumed it (e.g.: you have already read its content).

One example, consider a "friend request" event. I can query friend requests with ! tag equal to my pubkey and ignore the rest (that's why ! is added to NIP-12). Now I am able to reject a friend request by issuing a deletion event to the relay, even though I'm not the friend request author.

There exists many use cases that would benefit from having dismissable events such as the above one. It makes it possible to clean some received "notifications" which would otherwise require to persist auxiliary events to track soft-dismissed notifications.

@arthurfranca
Copy link
Contributor Author

I am in look for feedback regarding adding ! to NIP-12.
I thought of using a z tag instead but was afraid of pissing someone off who may be already using it. Although it would be a problem just for people who is not only using z tag, but also filling it wiith pubkey values.

@LockeShor
Copy link

This looks a lot like delegated event signing, but specific to a single event. Have you considered something more similar to NIP-26 Delegation? Maybe some extension of the original spec?

@arthurfranca
Copy link
Contributor Author

@Redpug111 Yes, I've considered and for now concluded that it would be harder, although possible.

With NIP-26, user A delegates kind 5 creation to user B, but how to limit user B to deleting an event with a specific id (creating kind 5 with specific e tag)?

First we would have to edit NIP-26 to allow tag condition (the e tag from kind 5). And, as a side note, I anticipate many voices of disapproval coming from the nostr community, as they always do with NIP-26.

Then i would not be able to embbed the delegation token on the same event I wish to be deleted in the future.

For instance, I can't do this:

{
  "id": "event_id_a",
  "kind": 63275343,
  "tags": [
    [
      "delegate_this",
      "kind=5&#e=event_id_a", // can't do this because event.tags is used to generate the event.id, so don't know that the value is "event_id_a" yet
      "sha256signature"
    ]
    // other tags
  ]
  // ... other fields
}

So we would have to create an auxiliary event (or other means) linked to the main one just to transfer "delegate_this" data to user B.


There is another way that would allow me to embbed the "delegate_this" tag on same event I want to be deleted in the future, like using a condition such as "kind=5&#n=ramdon_nonce" and add that n nonce tag to the same event. But, we would still have to change how kind 5 work by having relays/clients validate that the n tag is there when they receive a kind 5 with such tag. So something like that would be cumbersome.

@fiatjaf
Copy link
Member

fiatjaf commented May 18, 2023

I kinda like the spirit of this, but I would prefer that relays implemented custom hardcoded support for kinds-that-warrant-deletion allowing the p mentioned people to delete the events.

First because it makes the protocol more flexible without creating yet another NIP that has to be read by everybody.

And also because it would prevent some asshole from creating their notification events without the ! thus making their notifications "sticky" forever.

@arthurfranca
Copy link
Contributor Author

arthurfranca commented May 18, 2023

And also because it would prevent some asshole from creating their notification events without the ! thus making their notifications "sticky" forever.

This is addressed, cause you can query just events of the kind you want and with a must have ! tag with your pubkey. So you are effectively ignoring events from punks without the !. edit: although I get that with a specific kind the up side is relay could validate it and reject if it wants.

For events that shouldn't be deleted by the receiver side (DMs for example) but the receiver still wants to take control of his notifications/inbox, I created the Event Copy PR, that also seems to be misunderstood - please see this example.

...yet another NIP that has to be read by everybody.

Sorry but this PR is creation zero new NIP. It is just adding som text to the Deletion Event NIP and to the NIP-12 (the latter to allow the ! tag to be queriable. It could be a 'z' tag instead if it is a problem)

@arthurfranca
Copy link
Contributor Author

arthurfranca commented May 21, 2023

I would prefer that relays implemented custom hardcoded support for kinds-that-warrant-deletion

What if kind 5555 has the said behavior but now a new kind 7777 made it into a NIP and has the same behavior? all relays must update their hard-coded list

What if someone needs kind 30078 - app-specific data to have this behavior? again relays must update their hard-coded list

What if I'm using a custom kind that isn't a NIP yet or will never make it into one and I want this behavior? you are out of luck. no relay will honor the expected behavior. you must use your own custom centralized relay and update the hard-coded list

I'd say the reasons to make it a behavior available to any kind are similar to why expiration tag can be used with any event kind.

@arthurfranca
Copy link
Contributor Author

I think this PR is a basic need @fiatjaf and should be available to any event kind because of above comment. Would you reconsider?

See the last paragraph here for another use case.

@mikedilger
Copy link
Contributor

This is useful when you want to be able to delete an event someone sent you (e.g.: with a p tag with your pubkey) after you have already comsumed it (e.g.: you have already read its content).

This seems like the domain of a client, not of a relay. Other people may also be tagged, or want to read the event.

I can query friend requests with ! tag

'!' is not a single letter, so you can't query it

Now I am able to reject a friend request by issuing a deletion event to the relay

In any useful friend request architecture, deleting the event on the relay would not be a reasonable way to reject the request. Because the friend would never know and might just wait forever. If that were acceptable, might as well just leave the event and ignore it.

There exists many use cases that would benefit from having dismissable events such as the above one. It makes it possible to clean some received "notifications" which would otherwise require to persist auxiliary events to track soft-dismissed notifications.

Again this is very much the domain of a client, not of a relay.

Is your goal here to clean up useless events at relays? or something else? Because that is the only benefit I am seeing, and that can be resolved in other ways (expiration tags or relay policies).

My read of @fiatjaf 's comment is that you dispense with the extra '!' tag, and allow anybody in a 'p' tag to delete... if the event kind is of that sort. Obviously you don't want that for most event kinds... just because I was among the tagged people in a textnote shouldn't allow me to delete the event and not let other tagged people ever see it.

@arthurfranca
Copy link
Contributor Author

Thank for feedback @mikedilger

This seems like the domain of a client, not of a relay

Everything that doesn't involve relays will only happen on client local database which is bad because other clients won't be in sync.

'!' is not a single letter, so you can't query it

This PR edits NIP-12 because of that. It you consider this disruptive, we may reserve a regular tag such as z instead of !. What do you think?

[...] deleting the event on the relay would not be a reasonable way [...] Because the friend would never know and might just wait forever

This "friend request" was an incomplete example. After deleting the initial event, the receiver could also send a "rejection" event to the former sender (that could also be later deleted by the former sender - using this very NIP). It seems Amethyst may need this feature soon. (not the friend request feature, but being able to delete someone else's event).

Is your goal here to clean up useless events at relays? or something else?

Yes this would help relays but the ultimate goal is to make clients interoperate. Cleaning local database is not good for that. When you clear "notifications" on relays, all clients' "notifications" are effectively in sync.

My read of @fiatjaf 's comment is that you dispense with the extra '!' tag, and allow anybody in a 'p' tag to delete... if the event kind is of that sort.

Limiting this behavior to specifc kinds has the problems I mentioned above.

@mikedilger
Copy link
Contributor

Yes this would help relays but the ultimate goal is to make clients interoperate. Cleaning local database is not good for that. When you clear "notifications" on relays, all clients' "notifications" are effectively in sync.

I still don't understand. The absence of an event at a relay carries no meaning whatsoever. Maybe that relay never had such an event. Maybe that relay fails to deliver it because of some error condition. Maybe it was censored. Only the presence of a digitally signed event can carry meaning.

@arthurfranca
Copy link
Contributor Author

@mikedilger steps:
1- install gossip on my PC > fetch my "latest" friend requests notifications from my read relays
2- 5 found > clear notifications (no matter how gossip would implements this)
3- install gossip on my Laptop > fetch my "latest" friend requests notifications from my read relays
4- 5 would be found again 😢

Now if on step 2 gossip could use the authorization granted by the ! tag to delete the 5 notifications from all read relays, step 4 would have found no notifications, right? Isn't this good for relays (space saving) and clients (keeping in sync)?

@mikedilger
Copy link
Contributor

mikedilger commented May 24, 2023

I understand your motivation better now. How about using ephemeral events, and creating a final event in the 'd' tag group that means "this 'd' tag group is deleted"?

[EDIT] oh wait, sorry, of course you couldn't do that to somebody else's events.

@arthurfranca
Copy link
Contributor Author

@mikedilger Did I hear a "Concept ACK"?

The recipient being able to delete from relays the disposable events already consumed/read is imo a basic protocol feature.

Also think it shouldn't be limited to a fixed set of kinds.

@fiatjaf
Copy link
Member

fiatjaf commented May 31, 2023

There are many "basic protocol features" that we don't have depending on what you ask. I'm not against having this, but I think we should see more explicit and obvious demand first.

@arthurfranca
Copy link
Contributor Author

One more immediate use case now that people are talking about is chat groups:

Chat clients only request chat messages that have the tag ['!', <chat_owner_pubkey>] present. Others messages are just ignored.

Now chat owner can send a deletion event to relays to delete any chat message.

@fiatjaf
Copy link
Member

fiatjaf commented Jun 2, 2023

This is actually a very interesting idea. I think it can be useful in many circumstances except my simple group chat NIP-29 proposal.

@arthurfranca
Copy link
Contributor Author

NIP-172: Moderated communities could use this to make community owner able to reject (delete) a previously approved content by a moderator X.

Without it, the only option the community owner has is remove moderator X from the moderator list (effectively rejecting all previously approved content by moderator X).

@vitorpamplona
Copy link
Collaborator

I am not sure this actually achieves much because the author (or anyone that has a copy of the to-be-deleted event) can just re-broadcast it and users will have to dismiss it again. Or delete it again in the case of NIP-172

From a UI perspective, it doesn't make sense to dismiss something just to come back later. It would be better to register the dismissed action in a permanent way.

@arthurfranca
Copy link
Contributor Author

hmm your r right regarding NIP-172 because the community owner would delete the "post approval" but the moderator could end up reapproving the same "post request" by mistake because the "post request" would still be there.

Maybe the community author could do 2 things together:

  1. delete the moderator "post approval" (would need the ! tag)
  2. mark the referenced "post request" as "rejected" by placing the event id in a specific NIP-51 list he keeps just the last 200 entries or so (it can't grow unlimited).

The "rejected" would mean no other moderator should (re)approve.

@staab
Copy link
Member

staab commented Aug 28, 2023

I like this idea, it might help to solve deletion of gift wraps, in which the author doesn't actually exist, so the event can't be deleted. In that case, the only person who should be able to delete it would be the recipient. However, this doesn't solve the problem of deletions with shared keys. What if ! authorized a pubkey instead of the author who can delete the event? Multiple ! could be used to delegate deletion to multiple people — restoring the author's ability to delete as well if needed.

@arthurfranca
Copy link
Contributor Author

@staab good idea. I will update the PR soon.

@vitorpamplona vitorpamplona self-requested a review August 29, 2023 13:49
@alexgleason
Copy link
Member

I don't think we should use a tag called !. Filtering it looks like profanity: { "#!": ["..."] }

It requires modifying NIP-01 to extend the allowed characters in tag names. That potentially breaks existing regexes.

If it were a basic protocol feature, maybe it would be justified, but this is an optional NIP. It should just be a letter, or even a couple of letters.

@arthurfranca
Copy link
Contributor Author

It should just be a letter, or even a couple of letters

I'll quote myself above: "It you consider this disruptive, we may reserve a regular tag such as z instead of !. What do you think?"

It shouldn't be a couple of letters though as it needs to be indexable to open up the possibility to use it in place of the p tag to avoid repetition, when it makes sense.

@alexgleason
Copy link
Member

I support the z tag for this.

@vitorpamplona
Copy link
Collaborator

Why does it need to be indexed?

@arthurfranca
Copy link
Contributor Author

arthurfranca commented Aug 29, 2023

@vitorpamplona to sometimes do this:

{
 tags: [
   ["!",<pubkey xyz>, <relay-url>]
 ]
}

Instead of this:

{
 tags: [
   ["p",<pubkey xyz>, <relay-url>],
   ["!",<pubkey xyz>]
 ]
}

But if overloading other meanings to the ! (or z?) tag seems wrong, we can use a non-indexable tag. Edit: overloading isn't a good idea.
Like deletable_by or simply zz. What do you think?

@vitorpamplona
Copy link
Collaborator

Yeah, it feels wrong to overload p in this example. I like the more verbose/explicit: "deletable_by" or similar.

@arthurfranca
Copy link
Contributor Author

arthurfranca commented Aug 29, 2023

Wait. Now that I've changed it to deletable_by I remembered the real reason why the tag should be indexable.

If you want to fetch just events with a specific "deletable_by" tag. For instance,a client may only consider valid chat messages those that contain the "deletable_by" tag with the chat owner pubkey. Edit: So the client uses a REQ filter that includes the deletable_by z tag.

@vitorpamplona
Copy link
Collaborator

If you want to fetch just events with a specific "deletable_by" tag. For instance,a client may only consider valid chat messages those that contain the "deletable_by" tag with the chat owner pubkey.

hum... Is this needed? I don't know why a client would need that filter. It feels strange to filter by deletable

@arthurfranca
Copy link
Contributor Author

arthurfranca commented Aug 29, 2023

For example this filter: { kinds: [42], "#e": [<kind_40_event_id>], "#z", [<kind_40_author_pubkey>] } for NIP-28 chat messages. This in practice gives the chat owner the power to delete chat messages (because all other messages that don't include the z tag would be ignored by chat clients).

@arthurfranca arthurfranca changed the title Add ! as authorized deletion pubkey tag Add ~!~z as authorized deletion pubkey tag Sep 1, 2023
@arthurfranca arthurfranca changed the title Add ~!~z as authorized deletion pubkey tag Add "z" as authorized deletion pubkey tag Sep 1, 2023
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 adds additional complexity to all client and relay implementations, with no real benefit to any except a few. Relays and clients can decide to honor deletions for certain event kinds from other parties if they want to.

@arthurfranca
Copy link
Contributor Author

One more use case is #1056 (NIP-22 Key Migration).

Instead of saying here that "Supporting Relays and Clients MUST reject Event Deletion (NIP-09) requests of kind:18s." and expect that all relays and clients read the new NIP, using the z tag set to the new account's pubkey would be enough.

@arthurfranca arthurfranca deleted the authorized-deletion branch May 9, 2024 17:22
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.

8 participants