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

Should DID Methods expose Proof Purposes for DID Operations? #289

Closed
OR13 opened this issue May 19, 2020 · 44 comments
Closed

Should DID Methods expose Proof Purposes for DID Operations? #289

OR13 opened this issue May 19, 2020 · 44 comments
Assignees
Labels
question Further information is requested

Comments

@OR13
Copy link
Contributor

OR13 commented May 19, 2020

Recently we had a very passionate sidetree working group call where @csuwildcat and I disagreed strongly on the correct course of action, and as proper gentleman-scholars we resolved to collect feedback from the did wg.

In Sidetree based DID Methods, like did:ion, did:trustbloc, and did:elem there are keys which are used to perform Update/Recover and Deactivate... In DID Core terms, we refer to these as: https://w3c.github.io/did-core/#method-operations

TLDR the spec says you MAY expose keys for DID Operations in the DID Document...

It lists authentication as one place for them, and capabilityInvocation as another.

Let me start by summarizing my position, and then @csuwildcat can lay out his.

I consider sidetree protocol keys used for operation and recovery proof purposes as equivalent to capabilityInvocation... because they are used to invoke the Update or Deactivate Operations by the controller. In addition, while I consider it to be a best practice to not reuse keys for multiple purposes, I also find it desirable to minimize the number of keys needed to create a useful did document.

Here is an example of what I would expect to see:

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    {
      "@base": "did:example:123"
    }
  ],
  "id": "did:example:123",
  "publicKey": [
    {
      "id": "#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
      "type": "JsonWebKey2020",
      "controller": "",
      "publicKeyJwk": {
        "crv": "Ed25519",
        "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
        "kty": "OKP",
        "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
      }
    }
  ],
  "authentication": ["#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"],
  "operation": ["#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"],
  "recovery": [
    {
      "id": "#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A",
      "type": "JsonWebKey2020",
      "controller": "",
      "publicKeyJwk": {
        "crv": "secp256k1",
        "x": "Z4Y3NNOxv0J6tCgqOBFnHnaZhJF6LdulT7z8A-2D5_8",
        "y": "i5a2NtJoUKXkLm6q8nOEu9WOkso1Ag6FTUT6k_LMnGk",
        "kty": "EC",
        "kid": "4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"
      }
    }
  ],
  "assertionMethod": ["#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"],
  "capabilityDelegation": ["#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"],
  "capabilityInvocation": ["#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"],
  "keyAgreement": [
    {
      "id": "#zC8GybikEfyNaausDA4mkT4egP7SNLx2T1d1kujLQbcP6h",
      "type": "X25519KeyAgreementKey2019",
      "controller": "",
      "publicKeyBase58": "CaSHXEvLKS6SfN9aBfkVGBpp15jSnaHazqHgLHp8KZ3Y"
    }
  ]
}

Notice that the key did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A is registered for all kinds of proof purposes.

Notice that the key did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A is only useful for recovery / deactivate.

For consistency and transparency I would prefer to expose recovery and operations in the DID Document as proof purposes.

@csuwildcat would prefer that these keys never be exposed via the did document, because no party other than the did controller is meant to use them, and the did core spec state:

"For example, a DID method MAY: not use the DID Document at all to decide this, but have rules that are "built into" the method."

Daniel's main argument (feel free to correct me) is that recovery and operations are proof purposes that are internal to sidetree, they are used to perform method operations, and as such, they should not be exposed via the DID Document, since there is no use for them outside of DID Method operations.

This area of the spec: https://w3c.github.io/did-core/#method-operations

has a lot of optionality... as authors of sidetree (a spec for helping method implementers create safe / interoperable / ledger agnostic did methods) we are seeking to eliminate some of this optionality...

First a couple of questions:

How many DID Methods have chosen to use option 3?:

"For example, a DID method MAY not use the DID Document at all to determine the authority of a party to carry out the operations, but have rules that are "built into" the method."... in other words... how many did methods are there that don't publish the keys that are used to control the did document... in the did document... is this the common case, or the uncommon case?

We have a couple options:

Option 1

Add normative language to Sidetree Spec, that says that recovery and operation keys MUST NOT be exposed via the DID Document / Resolver Method Meta Data... even though these are publicly observable and correlated to the DID Subject, rational is that the less we talk about them, the less likely someone is to get tricked into using them, or reusing them for other things.

Option 2

Add normative language to Sidetree Spec, that says that recovery and operation proof purposes MUST be exposed via the DID Document. Rational being that they are just like authentication and capabilityInvocation and that as they can be used to mutate the did document by the did controller, we should clearly communicate that publicly (avoiding security through obscurity, following convention of did:ethr / did:btcr).

Option 3

Add normative language to Sidetree Spec, that says that recovery is handled via capabilityInvocation and that operations are handled via authentication... this would effectively endorse the first 2 bullet points and recommend against the third bullet point here: https://w3c.github.io/did-core/#method-operations

Option 4

Allow sidetree methods to choose if they want to expose recovery or operation proof purposes or, if the want those keys to internal (this is basically a no-op, it assumes that the 3 options did core provides are all equally good ideas... something I find hard to believe is true).

@OR13
Copy link
Contributor Author

OR13 commented May 19, 2020

@msporny @dlongley @dhh1128 @awoie

can you comment on how your did methods handle exposing of keys that can be used to update the did document?

do you expose them in the did document?

do you not expose them in the did document?

which option should we recommend for the sidetree spec?

@csuwildcat
Copy link
Contributor

csuwildcat commented May 19, 2020

My points/positions on this issue are as follows:

  1. I believe it is odd to leak out keys into the DID Document that do/may not serve any Method-external purpose (e.g. a key that is not to be used for anything but last-ditch recovery of a DID)
  2. Following on from 1 above, I believe there are concrete security advantages to not adding 'internal'-only keys, like recovery, to the output DID Document, because it could lessen the chance that errantly written wallet code could screw up and allow some inbound DID Doc key referencing request to trigger use of the Method op-capable/recovery key for something other than those sensitive things.
  3. If it turns out folks believe I am wrong about 1 & 2 and/or being too cautious in my security posture, then why aren't these 'verification' methods specified in DID Core? If the answer is that this is what the spec/community intended a DID Document to express, the spec is almost entirely silent about it. If the sort of thing that Orie is advocating for is right/required, what do folks think the spec should do about it? To be clear: I don't think this is what a DID Doc was intended for, but I want to make sure we think about the spec implications if folks disagree with me.

@csuwildcat
Copy link
Contributor

@msporny @dlongley @dhh1128 @awoie

can you comment on how your did methods handle exposing of keys that can be used to update the did document?

do you expose them in the did document?

do you not expose them in the did document?

which option should we recommend for the sidetree spec?

I just want to note something about the above: if this was a convention folks really wanted, and want to mean anything of significance/effect, this seems to be such a fundamental decision that it wouldn't be proper to just have a few Methods agree on some roughly common convention, it should be detailed and mandated in the DID Core spec. I will again cite that I am not of the opinion this is a good practice, or that we should do this, I am just saying that if folks decide this is the Right Path™, it really would need to be codified in the DID Core spec.

@dhh1128
Copy link
Contributor

dhh1128 commented May 19, 2020

I think @SmithSamuelM has a strong opinion about this, and I think it's somewhat like Daniel B's: keep most of this out of a DID doc. I believe the only keys Sam wants in a DID doc are the ones that prove control (currently called the authentication method), with all others removed. But I could be summarizing wrong, so I hope he comments directly.

I do agree with Daniel that if a convention were really wanted around this, we'd see more evidence of it in the spec already. I don't like the conventions that are accreting, so I hope it stays out.

The did:peer method was written before verification methods and proof purposes were explained well; at the time, there were only short, cryptic mentions of them in the DID spec, and there were also descriptions in the spec of sections like authorization that have since been removed. The method thus went down a different path from proof purposes and verification methods, and put everything into an authorization section. At the time, this was entirely kosher; it is now a bit odd and ought to be fixed.

In the authorization section used by early did:peer, all of the things that we now call "verification methods" were defined, and they were assigned authorizations (conceptually broader in scope than verification methods) using a JSON-based rule language called SGL. This had some useful benefits, including a straightforward mapping onto CRDT logic that I wanted for peer-to-peer DID doc replication. A big deal with that method is to only have to replicate DID doc deltas, signed appropriately. I am disappointed in where we've ended up in terms of verification methods; I think they are clumsier, more verbose, and far less flexible than what did:peer had -- and I chafe at the justification that this makes the JSON-LD triplets cleaner, when we were supposed to not have to do headstands to accommodate that worldview. However, if that's the direction the community is going, we will probably evolve into compatibility again soon. We may do this by taking almost everything out of the DID doc and putting it somewhere else. However, we probably can't remove authentication and keyAgreement, since they are required for DIDComm.

I don't think did:peer will ever use capabilityInvocation, because although I love object capabilities, I believe their embodiment in ZCAP-LD is a serious mistake (I believe these should be pure VCs). But that's a whole 'nuther story.

Another person who may have an interesting opinion on the topic is @dhuseby. I think his vision was to express all verification methods in an abstract cryptographic language. He should provide additional details.

@SmithSamuelM
Copy link

SmithSamuelM commented May 20, 2020

In KERI the root-of-trust is a self-certifying identifier. That root-of-trust is a unique binding between the authoritative key pairs and the identifier i.e. the identifier itself is derived via one or more one-way cryptographic functions that include the public-keys from the key pairs.

These authoritative key-pairs have all authority unabridged at inception or issuance of the identifier. In KERI terminology these are the root authority over the identifier.

This root authority includes all authority including but not limited too: authentication, recovery, operation, and capabilityInvocation). That root authority may issue statements anchored to KERI events that authorize or delegate some or all of that authority to other keys. In KERI there are really two important classes of keys. Keys that hold the root authority and keys that do not hold root authority but are revokable authorized by that root authority. Root authority may be transferred via a rotation operation.

The DID term for recovery purpose IMHO is a poor choice of terms. It is ambiguous. In key management practice, "recovery" has two meanings. The most common is refers to recovering lost keys as in "recalling" lost keys. The other use refers to recovery of control authority from keys that have been compromised usually by rotation. If its recall then recovery keys are usually some sharded set of keys that cryptographically reassemble the forgotten key. A clearer term might be recall purpose. If its recovery from compromise then rotation is a clearer term. If it is being used for recall then it needs to be better clarified. In general recall keys should be kept private but one could expose encrypted or ZKP versions as authorized recall key commitments as part of a proof of recall.

So what I believe is that in this issue the term "recovery" is being used to mean recovery of root authority from compromised keys. In this case it is called rotation in KERI which transfers root authority to a new set of key. To clarify, this is not recovery in the sense of recalling forgotten keys but recovery from compromised keys by rotating to new keys. KERI does this with a pre-rotation scheme.

Proof of establishment of control authority requires that the chain of authority be verifiable. This means that the current authoritative set of root authority keys be disclosed. However recovery from compromise (rotation) in KERI uses a pre-rotation scheme. The pre-rotated keys are not disclosed but a hash of the pre-orated keys is disclosed. This means the recovery keys remain private but provable via the cryptographic commitment that is expressed as a hash of the keys in a signed KERI event (this is the pre-rotation). Hence with KERI this issue #289 is a non-issue as the pre-rotation hash preserves privacy yet provides a commitment that may be verified upon rotation (recovery). The pre-rotated keys are not disclosed in a DID:Doc while they are nascent but only after they have been invoked in a rotation operation upon which they are no longer rotation keys but are now the current control authority keys.

How KERI maps to DID purposes is that the by default the current keys always have all authority. But other keys may be authorized in a revokable sense to have some subset of the authority not including rotation. Recovery of control authority from compromise in KERI is tied to Rotation and those keys are always hidden. So the recovery purpose if used to mean recovery from compromised keys has no usefulness in KERI. But other keys for other purposes besides rotation may be declared or disclosed in a DID doc with purposes (always revokable) that match the DID DOC purposes of authentication, operation and capabilityInvocation in a KERI compatible way.

IMHO the only way to a cleanly address this in decentralized key management is using the concept of root authority with self-certifying identifiers. This means there is a bifurcation of key roles.

  1. keys that are part of the sequence of keys in the chain of root authority. Root Authority Role.
  2. Keys that are revokable authorized by the root authority for other purposes. All Other Roles. Those other purposes are appropriate for DID:Docs and may the purposes may be delineated as purposes.

Once a key has been rotated away from a root authority role, it may be repurposed for other Roles (purposes). It is no longer authoritative for the root authority. The chain of control establishes unequivocally at any point in the chain what role the key serves.

Not having an absolute clear policy with regard to control authority exposes security vulnerabilities. It will cause head aches from a security perspective down the road.

@csuwildcat
Copy link
Contributor

@SmithSamuelM I'm still trying to tease out the bits of your reply that may be relevant to the questions here, but just wanted to note that this Issue doesn't affect the "absolutely clear control policy" for the Method used by Orie in the example description (Sidetree DIDs), in case that's something that it seemed to indicate. Nothing about a revocation public key being inside or outside of the rendered DID Doc has any effect on the deterministic control lineage for DIDs of the type used in the example.

@SmithSamuelM
Copy link

My confusion is what you mean by "recovery" keys. Is it recall or rotation?

@csuwildcat
Copy link
Contributor

Sam, it seems that you have a somewhat different recovery setup than the Method used in the example, but it does seem to share a common aspect in not exposing the recovery public key in the DID Document, correct?

@csuwildcat
Copy link
Contributor

My confusion is what you mean by "recovery" keys. Is it recall or rotation?

Recovery key in this sense = public key that is supposed to only be used exclusively used for recovering control of a DID in the case a lower authority key is compromised. The recovery key is basically something you should store securely, not use for anything else, and only use in a 'break glass in case of fire' circumstance.

@SmithSamuelM
Copy link

Yes we are on the same page in that case. (notwithstanding that using the term recovery for this this is a poor choice of terms). But frankly a break the glass rotation key is not a long term viable solution. It's just kicking the can down the road. Once you use it once to rotate (recover) it is now exposed and no longer secure. This means you need to create a new rotation key. But by what authority? Yet another higher level rotation key (infinite regress). My strong objection to these discussions is that they involve defining terminology and specification for key management operations that in IMHO are not best practices and should be discouraged not enabled by the specification. IMHO pre-rotation is a best practice key rotation scheme that is also amenable to decentralized identity. A one time rotation (recovery) key is not best practice. Break the glass as a last ditch effort is not a secure approach. Either the identifier is persistently recoverable which means that the rotation authority is one time use with a forward commitment to the next rotation key (unexposed) ie renewable rotation authority or its of limited utility meaning its not really persistent.

@SmithSamuelM
Copy link

I have been investigating key rotation practices for about three years now. I realized a long time ago that any decentralized key management scheme must start with solving the hardest problem first, not the easiest problem first. The hardest problem is recovery from compromise of keys. There are some esoteric ways using some fancy crypto to do this but the most straightforward practical way that uses off-the-shelf crypto is pre-rotation. Any recovery scheme that merely defines a "rotation" key that does not have the ability to "recover" the rotation keys is half-baked from a security perspective! The bigger question is not whether or not a "recovery" key should be disclosed in a DID DOC. That is not the problem. The problem is how are you managing recovery in a secure way? which means recovering the recovery key. If you have not answered that question then answering this question (did:doc exposure) is premature.

@csuwildcat
Copy link
Contributor

Sam, we are able to rotate in a new recovery key within the recovery invocation, but this is orthogonal to the issue at bar. (as previously suggested, I'd take a look at the Sidetree spec to read about details like this)

@csuwildcat
Copy link
Contributor

I have been investigating key rotation practices for about three years now. I realized a long time ago that any decentralized key management scheme must start with solving the hardest problem first, not the easiest problem first. The hardest problem is recovery from compromise of keys. There are some esoteric ways using some fancy crypto to do this but the most straightforward practical way that uses off-the-shelf crypto is pre-rotation. Any recovery scheme that merely defines a "rotation" key that does not have the ability to "recover" the rotation keys is half-baked from a security perspective! The bigger question is not whether or not a "recovery" key should be disclosed in a DID DOC. That is not the problem. The problem is how are you managing recovery in a secure way? which means recovering the recovery key. If you have not answered that question then answering this question (did:doc exposure) is premature.

Because this entirely separate, conceptual recovery discussion is happening here, I want to be clear for any potential readers: none of what is outlined above is an issue for Sidetree Methods, as they do all the things required to tick the Method-centric side of these security boxes.

Can we all please return to discussing the Issue topic?

@SmithSamuelM
Copy link

So if you are making a commitment to the next recovery key then you are doing a form of pre-rotation. So the question is how much do you care about disclosing the next recovery key. Merely disclosing the next recovery public key is not a pre-quantum security problem. I don't see it as much of a privacy problem any more than disclosing the identifier. If you're concern is post-quantum security (not privacy) then hash it the way KERI does. If your concern is privacy all you've done by disclosing it is allowing correlation to the eventual key recovery operation when it occurs which will be public anyway. So I see it as a non issue from a privacy perspective. But maybe an issue from security perspective.

@SmithSamuelM
Copy link

A sufficiently strong hash (blake2-256, blake3-256, sha3-256 or greater) are post-quantum secure. This is why KERI now hashes the pre-rotated keys instead of disclosing them. Disclosing the hashes is neither a security or privacy problem.

@csuwildcat
Copy link
Contributor

csuwildcat commented May 20, 2020

"But maybe an issue from security perspective." - yes, one of the security issues that worries me about sticking things in the DID Doc you specifically DON'T want outside entities to interact with are case like a wallet that has a bug in its code that allows someone to send a reference to this type of info in a DID Doc, and the wallet performs some action using that material on accident. This simply would not feasibly happen if those sorts of things were not in the DID Doc and able to be referenced in the scope of DID Doc-related activities. Leaving them out removes an huge surface area for even the possibility of attempts of this sort, which I personally see value in.

@SmithSamuelM
Copy link

So if the recovery purpose is to disclose the pre-rotated recovery key then it depends on how the proof of recovery is constructed.

Quoting @csuwildcat has THREE points

  1. I believe it is odd to leak out keys into the DID Document that do/may not serve any Method-external purpose (e.g. a key that is not to be used for anything but last-ditch recovery of a DID)

So contrary to the statement above. The ensuing discussion has clarified that its not a last ditch recovery but part of a renewable key pre-rotation like scheme. The only way such a scheme should be able to be invoked is with a signed statement using the recovery keys. The security of the operation is then dependent solely on the security of the private recovery keys and who controls them not the publicity of the recovery public keys. Leaking public keys in this case is not a security problem pre-quantum but may be a potential post-quantum security problem. It may be a minor privacy problem. Because @csuwildcat did not mention post-quantum security as a concern. Then it's not a security problem per se. Given the public keys and access to the private key store one may have less work in matching the two keys sets but thats just a weak form of security by obscurity.

  1. Following on from 1 above, I believe there are concrete security advantages to not adding 'internal'-only keys, like recovery, to the output DID Document, because it could lessen the chance that errantly written wallet code could screw up and allow some inbound DID Doc key referencing request to trigger use of the Method op-capable/recovery key for something other than those sensitive things.

I don't understand well enough how its possible at all of errant wallet code to screw up and create a recovery rotation given that some did doc contains the public recovery key. I suppose one could have the wallet use the did:doc as authoritative vis a vis the wallet trigging an recovery but any recovery operation should have some MFA or confirmations in place so that is not possible to errantly recover. But if the private keys are not protected very well then it must not be a very valuable identifier anyway. So the worst case is that you recover and pre-rotate to a new set of keys. What's the harm in that?
I can see it being a harm if you are not pre-rotating and the recovery key is a last ditch key as originally described but @csuwildcat has clarified, sidetree is using a pre-rotation scheme which handles that case harmlessly.

By Zero_Trust Compuing principles, any unencrypted document or data stored anywhere on a server is not secure. So if sidetree is storing the pre-rotated recovery keys unencrypted on some server that is accessible by the wallet but just not in a did:doc its not a true security advantage.

  1. If it turns out folks believe I am wrong about 1 & 2 and/or being too cautious in my security posture, then why aren't these 'verification' methods specified in DID Core? If the answer is that this is what the spec/community intended a DID Document to express, the spec is almost entirely silent about it. If the sort of thing that Orie is advocating for is right/required, what do folks think the spec should do about it? To be clear: I don't think this is what a DID Doc was intended for, but I want to make sure we think about the spec implications if folks disagree with me.

This I agree with. We should have clear semantics from a security perspective. The problem is that each DID Method is free to define its own security measures, policies, and procedures. This means that the DID spec itself can't have much of an opinion. This will lead to no good =). Unfortunately IMHO the only way out of this mess is to have one or at most a handful of standard best practices policies for "recovery" and require strict adherence to a given policy. I don't see this happening at least as part of the DID:doc standards process. It might happen as part of market forces choosing a winner or set of winners of DID methods.

@SmithSamuelM
Copy link

SmithSamuelM commented May 20, 2020

To elaborate. A true pre-rotation scheme requires that a rotation operation do several things.

  1. Create a new set of key-pairs that are to be the next recovery keys public and private. This requires permission and access to the key creation infra-structure. This is never in or on or controlled by a DID:Doc.

  2. Sign a recovery statement operation with the old recovery keys . The operation includes a commitment to the next recovery public keys. This signing operation either means retrieving the private keys from some key store or sending the statement to secure (enclave, TPM, etc) to sign.
    It is absolutely essential to security that the recovery statement include a cryptographic commitment to the next recovery key. The commitment may be the bare public key or some one-way cryptographic function on the public key. But the pre-commitment is essential.

  3. Promulgate the recovery statement.

Each of these steps typically requires confirmation or MFA by the user. They should never be triggered by anything in a DID:Doc. the DID:Doc is merely a record of the final step 3) which is after the fact. A proof of recovery includes a record of the recovery statement.

So in order for pre-rotation to work a rotation statement that is proof of recovery must be published somewhere. Its publication includes a cryptographic commitment to the next recovery key. this means that unless that commitment is in a hidden form, that the pre-rotated public key is published. Seems reasonable that a DID:Doc may be the place those publications occur. So I don't see a reason for not publishing a commitment to the next public key in a DID:Doc. I see a reason for hiding the actual public key (pos quantum security) not for hiding the commitment to the public key itself .

Even if it is a last ditch one-off recovery scheme there must be an irrevocable immutable cryptographic commitment somewhere to the recovery key otherwise it is not a secure form of recovery. If it is an immutable irrevocable commitment then by what authority is it authoritative and how is that established? If it is via registration on a Ledger then it is already public and republishing it in a DID:Doc does not pose any materially greater security risk. If it is not registered on a ledger then how is the cryptographic commitment verified. KERI uses immutable logs of rotation events. But these publicly disclose the cryptographic commitment (hash of the public keys) in order that they may be protected via duplicity (consistency) checks of the logs. This provides similar guarantees to registration on a ledger without being locked to a given ledger.

@ChristopherA
Copy link
Contributor

ChristopherA commented May 20, 2020 via email

@SmithSamuelM
Copy link

So a multi-sig transaction does not allow recovery of a compromise of a majority of the multi-sig keys. This is not recovery. This is just multi-sig making revokable authorizations. The multi-sig recovery is not recovery of root control authority after it has been compromised. It is just providing revokable authorizations. Multi-sig is great. Its very very difficult to exploit. The gnosis multi-sig ethereum wallet has never been compromised (at least by any public report) with billions under its control. So its a reasonable security measure. One may choose to use multi-sign as the root authority. But it is not recovery in the sense that we have been using it so far in this discussion.

@SmithSamuelM
Copy link

Recovery has defined in this discussion is recovery after compromise of keys. If its multi-sig then a full compromise would be a compromise of a majority of the keys. A partial compromise of a minority of the keys could be recovered from via a rotation that is not pre-rotated. The trade-off is that even though all the keys in the multi-sig have been exposed (ie used to sign something at least once) the fact that a majority must be compromised provides reasonable security despite the exposure.

@ChristopherA
Copy link
Contributor

ChristopherA commented May 20, 2020 via email

@SmithSamuelM
Copy link

@ChristopherA I think there are some cool interesting new crypto approaches for "recovery" or rotation. Sounds like you are building one. The KERI pre-rotation approach only requires plain vanilla digital signatures and hashes.

@peacekeeper
Copy link
Contributor

@OR13 and @csuwildcat , both approaches are valid from a DID spec perspective, i.e. your method may choose to have these keys in the DID document, or it may choose to not have them in the DID document. This is up to the method spec author to decide, based on some of the considerations that have been mentioned in this thread.

One of the reasons why the spec has this language:

For example, a DID method MAY not use the DID Document at all to determine the authority of a party to carry out the operations, but have rules that are "built into" the method.

.. is that some methods authorize operations in ways that are much more complex than just possession of a key or a capability. The example I always give is the did:erc725 method. This method is experimental and not really in use, but it allows you to authorize DID operations based on any conditions that can be expressed as an Ethereum smart contract e.g. using the Solidity language. It would be difficult and not useful to "map" such complex authorization logic into a DID document.

Other methods such as did:v1, did:peer use the DID document itself to authorize DID operations.

So again, both is fine.

@csuwildcat
Copy link
Contributor

csuwildcat commented May 20, 2020

Lots of interesting discussion happening here about different recovery concepts. As for the immediate Issue at bar, which is less about all of your recovery schemes in detail than it is a single set of DID Doc related questions, it's pretty clear to me everyone who responded has answered, but within longer discussions that cover far more than just the Issue. To help hone in on conclusions, please (hopefully) respond with Yes/No answers to the following list of questions that I believe are a condensed replay of your responses, as they pertain specifically to the Issue:

  1. No one here is specifically outputting 'internal'-only keys to a DID Doc out of a belief that all keys the user uses to facilitate updates/recovery must be in the document as some sort of mandatory "Look at these keys I use to do things internal to my DID ops".
  2. Most (all?) of you intentionally don't expose public keys of this sort in-Doc, albeit for a variety of reasons.
  3. No one thinks this type of in-Doc key exposure was specifically intended or recommended by the current spec, and there doesn't appear to be a desire to go this direction. (I even gather that some of you feel it's an anti-pattern for a variety of reasons)

@OR13
Copy link
Contributor Author

OR13 commented May 20, 2020

@csuwildcat ^ this is not an accurate summary of the comments so far....

The only DID Method known to not expose authoritative keys, is did:erc:725... all the rest appear to use authentication for what we call operation keys.

The group is also suggesting that recovery is unnecessary... which I agree with, given that it is technically just a complex case of the DID Update Operation... and is not specified in DID Core....

Based on this feedback, I believe that we should drive consensus around the use of authentication for authoritative keys, we don't need to define another method specific proof purpose for operations... most methods are using authentication for this already... if we recommend doing something different, we will be undermining the convention, and increasing complexity for interoperability.

did:v1 and did:peer do exactly what I have suggested... it's worth noting that when Microsoft introduced the "internal data model" and stopped taking this approach, you also stopped reviewing proof purposes, and how they map to the standards work.

I worry that if we create a spec which specifically endorses the least common approach (recommend against the inclusion of authoritative keys in a did document), we will be weakening DID Core, interoperability, and undermining the approach taken by methods that do believe that authoritative keys SHOULD be present in the DID Document.

I am not seeing an impressive list of highly secure DID Methods that take the approach you are advocating for... in fact, I'm seeing the exact opposite...

@OR13 OR13 closed this as completed May 20, 2020
@OR13 OR13 reopened this May 20, 2020
@OR13
Copy link
Contributor Author

OR13 commented May 20, 2020

Also worth noting that the full bytes of the recovery and operation keys are leaked via the create operation... so its not like they are private in any sense... secure key actually returns these keys in resolver meta data today.

If they were not leaked via the create operation, I would be in favor of not putting them in the did document... because they are leaked, I feel like its a bad idea to pretend like the world does not have them.

@troyronda
Copy link
Contributor

troyronda commented May 20, 2020

Based on this feedback, I believe that we should drive consensus around the use of authentication for authoritative keys, we don't need to define another method specific proof purpose for operations

I believe there is a benefit in having an additional category of key for DID method updates. To me, update and authentication are in different categories and I think should be treated differently. For example, I might rarely update my DID document but frequently authenticate. I may want to have a different protection scheme for my DID method update/operation key vs my authentication key.

@csuwildcat
Copy link
Contributor

csuwildcat commented May 20, 2020

Also worth noting that the full bytes of the recovery and operation keys are leaked via the create operation... so its not like they are private in any sense... secure key actually returns these keys in resolver meta data today.

If they were not leaked via the create operation, I would be in favor of not putting them in the did document... because they are leaked, I feel like its a bad idea to pretend like the world does not have them.

It's not about the fact that they are currently locatable if you spelunk into the DID Method internal op data, it's about the fact that you're exposing keys to possible invocation references via common, everyday DID references and queries that wallets will support, and if a wallet's code has a bug that allows selection and use of a key in a doc through some business logic bypass, its just another vector. This is like the alg: "none" of DID Document things, imo. Would it be common vulnerability? Probably not. Should you knowingly choose to add yet another possible vector for no concrete benefit that can be done in other ways? No, I don't personally think so. I think being a tight-ass security overreactive person is just fine, and I would like to remain one, or at least have the option to in a DID Method.

@OR13
Copy link
Contributor Author

OR13 commented May 20, 2020

@msporny @dhh1128 @dhuseby @SmithSamuelM I would like sidetree spec to align as closely as possible with did:peer, did:v1 and KERI on this issue of how authoritative keys are expressed.

Since KERI is not a DID Method, I don't think it has specific advice regarding the DID Document data model.

In did:peer terms, the question is "should keys that sign DID Document deltas be in the did document?"

In KERI terms, the question is "should authoritative keys for the DID be public?" (regardless of the representation as a DID Document or something else entirely).

@csuwildcat
Copy link
Contributor

Based on this feedback, I believe that we should drive consensus around the use of authentication for authoritative keys, we don't need to define another method specific proof purpose for operations

I may want to have a different protection scheme for my DID method update/operation key vs my authentication key.

Any such protection scheme would rely on a wallet having specific awareness of the operational key sections and having flawless code that does not allow for execution against those sections based on any number of possible DID request handler activations, doc queries, etc. If the wallet is not properly informed, and its code has a path that allows a query on the doc to exec against those keys, it would result in compromise. I would like the ability to basically avoid that vector entirely by not having such things exposed at the level of the standardized query surface, and I don't think we should force people to expose things on the query surface that they don't want to.

@dlongley
Copy link
Contributor

dlongley commented May 20, 2020

Whether or not it makes sense to expose particular verification methods in a DID Document is an application/systems/privacy design question; there is no rule that says you MUST always expose verification methods associated with a particular DID in a DID Document. If you don't expose verification methods in a DID Document, it just means that standard tools won't know where to find them when trying to verify a proof -- you'll have to provide them to the tools in some custom way.

But, if a verification method is to be used to verify a proof that is attached to some kind of a capability invocation (i.e., you're trying to make a system do something -- you're signing a statement that says "take this action"), and you want to expose this VM in your DID Document, then I recommend expressing that verification method under capabilityInvocation so its authorization for that purpose is clear. Note: The DID v1 method uses VMs expressed in this way to verify capability invocations to perform DID register/update operations on the Veres One ledger as mentioned/alluded to by others in this issue.

@dlongley
Copy link
Contributor

There are some additional comments on this subject in issue #268.

@dlongley
Copy link
Contributor

dlongley commented May 20, 2020

I should add: if some VMs aren't expressed in a DID Document, there should at least be some kind of provable path back to an authoritative key in the DID Document, otherwise, the chain of authority is broken. (I'm assuming no one here is suggesting otherwise).

@csuwildcat
Copy link
Contributor

I should add: if some VMs aren't expressed in a DID Document, there should at least be some kind of provable path back to an authoritative key in the DID Document, otherwise, the chain of authority is broken. (I'm assuming no one here is suggesting otherwise).

Yes, there's absolutely a deterministic, cryptographic chain of authority, and that's true regardless of whether one exposes an inter-method piece of logic/material into the DID Doc. Personally, as a user, I would just rather not have anything included in my open query substrate (the DID Doc) that I specifically do not want others to try to invoke or operate against.

@OR13
Copy link
Contributor Author

OR13 commented May 20, 2020

As a DID Subject and a DID Controller, I would prefer not to need to check resolver meta data for authoritative keys... I feel that did:peer, now more closely resembles what I have always wished for sidetree to be... If did:peer supported an optional public / ledger agnostic anchoring approach that was consistent with KERI, thats pretty much what I want....

  • self certifying inception event => did => did document.
  • authenticated CRDT based on did document.
  • CRDT deltas optionally anchored in linear order publicly.
  • delta verification as a function of the DID Document NOT Microsoft's JOSE based Internal Data Model...

Don't get me wrong, I'm a strong supporter of JOSE... I just prefer to support it using public standard based data models, in way that works for everyone, and not just Sidetree DIDs.

Although I suppose I have the same grievance with did:peer in its current form... authorization and operations are DID Method specific proof purposes, which seem to solve the question of how do I know which keys can be used for DID Operations problem for themselves, and not anyone else....

Perhaps in a world where we could all agree that DID Operations are capability invocations by the did controller, capabilityInvocation would work for all of us.... it is not limited to ZCAP-LD... you can use it for any capability invocation... the fact that it was never documented properly is truly sad.... its hard to align to terms that have no definition.

@peacekeeper
Copy link
Contributor

I would be opposed to requiring the exposure of authoriative keys in a DID document, but it seems to make sense to agree on conventions for those DID methods that do want to expose the keys needed for DID operations.

@SmithSamuelM
Copy link

I agree with @peacekeeper it should be an option but an interoperable one.

@kdenhartog
Copy link
Member

kdenhartog commented May 25, 2020

I would be opposed to requiring the exposure of authoriative keys in a DID document, but it seems to make sense to agree on conventions for those DID methods that do want to expose the keys needed for DID operations.

+1 this most closely aligns with where I fall on the subject.

To answer the specific question for having an interoperable solution at hand, I lean towards exposing it because it seems useful for light weight transaction verification for trust-less resolution. In other words, with the key exposed in the did document, I can verify the transactions I received during resolution are correct because I can validate the signatures of the create/update/delete transactions.

@SmithSamuelM
Copy link

The way KERI views this is that if a DID is meant to be private then its never exposed in a public ally resolvable DID:Doc. The parties to the DID may prove control via private exchange of KERI events log did:docs etc. But for KERI whose root—of-trust is a self-certifying identifier, exposure of the current authoritative keys is not a pre-quantum security vulnerability merely a privacy issue. To elaborate, inversion of a public key via brute force is secure pre-quantum. The next public key in a KERI pre-rotation is protected hidden with a post quantum secure hash. So its not an unrecoverable security issue for KERI either pre or post quantum. There seems to be some confusion about security in this thread. Brute force inversion of ECC Ed25519 or ECDSA Secp256k1 public keys are not considered pre-quantum vulnerabilities. It may only be a privacy problem. If a DID is meant to be public then proof of control authority must also be meant to be public. Hiding the current authoritative keys in this case serves no privacy purpose and as already mentioned is not a security Vulnerability (pre-quantum). However for DID methods that are not end verifiable rooted in self-certifying identifiers like KERI there may be security vulnerabilities exposed in a DID:DOC proof purpose with keys. In this case allowing optional proof purpose might be beneficial. But this requires detailed security review of the associated DID methods.

@OR13
Copy link
Contributor Author

OR13 commented May 26, 2020

So assuming that a DID Method author wanted to expose authoritative keys for DID Operations in the DID Document, there options are:

  1. create a new proof purpose for the did method eg: operations, recovery
  2. use authentication
  3. use capabilityInvocation

separation of concerns, limiting key reuse, explicit over implicit, and a number of other developer feelings leads me to personally recommend option 1.

but I think the conclusion of this is that sidetree will not make further normative restrictions on how a did method expresses keys used for did operations, because did core doesn't.

Does anyone have a concrete proposal for improvement based on the discussion thus far?

If not, I feel like we may want to close this issue and non-actionable, at some point in the future.

@dlongley
Copy link
Contributor

It is possible that PR #312 will resolve this issue by providing more definition around capabilityInvocation and capabilityDelegation for expressing verification methods that are authorized for verifying proofs on capabilities -- where a capability represents the authority to take some action or perform some operation as/for the DID subject/on behalf of them.

@OR13 OR13 closed this as completed Jul 14, 2020
@msporny
Copy link
Member

msporny commented Jul 14, 2020

@OR13 agreed that this issue has been resolved on a DID WG call.

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

No branches or pull requests

10 participants