w3c / did-core

W3C Decentralized Identifier Specification v1.0
https://www.w3.org/TR/did-core/
Other
400 stars 94 forks source link

need to clarify revocation vs. rotation #386

Closed dhh1128 closed 3 years ago

dhh1128 commented 3 years ago

Creating a new issue to track a tangent to #382.

There appears to be a misalignment in the community about the semantics of changing a key associated with assertionMethod in a DID doc. The relevant comments from #382:

https://github.com/w3c/did-core/issues/382#issuecomment-685248497 https://github.com/w3c/did-core/issues/382#issuecomment-685629401

Tagging @jandrieu and @SmithSamuelM who have already commented on the topic.

dlongley commented 3 years ago

I'm going to go ahead and make an assertion with more specific details on rotation/revocation to see if we can figure out what's missing here:

I don't think anything needs to be done if the following rotation/revocation rules are acceptable:

To rotate a key:

  1. Generate a new keypair.
  2. Add the new public key to your DID Document.
  3. Change software that uses the old private key to use the new private key.
  4. Internally, mark the old private key as inactive and archive or destroy it if appropriate for your needs.

Now, all proofs generated by the old key will continue to verify properly and the new key will be used by your software going forward so any new signatures will also verify. There's nothing more to do here. These are the appropriate steps to take if you want to limit blast damage and you have no reason to believe the old key has been compromised. If you have any reason to suspect the old key has been compromised, you must proceed with key revocation.

To revoke a key:

  1. First, ensure that there is a replacement key (follow the key rotation steps).
  2. Remove the public key (associated with the potentially compromised private key) from your DID Document.

Now, all proofs generated by the old key will no longer verify unless special steps are taken. Proofs using the old key can't be trusted because it was (potentially) compromised. There may be certain risk profiles or mechanisms involving proof of existence that some verifiers could employ to continue to accept VCs signed in the past by the old key (as an example). This may involve using the version DID parameter.

Both of these use cases are supported today. What are the specific requirements that are missing that people are interested in adding new features for?

SmithSamuelM commented 3 years ago

@jandrieu

Maybe there is some new option, perhaps thanks to KERI or some other insight I haven't figured out yet. I'm familiar with the pre-rotation concept @SmithSamuelM has championed, but I'm not seeing how that helps here.

Prerotation does not help here directly, but the key event log does. Instead of a time stamp, the KERI key event log is a hash chained data structure where any issuance or revocation actions may be anchored to a given event in that log via a digest. This makes the log a "chain" clock where the relative times of any actions are determined by the location of their anchors in the log. Updates to a did:doc could be also anchored and hence verifiably chain-clock time stamped via a reference to the anchoring event in the log.

SmithSamuelM commented 3 years ago

Given a chain clock time stamp in a VDR like a KERI key event log. One can then embed in a VC or a DID;doc the authorization rule as a modifier to any authorization action. The rule then tells a verifier how revocation happens. As long as everything is verifiable back to the root control authority, then we have a verifiable chain-of-authorization. So root control authority authorizes an update to a did:doc that revokes a key. The original authorization of that key in an earlier version of a did:doc included a commitment to the authorization/revocation rule. The later revocation is then unambiguously verifiable.

SmithSamuelM commented 3 years ago

Without a VDR such as a ledger or a key event log, authorizations become messy and you end up reverting to dynamic authorization verification as per the authorization token world (OIDC) using an effectively bipartite issuer-verifier model. This breaks the privacy preserving properties of a tripartite issuer-holder-verifier model. Effectively bipartite because the verifier must contact the issuer to verify revocation of any presentation by a holder. But with an ordered VDR a verifier need only access the VDR to unambiguously establish the authorization revocation state. The CRUD model of a did:doc alone is inadequate to this task. The updates must be backed against a linearly ordered VDR that anchors those updates.

dhh1128 commented 3 years ago

I want to respond directly to @dlongley , because he's asking a really important question. The essence of my difference in perspective can be summed up by the tense you used on the "have" verb here:

no reason to believe the old key has been compromised. If you have any reason to suspect the old key has been compromised, you must proceed with key revocation.

You're using past perfect tense here; in other words, decisions are made based upon what is believed to have happened in the past. The guidance you suggest would escalate to revocation as soon as compromise is believed to be a past event; before that, you only need rotation. And rotation is not a public event; you're the only one that knows you've done it.

I have been thinking of rotation as taking the future into account as well -- that once you rotate a key, you can forget about it entirely; future compromise is harmless, because everyone who cares about the key can know the key's become inactive. But under the guidance you're advocating, rotating a key does nothing to diminish your responsibility to safeguard it. The only party that knows you're no longer using it is you, and you have no way to prove the rotation publicly. In that worldview, only revocation is public, and it is retroactive.

I don't believe there's any such thing as retroactive revocation. I'm going to explain why in terms of VCs, even though we're talking about DID keys here -- because we believe DID keys will be used to issue stuff.

When you revoke a credential at point-in-time X, the credential retains its validity/verifiability at point-in-time X-N. That's the way driver's licenses work. You can't issue a driver's license in January, revoke it in May, and have an insurance company stop payment on the accident that happened on April 30 on the basis of that the revocation undid the driver's legal right to drive in April. It didn't. The driver had a legal right to drive in April; that's undeniable reality. If I verify the credential against an April timeframe, it BETTER give me a thumbs up, or the entire VC ecosystem is useless. The right ceased in May; it didn't undo the issuance entirely. Revoking a credential says that you no longer stand behind what you used to assert -- not that you never stood behind the assertion.

Likewise with keys. Revoking a key doesn't solve the problem of key compromise retroactively. Whatever happened with that key, happened. Period. You can go to court and explain that your key was compromised during that timeframe, and therefore you're not on the hook for what happened. This may be convincing, and lead to the outcome you need. But if so, it's not convincing on the basis of revocation; it's convincing because you are DECRYING the transaction. Decry != revoke. Decrying IS retroactive. Revocation only works from the point of revocation forward.

So this is a profound difference in worldview. We can argue about which worldview is right. Perhaps I'm

dlongley commented 3 years ago

When you revoke a credential at point-in-time X, the credential retains its validity/verifiability at point-in-time X-N. That's the way driver's licenses work. You can't issue a driver's license in January, revoke it in May, and have an insurance company stop payment on the accident that happened on April 30 on the basis of that the revocation undid the driver's legal right to drive in April. It didn't. The driver had a legal right to drive in April; that's undeniable reality. If I verify the credential against an April timeframe, it BETTER give me a thumbs up, or the entire VC ecosystem is useless. The right ceased in May; it didn't undo the issuance entirely. Revoking a credential says that you no longer stand behind what you used to assert -- not that you never stood behind the assertion.

Likewise with keys. Revoking a key doesn't solve the problem of key compromise retroactively. Whatever happened with that key, happened. Period. You can go to court and explain that your key was compromised during that timeframe, and therefore you're not on the hook for what happened. This may be convincing, and lead to the outcome you need. But if so, it's not convincing on the basis of revocation; it's convincing because you are DECRYING the transaction. Decry != revoke. Decrying IS retroactive. Revocation only works from the point of revocation forward.

You need proof of existence to make any of this work. I mentioned above that that is an option, but we need to acknowledge it as a requirement for the cases you mention. This is independent from proofs generated with the keys. If a key is compromised, the attacker can put whatever (past) timestamp they want to on a VC.

So this is a profound difference in worldview.

I don't think we have a difference in worldview -- I'm just asserting that the technical solution to the use cases you outline requires something independent from the keys.

SmithSamuelM commented 3 years ago

@dlongley What your argument feels like, is a hammer looking for a nail. The hammer is the OIDC and associated tooling like JWT. I call it the security token world model where authorizations are ephemeral and tightly bound to keys. When a key is rotated so are the authorizations. This model is very efficient and is well suited to a token based authorization system and the associated tooling. But this model is ill suited to many real world use cases of credentials as persistent authorizations until explicitly revoked. We need better models and therefore new tooling to support these real world use cases. Can't put new wine into old bottles.

If a key is compromised, the attacker can put whatever (past) timestamp they want to on a VC.

See my comment above about the need for a linearly ordered VDR (LOVDR) like a key event log or ledger. While an attacker may be able to use a compromised key to forge a timestamp, they can't use it to undetectably forge a new LOVDR or to insert a new anchor to the forged VC at an already past event in the LOVDR. This is what I mean by a new model. The OIDC token model is efficient because it does not require a LOVDR. But persistent models only work with an LOVDR . And your example is a cogent reason. In KERI I call this a "dead" exploit versus a "live" exploit. Attempts to use anything less than an LOVDR are fraught with security problems.

A key event log KEL in KERI is an LOVDR. A digest of a VC issuance is anchored to an event in the log and the VC includes a reference to the anchoring event. Thusly the "time" of the issuance is verifiable at its anchoring location. A successful attack for issuing a fake VC at a different time is not verifiable unless the attacker replaces the LOVDR and this is really really hard to do. And even should an attacker succeed such an attack is eminently detectable as the LOVDR is non-repudiable. Any alternate versions will be detectably inconsistent. An ephemeral issuance model forces a trade-off between privacy and security. A persistent issuance model allows both privacy and security but the trade-off is the need for an LOVDR.

dhh1128 commented 3 years ago

I said:

So this is a profound difference in worldview.

Dave replied:

I don't think we have a difference in worldview -- I'm just asserting that the technical solution to the use cases you outline requires something independent from the keys.

Right. It requires a VDR that supports a time-based view, as @SmithSamuelM clarified. But that's not the difference I was talking about. The difference in worldview is tied to two things where we appear to strongly disagree:

  1. What "revocation" actually means.
  2. Whether my view is a new feature.

My previous post got truncated, but I want to formally disagree with these sentences from @dlongley :

Both of these use cases are supported today. What are the specific requirements that are missing that people are interested in adding new features for?

My disagreement is with the implication that we're talking about a new feature. This is absolutely not the case. We've had verbiage in the spec about version-timestamp and version-id for a very long time. They are there to support a VDR offering time-based views. I'm fine debating the right way forward, but not starting from the assumption that I'm advocating something new, and not starting from the assumption that everything in scope is already supported by the rules @dlongley proposed. Those rules subtract something that's already present.

As I said, I'll raise a PR today so the debate can be more concrete.

dlongley commented 3 years ago

@SmithSamuelM,

See my comment above about the need for a linearly ordered VDR (LOVDR) like a key event log or ledger. While an attacker may be able to use a compromised key to forge a timestamp, they can't use it to undetectably forge a new LOVDR or to insert a new anchor to the forged VC at an already past event in the LOVDR. This is what I mean by a new model. The OIDC token model is efficient because it does not require a LOVDR. But persistent models only work with an LOVDR . And your example is a cogent reason. In KERI I call this a "dead" exploit versus a "live" exploit. Attempts to use anything less than an LOVDR are fraught with security problems.

A key event log KEL in KERI is an LOVDR. A digest of a VC issuance is anchored to an event in the log and the VC includes a reference to the anchoring event. Thusly the "time" of the issuance is verifiable at its anchoring location. A successful attack for issuing a fake VC at a different time is not verifiable unless the attacker replaces the LOVDR and this is really really hard to do. And even should an attacker succeed such an attack is eminently detectable as the LOVDR is non-repudiable. Any alternate versions will be detectably inconsistent. An ephemeral issuance model forces a trade-off between privacy and security. A persistent issuance model allows both privacy and security but the trade-off is the need for an LOVDR.

Yes, you're describing mechanisms to do the "proof of existence" I mentioned. I don't think we're in disagreement here -- at least I can't tell that we are if we are.

dlongley commented 3 years ago

@dhh1128,

My disagreement is with the implication that we're talking about a new feature. This is absolutely not the case. We've had verbiage in the spec about version-timestamp and version-id for a very long time. They are there to support a VDR offering time-based views. I'm fine debating the right way forward, but not starting from the assumption that I'm advocating something new, and not starting from the assumption that everything in scope is already supported by the rules @dlongley proposed. Those rules subtract something that's already present.

I'm confused -- because I asserted we already have what we need and you're talking about a feature we already have (version*) which is the same one I also mentioned being useful here. This is why I asked the question: if these features are insufficient, what else do we need? I look forward to the PR.

dhh1128 commented 3 years ago

@dlongley : what we have is an inconsistently and inadequately described feature that doesn't make logical sense; if we adopt the rules you've proposed, I feel like the version-* stuff becomes useless and VCs can never be verified against a historical date. We can't hold anybody accountable for past statements, since they can undo them any time they want.

@jandrieu : I realized upon more careful reading and pondering that your recommended rules and Dave's amount to the same thing. So I'm retracting my offer to submit a PR that embodies your rules. I don't believe in them. Perhaps I'll reattempt next week, when my brain is clear of weekend distractions.

I spent all afternoon reading NIST PKI and KMS docs and some RFCs like 6960 (OCSP), plus lots of derivative sources that seem to map back to these, to see what I could glean from them as authoritative treatments of the topic. It's surprisingly muddy. The wisdom seems to be that each system can define the semantics for itself, per policy of its operators, within certain parameters that don't narrow the semantics enough to help us. So far, the most useful discussions of revocation (of certs and of keys, respectively) seem to be in NIST SP 800.32, on page 16 (section 3.1, see Certificate Revocation Lists) and NIST SP 800.57, rev 5, on page 49 (section 5.5.1).

SmithSamuelM commented 3 years ago

@dlongley I have to admit that I don’t understand your use of the term proof of existence in the context of this discussion. Proof of existence of what?

dhh1128 commented 3 years ago

I woke up this morning with a brainstorm.

I think the thing that would resolve this for me is to create a new verification method. We have overloaded authentication to mean any operation that proves the controller's involvement. I feel constrained to use authentication for signing VCs, but the VCs I want to create have very different semantics from the ones that Dave, Manu, and Joe appear to like (the issue of what semantics obtain when you pull the keys out of the DID doc).

My proposal is to create a new verification purpose -- call it permanentSign for the sake of argument -- that differs from authentication in its semantics in that this purpose is to make a permanent commitment that doesn't vanish when a key is removed from a DID doc, because it will be evaluated against state at the time the signature happened (the semantics @SmithSamuelM called style 1 above), whereas the authentication purpose is to make an ephemeral commitment now that is undone when keys disappear from a DID doc because it can only be evaluated "now" (the semantics of OIDC tokens, advocated by Dave, and called style 2 by Sam above). What do you think?

dlongley commented 3 years ago

@dhh1128,

I think the thing that would resolve this for me is to create a new verification method. We have overloaded authentication to mean any operation that proves the controller's involvement. I feel constrained to use authentication for signing VCs, but the VCs I want to create have very different semantics from the ones that Dave, Manu, and Joe appear to like (the issue of what semantics obtain when you pull the keys out of the DID doc).

My proposal is to create a new verification purpose -- call it permanentSign for the sake of argument -- that differs from authentication in its semantics in that this purpose is to make a permanent commitment that doesn't vanish when a key is removed from a DID doc, because it will be evaluated against state at the time the signature happened (the semantics @SmithSamuelM called style 1 above), whereas the authentication purpose is to make an ephemeral commitment now that is undone when keys disappear from a DID doc because it can only be evaluated "now" (the semantics of OIDC tokens, advocated by Dave, and called style 2 by Sam above). What do you think?

I don't know if this is just nitpicking at your idea or more than that, but it's important to clarify here just in case. authentication is not a verification method, it is a verification relationship. Furthermore, the verification relationship used for signing VCs should be assertionMethod as this is what is expected to show up in a proof as its purpose. You use a VC and attach a proof to it for the purpose of making an assertion, not to authenticate. So, regardless of which verification method you use, the expected verification relationship for a VC is assertionMethod. Again, this might just be nitpicking here because your idea of using a different verification method (the value associated with the assertionMethod relationship) is potentially a way for place for you to explore doing at least some of what you want to do. I don't think it makes sense to change the verification relationship though.

So, you could create a new type of verification method that allowed for users to express more information, for example, around the period of validity for that verification method. Verifiers that accept that method would be expected to consume that information appropriately. I don't think this fully solves your problem, however, as I mentioned that your VCs will also need some kind of proof of existence attached to them. This would be something that proves that the VC (including its signature), existed at some point in time that coincides with the associated verification method's validity period (which similarly must be proven to exist at that time). Otherwise, once a key is compromised, an attacker can fake whatever timestamp they want to on the VC. Additionally, since anyone can edit their DID Document and add/remove verification methods at will -- a robust protocol will need to account for this with additional information in the VC itself that links back to something the DID controller cannot change (e.g., immutable history in a VDR).

In short, this just falls back to what I was alluding to before. I think we have the features at the DID layer that enable people to create solutions (where such solutions are logically possible) here. It's just that someone needs to do the work to put together something at the VC/proof/verification method layer that others would find interest in implementing to get to interop. But these things all build on top of the work we've done with the DID spec already; I don't think there's anything that needs to be done in DID core at this point.

dlongley commented 3 years ago

@SmithSamuelM,

Proof of existence of what?

That a VC with a signature from a certain key existed at a certain point in time. A VC that has been signed with a key that is no longer considered valid should not be accepted simply because it carries a timestamp that is within the accepted validity period for the key. The timestamp is set by the party that signed -- and the key could have been compromised. Therefore, the VC must carry some kind of proof of existence (of it being signed in the past at an acceptable time), the strength of which must not depend on the key in question.

dhh1128 commented 3 years ago

@dlongley : Thank you for correcting my terminology. You've had to do that at least once before, and you may have to again. I find it incredibly confusing that there's a "relationship" named "assertionMethod" that is NOT a method.

I think I want a different verification relationship, then, not just a different method. I believe you are claiming that assertionMethod is only useful for making assertions in the present, and can be undone a split second later by removing the key with which it was made. I want something that creates a relationship between the DID controller and the public that is not ephemeral but rather persistent with respect to time. It would be used to make assertions, but with different semantics than you have advocated.

dlongley commented 3 years ago

@dhh1128,

I think I want a different verification relationship, then, not just a different method. I believe you are claiming that assertionMethod is only useful for making assertions in the present, and can be undone a split second later by removing the key with which it was made.

No, I am not making that claim. None of those restrictions are implied by the relationship at all and a new relationship is not necessary. The relationship is for expressing verification methods intended to verify proofs created as methods of assertion and a proofs created as methods of authentication (or as methods for invoking capabilities, etc.). These are all general intents and make no other statements around what is signed or other characteristics of the proofs themselves. They help ensure, for example, that a message that is signed with an intent for it to be shared and used by another party (a VC) is not confused with a message that is not signed with an intent to be shared with another party as they could (ab)use it to authenticate as you or take an action as you. This is just one layer of the security onion. So, a VC that has significant permanence is still intended to be understood as an assertion of claims about something -- and assertionMethod is the appropriate verification relationship for expressing verification methods that the DID controller approves of for that purpose.

Furthermore, I am not claiming that VCs should generally work in the way you're suggesting here (with a lifetime of a split second). I'm saying that if we want people to be able to verify VCs when the public key material is no longer present in a DID Document or when it may have been compromised long after the VC was signed, then we'll need to prove some additional things. I'm concerned that it seems that you want this type of VC without putting any real technical force behind it -- and that what you want cuts against other realities. I don't want to merely say, "I promise not to revoke the keys I put in this bucket in a bad way". That has no force. Rather, I want us to confront the constraints we already have and build a trustworthy system.

These are realities:

  1. People can edit their DID Documents at will (public key material can disappear from the current DID Document).
  2. VC timestamps that are asserted by the signer have trust that is only rooted in control of the signing key.
  3. Anything expressed in a DID Document (including perhaps a validity period for a verification method) only has trust that comes from the DID controller according to the DID method.

We have a situation where we can't trust the DID controller and we can't trust the key used to sign the VC. Note that this means there's nothing we can add to the current DID Document to resolve the problem. We need additional proof(s) in the VC and/or help from the DID method (e.g., its VDR).

The above must be accounted for in whatever proof scheme you design to create the kinds of long term VCs desired. Note: I also think these kinds of VCs are useful. I have suggested that to enable these VCs, we'll need additional proofs (proof of existence) and the structural components (e.g., immutable history) to back them. That's what needs to be discussed and explored. I don't think DID core needs to be changed, however, as these requirements are external to it.

agropper commented 3 years ago

@dlongley

The above must be accounted for in whatever proof scheme you design to create the kinds of long term VCs desired. Note: I also think these kinds of VCs are useful. I have suggested that to enable these VCs, we'll need additional proofs (proof of existence) and the structural components (e.g., immutable history) to back them. That's what needs to be discussed and explored. I don't think DID core needs to be changed, however, as these requirements are external to it.

In our HIE of One healthcare use-case implementation, we supplement the doctor's SSI authentication, credential, and digital signature (their wallet) with a timestamp on a public blockchain. This adds huge complexity. The timestamp cost has to be charged to someone, the proof has to be stored somewhere, and merkelization is required to keep the cost in line. Like @dlongley, I don't think DID core needs to be changed but I'm hoping that KERI will simplify this somewhat.

msporny commented 3 years ago

We are getting ready to enter the Candidate Recommendation stage, which means the WG needs to decide whether to close this issue or if there is enough here to write something concrete in the specification. Note that feature freeze happened on July 15th 2020, so no new features can be proposed at this time.

We will need a concrete proposal with a concrete PR from this discussion thread or this issue will be closed before we go to CR.

OR13 commented 3 years ago

Not all DID Methods need to describe their internals the way that KERI does, and KERI event log can be projected into a DID Document in more than one way.

IMO this issue is about key identifiers.

The following will remain true:

  1. public key bytes can change and the identifier can remain the same.
  2. identifier can change but public key bytes can remain the same.
  3. purpose / relationship can change and identifier / public key bytes can remain the same.

IMO further restrictions on these are the realm of DID Methods (such as did:un / did:ion, etc...), not did core.

Its not clear what the action should be on this issue, but perhapse some plain english around the list above next to verification method section would help?

dhh1128 commented 3 years ago

@msporny What is my deadline for raising a PR?

msporny commented 3 years ago

@msporny What is my deadline for raising a PR?

I expect that the PR needs to be in by the end of this month. I can't give you a firm date as the WG hasn't decided when it's entering CR... just that it's "really urgent that we do so as soon as possible". We expect to have the remaining major issues resolved this week, and with a few weeks of time for the Editors to get the spec into shape... I expect we'll start the process of closing/deferring this week with the process increasing in intensity through the end of the month.

The sooner the better... PRs raised this week have a better chance to be refined by the end of the month than a PR submitted towards the end of the month.

TallTed commented 3 years ago

@dhh1128 -- you said in https://github.com/w3c/did-core/issues/386#issuecomment-685756249 (Yes, that was a while ago.)

allowing the issuer to back out is like letting a lender off the hook for a mortgage without any loan repayment

I think you meant "letting a borrower off the hook". Rather different meaning.

I think it's worth correcting that comment, because whether a PR goes in for this Issue now/soon or this Issue gets tabled until the next spec that branches from DID-Core (or until one or more separate DID Method specs, as I'm currently thinking most likely), others will be re-reading this thread to understand and/or write the PR(s) that address(es) it.

dhh1128 commented 3 years ago

@TallTed : Thank you for the catch. You're correct that my fingers moved faster than my brain when I typed that comment. :-) I've now fixed it.

OR13 commented 3 years ago

I will try to address this with non normative language that accounts for https://github.com/w3c/did-core/issues/337

OR13 commented 3 years ago

I took a stab at this in https://github.com/w3c/did-core/pull/548

I took a pretty strong stance on the "revocation is forever" side of this debate....

While solutions that require a blockchain / special kinds of VDR might exist might allow for relative confidence that a revoked key was used by the controller and not the attacker, I find no evidence that this is sufficiently described in did core to be even hinted at in the spec...

As as such I have separated the stew we had before into 3 categories:

  1. rotation - a proactive security measure applying only to verification methods
  1. revocation - a reactive security measure applying only to verification methods
  1. recovery - a reactive security measure applying to DIDs

I am aware of some community perspectives that a certificate from a "revoked key" should still be valid / trusted "assuming non standard hand waving and version-id".... I wish I could point to some normative definition for why a verifier can trust a revoked verification method based on "version time", but I can't so I have said:

All verifications from revoked verification methods must be considered invalid, regardless of "when" revocation occurred" / how it is represented.

I think this may close the door on some folks who were planning to get creative with version-id... specifically @dhh1128 @brentzundel @oed please review this PR, and make sure I am capturing how you think rotation, revocation and recovery should work.

SmithSamuelM commented 3 years ago

Instead of copying and pasting and reformatting. Section 4 of the following white paper provides my view on this issue.

https://github.com/SmithSamuelM/Papers/blob/master/whitepapers/IdentifierTheory_web.pdf

SmithSamuelM commented 3 years ago

My approach is to separate key management (rotation =revoke and replace keys = recovery) from statement management (issue and revoke). IMHO we want to have standards that allow loose coupling between the two. Its ok for an application to use a tightly coupled model (as the white paper above indicates when it looks at the 4 models) but not for the standard to force tight coupling. Thus the only way to allow loose coupling is to to separate key management from statement management at the standards level.

SmithSamuelM commented 3 years ago

Related to this issue is authorization models. Keys are used to authoritatively authorize statements. So statement authorization verification models also play a role. The following white paper characterizes the most common authorization models for statements which might also bring some additional rigor to the discussion.

https://github.com/SmithSamuelM/Papers/blob/master/whitepapers/ACDC.web.pdf

See section 3 property comparison for the different models of authorization. Understanding how the model properties differ provides additional information as to why we want a separation between key management and statement management.

dhh1128 commented 3 years ago

@OR13 and @dlongley : Please tell me if I have understood your concern accurately.

I think you're worried that an issuer could use key A from Jan 1 to June 1, and then revoke key A. Then, on July 15, a malicious party could get key A and use it to sign a credential, claiming that the issuance date was months before, when key A had not yet been revoked. Essentially, possession of the revoked key allows an alternate past to be invented.

Have I understood your concern accurately?

There are several solutions to this problem (I'd be happy to go over some), but I claim it is not the DID spec's job to provide them. It is just the DID spec's job to provide a way to reference a state of a DID at a particular point in the past. That is using the ?version-id=X mechanism.

The DID's state in the past is immutable. We cannot give the future the ability to rewrite the past. You are worried about a malicious use of the key rewriting the past; I am worried about a malicious use of revocation rewriting the past. Neither is acceptable. That is why I am opposed to Orie's verbiage in #548; revocation cannot be retroactive.

dlongley commented 3 years ago

@dhh1128,

Please tell me if I have understood your concern accurately.

I think you're worried that an issuer could use key A from Jan 1 to June 1, and then revoke key A. Then, on July 15, a malicious party could get key A and use it to sign a credential, claiming that the issuance date was months before, when key A had not yet been revoked. Essentially, possession of the revoked key allows an alternate past to be invented.

Have I understood your concern accurately?

There are several solutions to this problem (I'd be happy to go over some), but I claim it is not the DID spec's job to provide them. It is just the DID spec's job to provide a way to reference a state of a DID at a particular point in the past. That is using the ?version-id=X mechanism.

The DID's state in the past is immutable. We cannot give the future the ability to rewrite the past. You are worried about a malicious use of the key rewriting the past; I am worried about a malicious use of revocation rewriting the past. Neither is acceptable. That is why I am opposed to Orie's verbiage in #548; revocation cannot be retroactive.

I agree with your entire post and that has been my position from the beginning :). +1 to consensus!

dlongley commented 3 years ago

@dhh1128,

My main points (which I think you also agree with):

  1. We must not allow the future to rewrite the past.
  2. The DID spec's responsibility in this matter is to define common representations/interfaces that DID methods may implement to enable checking the current and past status of verification methods.
  3. Other software higher up on the stack must make use of these mechanisms (and others) to give users confidence that the future is not rewriting the past.
msporny commented 3 years ago

PR #569 has been submitted to resolve this issue. This issue will be closed once PR #569 is merged.

msporny commented 3 years ago

PR #569 has been merged, closing.

cwarny commented 2 years ago

Late to the party. Is there a summary of the consensus? I landed here because I was wondering how a verifier would verify a credential signed with a key that has since been rotated. Am I correct that this would require each DID document to persist its entire history of keys forever and that the verifier either knows which specific key to look for or needs to "crawl" through the history of those keys? Thanks

msporny commented 2 years ago

I landed here because I was wondering how a verifier would verify a credential signed with a key that has since been rotated. Am I correct that this would require each DID document to persist its entire history of keys forever and that the verifier either knows which specific key to look for or needs to "crawl" through the history of those keys?

This is an involved use case that probably doesn't have a consensus answer at this point, so the following are just my thoughts (as the Editor of the specification and an implementer):

DID Documents probably won't "persist its entire history of keys forever". Some DID Methods might choose to do this, but you probably won't be able to count on that feature.

DID Documents that are stored on DLTs will probably provide some sort of "historical DID Document" feature that allows you to see if a key was valid at a certain point in time. With these DLT-based DID Methods, where you can check a key's status at a certain point in time, it would be possible to tell if a credential was every valid at a certain point in time.

Though, you're going to be dealing with the least common denominator here, and that's going to be... for an active verification on a credential, if a key has been rotated, the verification on the credential will fail (because the key will not exist in the latest DID Document for many DID Methods).

Hope that helps, just my $0.02.

cwarny commented 2 years ago

Thanks. I'm surprised that the default would be rotation=revocation, this seems less than ideal, but I guess I don't really see a way around that. Wouldn't this be a common situation? It feels like verifiers will routinely bump into rotated keys. I guess the holder of the VC, via an agent, could periodically hit the issuer's "refresh service" just in case the issuer happened to have rotated the signing key, but that seems awkward. Or maybe the holder, when presenting the VC to a verifier, could hit the refresh service for the VC before wrapping it in a VP? Alternatively, the DLT-based "historical DID document" feature you mention will become a must-have feature

dlongley commented 2 years ago

@msporny,

Though, you're going to be dealing with the least common denominator here, and that's going to be... for an active verification on a credential, if a key has been rotated, the verification on the credential will fail (because the key will not exist in the latest DID Document for many DID Methods).

-1 ... rotation doesn't mean removing the verification method from the DID document; that is revocation. See:

https://www.w3.org/TR/did-core/#verification-method-rotation

Rotation involves decommissioning or destroying the secret key material associated with a verification method so that it is no longer used. This does not mean that the public key material is removed from a DID document. That may happen for keys that are intended to be short term, but it would be bad practice for long term keys.

That being said -- the rest of your comments regarding history and being able to see if a proof was valid at a previous point in time are applicable for cases where verification methods are revoked.

msporny commented 2 years ago

+1 to the clarification that @dlongley made above.

I guess the holder of the VC, via an agent, could periodically hit the issuer's "refresh service" just in case the issuer happened to have rotated the signing key, but that seems awkward.

You might want to read how a refresh service spec might work first:

https://w3c-ccg.github.io/vc-refresh-2021/#refresh-protocol

Again, just my personal opinion for now... I expect that, eventually, credential validity periods will be less than half of a key validity period (including rotation and then, eventually, revocation). If we have automatic credential refresh, you'll get a new one, for the new issuer key before they end-of-life the old issuer key (via revocation). The time periods will largely depend on the issuer and use case. I expect much of the industry to settle on Let's Encrypt-like practices for credential validity (3 months) and key rotation/revocation (2-3 years to rotate, 5 years to revoke -- presumption on HSM-backed issuer keys).

Or maybe the holder, when presenting the VC to a verifier, could hit the refresh service for the VC before wrapping it in a VP?

This could result in DDoS for large issuers... the current refresh protocols we have suggest a time window when holder software should try to refresh.

Alternatively, the DLT-based "historical DID document" feature you mention will become a must-have feature

We can't make the feature a must have... some DID Methods will never be able to/want to support it (did:key, did:web, did:git come to mind).