nostr-protocol / nips

Nostr Implementation Possibilities
2.39k stars 582 forks source link

NIP-0b - On-Behalf of (Simple Sub-Key Management) #1482

Open ice-orestes opened 2 months ago

ice-orestes commented 2 months ago

Prior art:

This NIP defines a simple way for an Identity Sub-Key management system, including active, inactive and revoked public keys, for publishing On-Behalf of a master identity.

Why?

Each of these methods has their own pros and cons, but there's a very common use case that is not covered by any of these methods completely, which is having a master identity that is secure (possibly in cold storage), that can whitelist and blacklist multiple public keys (one for each device or app, for example), that can be used individually (less common but interesting for media management companies) and can publish on-behalf of one or several master identities.

Using NIP-26 for this purpose doesn't allow for blacklisting (revocation), or alternatively requires time bound delegation, with new delegation signing at every expiry. On the other hand NIP-41 is a more complete and complex identity management solution, but only allows for one active sub-key at any point in time, and that sub-key's only purpose is bound to the main identity.

fiatjaf commented 2 months ago

Vitor said it all.

ice-orestes commented 2 months ago

In general, this does create significant burdens for signers and verifiers as well as broken user experiences between clients and relays that do and don't implement it. The only way to solve the UX is to make this mandatory for all of Nostr, which significantly increases the startup time of any Nostr project. Complexity goes through the roof.

First of all, thanks a lot for your review @vitorpamplona . Since there's a lot to unpack there, let's start with this first...

The way we imagined this was that:

This should be similar to NIP-26 for relays and clients that don't implement it. But maybe we're missing something, so please advise...

vitorpamplona commented 2 months ago

This should be similar to NIP-26

Yeah. Some/many of these issues are also on NIP-26 and that's why no one implements NIP-26 and why I proposed to deprecate it entirely #1051

ice-orestes commented 1 month ago

I do agree with the fact that NIP-26 has many issues, but there's a clear need for having account delegation, and possibly the revocation part that we include in our proposal can open this feature to more usage. At least in our use case we need it because our main account will be a blockchain key pair, and it would be costly to sign all events with it... that way we need the feature of having sub-accounts that can reside on multiple devices to sign events on-behalf of the main account. We also require those sub-accounts to be able to rotate and even be revoked in case of compromised or lost devices, for instance. In sum, we think this is not a very uncommon use case, and security wise it is a good practice to implement such an architecture, so there's a real need for a account delegation and revocation in nostr, NIP-26 didn't cover it so we propose some alternative that can even substitute NIP-26 (although that wasn't the initial thought), as it requires less signature verifications and includes a rotation and revocation mechanism as well.

ice-orestes commented 1 month ago

Addressing the other points of @vitorpamplona initial comment:

It also does not solve how to deal with encryption and shared secrets for event kinds that need it, like DMs and private group chats. Meaning that, subkeys don't see what the main account and other subkeys are encrypting/decrypting even when authorized.

True for all ECDH Key Exchange based functionality, as they rely on participant accounts private keys to compute the shared secret. This limitation is also valid to any sub-account mechanism in nostr. But we had a few attempts like PR #59, or PR #580, to have a single shared secret effectively shared, by DM or replaceable event, encrypted to each participant. Something alike would solve this problem and allow sub-accounts to coexist peacefully with DMs and private group chats in nostr.

More importantly, this type of delegation changes the indexing of replaceable events. Since subkeys can change replaceables of the main key, queries by a tag must be broken down to also search by changes from authorized b keys.

True. Relays should consider a replaceable with a valid b tag as effectively coming from the master account, that way this problem is mitigated.

Relays that keep only the last event per pubkey in the 10000-20000 range must now also account for subkeys and those subkeys can be dynamically changed at any time, past and future (by rebroadcasting past kind 10100 events or deleting them, reverting to a previous state).

This is why we have these requirements for kind 10100:

A replaceable that has a b tag cannot affect the indexing of the sub key's own replaceables and should not be returned when a client requests the replaceables of the subkey.

Exactly, relays that receive a replaceable event with a valid b tag should apply it to the master account and ignore it on the sub-account level. Maybe this should be added to the last section of the NIP?

One can also create an elaborate attack by using a past kind 10100 when the stolen subkey was still authorized. The attacker gets the past version, sends it to a relay the attacker controls, and doesn't allow that event to be replaced by newer versions. Now new posts by the sub key can make clients think the attacker's relay is the main account's relay, which will make users see the stolen key as still valid.

Not sure what you mean by and doesn't allow that event to be replaced by newer versions, as I am not aware of a way for a single relay to block other relays from accepting new versions, or make clients think the attacker's relay is the main account's relay, as I don't know what that means, do you mean NIP-65 relay list metadata?

Thanks again for your comments and looking forward to improve this NIP with all the input...