Closed dhh1128 closed 3 years ago
I would expect that you would not need a new verification method type....
we are also past the feature freeze date.... and headed into CR.
To me it sounds like you want to identify that a specific keyAgreement
key is used for some specific purpose... You can do this a few ways...
did:example:123#didcomm-multiplex-key
did:example:123?didcomm=multiple#key
Another option might be using the controller
property to disambiguate...
"id": "did:example:123",
"keyAgreement": [
{
"id": "#didcomm-multiplex-key",
"type": "JsonWebKey2020",
"controller": "did:example:456", // maybe?
"publicKeyJwk": {
"kty": "OKP",
"crv": "X25519",
"x": "VYl2LVJ1fsdgIKZwwPxxV31Eey2RgN6TxeIuAN8oayw"
}
}
]
If you can provide a JSON example of what you want to see, it might be easier to assist with your use case.
Hmm I think the controller property may work best for that if we don't want to add a new verificationMethod. However, in my mind this actually isn't anything related to the semantics of a verification since it's ingress only usage, where as "verification" implies egress usage.
The other option we have with the usage of publicKeyJwk is that we can include the use
property where only keys which contain a use
that's specific to this (which would require an IANA registration) or we might be able to modify the values in the type properties of LD key definitions (e.g. JsonWebKey2021) which adds a usage property. @msporny has argued that this is exactly why usage is included in the type property as well, so he may come in with some strong opinions on how to do this as well.
I don't understand how a fragment or a query allows me to express the semantics I want. They allow me to get a particular piece of data associated with a DID document, but they don't let me declare the meaning of that piece of info (which is what I need). The meaning does not vary by the caller/client/use case; it needs to be intentionally locked to that meaning by the DID controller.
Your controller
example makes more sense in some ways, but I am not confident of the meaning you're intending. Are you saying that any verification method in a DID Document that has a controller other than the @id
property of the doc itself should be interpreted as an auditor?
What I want is a way to say something approximately like this, in a DID doc:
{
"id": "did:example:123",
"keyAgreement": [
// Normal public keys that can negotiate a symmetric key for encryption+decryption.
// The use of these keys in encrypted outbound communication authenticates the sender
// in some sense, but differs from `authentication` or `assertionMethod` in that it is
// repudiable.
],
"oversight": [
// Keys that the DID controller wants to be able to decrypt inbound
// comms for the DID, but that should not be used to emit encrypt
// outbound comms. They might be used to negotiate a symmetric key,
// but only with a one-way purpose.
]
}
Re. being past freeze and approaching CR: I understand. The mechanism I'm imagining could be declared outside of DID core. But I would still like to discuss it within this group, because I want to harmonize how it works with did core as much as is practical.
@dhh1128, this sounds like it could be an optional property of a keyAgreement
verification method. It would signal that applications, when using keyAgreement
verification method X as a recipient, should also include Y as a recipient. For example:
{
"id": "did:example:123",
"keyAgreement": [{
"id": "did:example:123#abc",
"type": "SomeKeyAgreementType",
// applications that select this key agreement key may honor the
// DID controller's request to include these one or more additional
// recipients in any comms sent to it (name could be bikeshedded of course)
// also, it could list just DIDs, not specific keys if you want some recursive oversight
// capabilities as well
"additionalRecipient": ["did:example:456#def", ...]
}]
}
Would this solve your use case?
@dlongley : yes, that would probably work. However, it makes the additionalRecipient
a subproperty of an individual key, whereas we would need it as a subproperty of all keyAgreement entries, collectively. That is, if Alice declares a key for her mobile phone, her laptop, and her tablet, there would be 3 keys in the keyAgreement
array, but the oversight keys I was postulating would apply across all of them. So it might be cleaner to create a property under all keyAgreement
entries named "outbound" that defaults to true -- then list additional recipients as peers rather than subobjects of individual keys. Something like:
{
"id": "did:example:123",
"keyAgreement": [{
"id": "did:example:123#abc",
"type": "SomeKeyAgreementType",
}, {
"id": "did:example:456:abc",
"type": "SomeKeyAgreementType",
"outbound": false // makes this like the additionalRecipient, but as a peer of other keys
}
]
}
Stepping back from that specific idea for a moment, I think @kdenhartog 's point is an important one. We have defined verification methods to be things that prove something about the outward actions of the DID controller. It's not obvious to me that something without any ability to prove anything, and that is only use inbound, is a good fit. (But to play the devil's advocate, we could say that we're adding this attribute to key agreement to constrain its scope, which makes a sort of sense...) A corner case that tests whether we like the answer is: what if a DID controller doesn't want to allow any outbound comms (e.g., wants to say to the world, "I will never speak to you on an encrypted channel, but feel free to send to me at the following keys") -- does our solution let us model this, when there is no verification method being described at all? But I don't know if this corner case is important enough to really care about...
@dhh1128,
Yes, that would probably work. However, it makes the additionalRecipient a subproperty of an individual key, whereas we would need it as a subproperty of all keyAgreement entries, collectively. That is, if Alice declares a key for her mobile phone, her laptop, and her tablet, there would be 3 keys in the keyAgreement array, but the oversight keys I was postulating would apply across all of them.
I would think that someone may want to have more optionality/granularity. You may want to have some keys that, when used, should include other recipients, and other keys where that isn't the case. You may also want (or need) different auditor keys for different cases.
what if a DID controller doesn't want to allow any outbound comms (e.g., wants to say to the world, "I will never speak to you on an encrypted channel, but feel free to send to me at the following keys") -- does our solution let us model this, when there is no verification method being described at all?
I don't know that we need to announce this sort of thing in a DID Document. If you don't want to send outbound comms, just don't send them. That being said, if people want to add extensions that allow these sorts of things to be stated, they can be, IMO, I'm just not sure that it's the right layer to be doing it.
I would think that someone may want to have more optionality/granularity.
Okay, I can buy that.
What registration process would you recommend for this additional property?
I don't know that we need to announce this sort of thing in a DID Document.
Okay. Let's lay that corner case to rest.
@dhh1128,
What registration process would you recommend for this additional property?
The CCG is where specs for this sort of thing are usually incubated and registration of the spec that defines the property/verification method types it is used with would end up in the DID spec registries. I'd expect anyone interested/already working on verification methods used with key agreement would be interested in this.
I'm content to close this issue. I had the helpful discussion I was hoping for. Thanks.
I have a use case where I want to list a key in a DID doc that is used to decrypt for the DID, but that cannot be used to encrypt. This would be a key used by an auditor. The auditor doesn't have control of the DID, but has oversight of the DID. The auditor should never be able to emit outbound communications as if coming from the DID, but should be able to decrypt inbound communications. This would be used in DIDComm multiplex encryption (which imagines Alice encrypting for each decryption key Bob declares, so Bob can pick up a message on any device without sharing keys anywhere). For more info about the use case, see "3. Opt-in Front Door Keys" here.
The current
keyAgreement
verification method that we document conflates encryption and decryption. I think this is a common scenario, so I don't have a problem with it. But I would like to introduce this other concept. Should I raise a PR explaining this more nuanced verification method? Or should I break apartkeyAgreement
into its two parts which are normally but not always reciprocal? Or would we say that being able to decrypt isn't a verification method at all, since it doesn't verify the recipient?Referencing @llorllale and @telegramsam, who discussed this on a Hyperledger call.