-
Notifications
You must be signed in to change notification settings - Fork 580
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-102: Subkey Attestation #1450
base: master
Are you sure you want to change the base?
Conversation
FYI NIP-100 is already used in this PR: #1411 |
Moved to NIP-102 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a benefit to using HD keys rather than just arbitrary sub-keys? The reason I ask is the sub-keys have to be published anyway, so the deterministic connection doesn't seem to matter much.
The challenge with this sort of thing has always been the soft-fork nature of making clients aware of relationships between keys. Not a terribly difficult problem, but it would be some time before this could be really usable.
102.md
Outdated
The parent key can publish a `Kind 10102` event for subkey management. This event lists subkeys that have been revoked, as well as those that are currently active, and a preference for how valid subkeys that are not listed should be treated. This is only a preference, as it may not always be immediately available to clients and relays. | ||
|
||
Content: | ||
```json | ||
{ | ||
"keys": { | ||
"<hex-subkey0-pubkey>": { "active_at": "<epoch-timestamp>" }, | ||
"<hex-subkey1-pubkey>": { "active_at": "<epoch-timestamp>", "revoked_at": "<epoch-timestamp>" }, | ||
"<hex-subkey2-pubkey>": { "active_at": "<epoch-timestamp>" } | ||
}, | ||
"default_policy": "allow" | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd model this using single-letter tags so that they can be indexed. That would then obviate the need for adding an account
tag to every event published by a subkey, since client could just fetch any 10102
s for pubkeys they don't recognize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that I understand how using a single letter tag would change whether or not we need a tag with the account
s npub. My suspicion is that the pipeline stalls caused by constantly fetching new 10102
s would outweigh the space savings. Is the efficiency of single-letter vs word tags due to how relays are optimized?
HD subkkeys don't strictly need to be published beforehand. Any key can claim to be a subkey of an npub, but only those actually derived from it will validate. This lets you take a trust-but-verify (that it hasn't been revoked) approach. For non-destructive/competitive events, we can first assume that a key has not been revoked, then get around to verifying it later (same as purple checks). For replacements and deletes, we would want to verify first. As far as client and relay adoption goes, if there are no major objections to this proposal I'll look into how to implement it for key projects. |
I have been using subkeys for a while, and I love them. Subkeys should be a standalone nip, and not coupled to use cases such as user locking. While I personally prefer open ended subkeys (maybe that's still possible, here?) I can live with this solution as a way of working. I do already have subkeys to my master key, so it would be nice if it would be possible for me to link those still, rather than have to start a new hierarchy. |
I wish I had done this for the Mostr Bridge. |
Instead of a list of active keys why not just do a bloomfilter (or equivalent structure)? In that way, users don't need to expose all keys their master accounts use. Yes, people could still collect ALL events and filter all The active dates don't really work. If they are based on |
The goal of
Agreed. I'll clarify that these attributes are non-authoritative, but I think it's good to include some record of the expected timing. |
If they were created using the same derivation ( |
Make an "active" set just for DMs, then. DMs are not going to be in every client. There will be two/three orders of magnitude more keys than the ones used by DM-enabled clients.
Sounds like wishful thinking. There is nothing anyone can reliably do with those dates. It only adds insecurity to the proposal. |
What would that look like? Renaming
That's fair. If an account wants to be able to revoke a key while preserving historical content, they could aggressively rotate them. Aside from the hassle of rotating keys securely, there's nothing that should prevent someone from using a new subkey for every message. |
Sure. I think more key sets will show up as new NIPs arrive. Thus, I would align the name to the thing that the group of keys is supposed to be used for... in this case, to group keys as a chat group and encrypt to them. We discussed key aliases for DMs in the past: #1306 Your idea is somewhat similar, but instead of senders just picking one, as in #1306, they have to encrypt all of them. #1306 is an OR filter, here it is an AND. |
I didnt use that no. There's quite a few different KDFs possible. Then there are random keys for completely unlinked personae. |
…r tag . Clarify migration path. Add a note about defensive coding.
First read just now and I'm kicking myself that I didn't think of this. I had thought that subkeys required some kind of signed document that tied the master key to the subkey. I forgot you could derive a subkey algorithmically... so I'm very glad to have seen this NIP. This is a little bit like NIP-26 delegated event signing, except no conditions, actually the same principal not really delegated. But it has that tag saying which real identity the event author is. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Knowledge of the parent xpub and a child private key being compromised causes compromise of all keys derived from the xpub.
This is the best reason for code reviews. I did some research, and it is unfortunately correct. The only property of HD keys that's essential here is the ability to validate their derivation from the claimed identity pubkey without any additional information. This keeps things fast in the common case, though we still need to do a lookup to confirm non-redaction before making destructive changes (eg, replaceable events, or revocation events). We can implement this same property with a non-HD key by including an attestation that this key is part of the main identity, signed by the main key. This adds more data to each message, and makes this NIP look very similar to NIP-26. So, what's wrong with NIP-26? Adoption has been low enough to soft-deprecate it and remove the code from some clients, even though it seems to solve an important problem that still doesn't have a satisfying solution. An obvious criticism is that it's too complicated, and adds a lot of data to each message. This comes from the idea that keys aren't merely revokable tokens, but have specific authorizations based the attributes they are allowed to publish: kind, created_at, etc. @vitorpamplona pointed out the limited value of making decisions on created_at. Both these rules and the attestation need to be included in every message, even though they are of limited use. If we've given up on NIP-26, does it make sense to re-imagine a lighter version? Specifically one that looks exactly like this proposal, with the addition of the smallest possible attestation from the already included |
NIP-26 had 3 problems. It had conditions of questionable use. It had a non-searchable tag. And it required both relays and clients to support it before it became useful... there was no easy path through partial support. Solve those three problems and you'll have a winner. BTW, you can prove part of the BIP-32 tree belongs to your pub without releasing your xpub. |
Just my 5 cents here. HD keys are terrible. Anything is better. For example,
That quote by @Semisol is true. Only hardened hd keys don't suffer from this. |
The problem with hardened keys is that there's no way to validate that a public key is derived from the parent's public key, so there's no point in using them. I've been mulling on an attestation based variant that I just pushed. It's similar to NIP-26 delegation without conditions, and I think it's feasible without significant relay support. |
b43ea84
to
2308e84
Compare
"kind": 1, | ||
"tags": [ | ||
["I", "<hex-account0-pubkey>"], | ||
["Ia", "<subkey1-attestation>"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is correct because we won't search for the attestation. If there are other reasons to use single characters I was considering J
.
Just a reminder: I'm a newbie Nostr developer and I have no experience with public/private key infrastructure. I understand that NIP-26 only deals with delegation, that is, it does not deals with token revocation or token management (it is quite similar to JWT), and worst, its attestation token is valid forever! In my opinion, it can be deprecated right now #1051 I was sad to know that using hierarchical deterministic subkeys is problematic. It would be very important to validate that the public key is derived from the parent's public key. But at the same time I'm happy, because this opens up the possibility for an existing account to be able to manage its own events and events on behalf of another account at the same time! @ynniv I liked your proposal, simple and direct (aligned with the Fiatjaf's philosophy/methodology). It deals with key management and revocation. In my opinion, it is ready to be approved. Just a small change, I would love to use the I am interested in this approval, as I already have plans to use it in the client I am developing 😁 addendum:
|
This introduces absurd complexity that makes Nostr unusable. |
While I agree that it could be confusing without significant client adoption, I think backwards compatibility allows for some clients to lead the way. Impact on the relays is minimal, and primarily about replaceable events and deletion requests. To me, key management is critical, and coming up with a way forward is worth the effort. |
Sub-key management is very important, and will become even more important with more adoption coming. We also made a suggestion for sub-key management in this PR #1482 if you want to check it out. Whatever the option, Nostr needs a way for sub-key delegation and revocation/undelegation! NIP-26 is clearly not enough and a simpler and more usable option is very important. Even to replace NIP-26 completely, why not? |
@ice-orestes I analyzed your proposal. @vitorpamplona asked you about the use of timestamps. You said that this would prevent replay attacks. @ynniv proposal does not use timestamps and it seems to work very well. Since these are replaceable events, you just need to rely on the "created_at" attribute. Am I wrong in my reasoning? (reminder, I'm a newbie Nostr developer). |
This NIP defines a way to separate identity from authentication using hierarchical deterministic (HD) keys. This allows people to use one key pair to issue independent key pairs for different apps. If a key is compromised, the root key pair can publish an event revoking that key as of a specific time.
HD keys (BIP-32, BIP-39, BIP-44) provide a means of creating new key pairs from a parent in such a way that the new pubkey can be verified to be a child of the parent's pubkey. A message signed by this new key can be rapidly and locally verified as an authentic subkey of the claimed parent.