-
Notifications
You must be signed in to change notification settings - Fork 96
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
Standardize the key revocation list #14
Comments
This is assigned to @csuwildcat ... waiting for him to be added to the group. |
I wonder if keys are the only data in a DID doc where it is desirable to test revocation. Do endpoints have a similar need? |
I don't feel this should be something specified in the DID spec, as it may differ greatly between methods, with some methods choosing simpler routes, like implying revocation based on key removal. |
Wonder if we can adopt a revocation cert approach like what has been used historically with PGP for interoperability? Or attempt to standardize the use of serviceEndpoints for facilitating revocation lists |
I think there is value in including a Additionally, there could be value in recommending a replacement key, or adding a "succeededBy" property that references another key. It was brought up that some DID methods are sensitive of large DID Documents. In this case, resolving a service that contains revoked keys should be a possibility, as long as the structure of the inactive key is consistent. This is not to claim that all revoked keys need to be marked as revoked, certainly there could be a use case where removing a key all-together would make sense. EDIT: I do think it is important to list tradeoffs in the design -- more updates to the diddoc, smaller diddoc size vs external resolution (a serviceEndpoint). There are competing interests here and I would urge to consider a more flexible solution that suits a wider variety of implementations, not just those where transaction frequency and size are concerns. |
I strongly believe we should not force DID Methods to retain revoked keys, and allow them the option imply revocation via removal of the key. For many of the more decentralized DID Methods, it simply isn't feasible to retain all that data on a constantly accumulating basis across tens of billions of DIDs. One scalable way to do this would be to publish key revocation references in an off-chain Hub/datastore that has a well-known mechanism for location/retrieval. This would allow the DID controller to publish any number of key revocation entries with any amount of detail they wish, all without encumbering the scarce resources of the underlying decentralized systems the DIDs are anchored in. |
To add a bit of detail: if we add a standard property/mechanism like Beyond this singular topic, I would advocate that we, as a WG, strongly push for all this sort of stuff to be handled via Service Endpoints. There are bound to be many, many things people might argue to put into the DID Document, and given this is generally backed by scarce, decentralized resources, I think it would be smart to set this precedent early. |
I agree. I think ideally, a publicKey entry would point to a service endpoint definition which could be used to answer questions about revocation or succession. Alternatively, this information could be embedded in the publicKey definition itself, but I'd rather see it in service endpoints section. |
The obvious way to revoke keys is to remove them from the DID document. (This is analogous to the way that OpenID Connect keys are revoked by removing them from the referenced JWK Set document.) Adding a list to the document won't scale, and so isn't an option we should consider. |
Though I agree that for many global scale DID Methods that having revoked keys in the DID itself will not scale. HOWEVER, some smaller scale DID methods, such as :btcr :peer :git etc. need to have some consistent way to convey that a key is not only absent or inactive, but explicitly revoked. These methods can’t use an interactive service endpoint. — Christopher Allen |
The service endpoint need not be interactive (depending on how you're
defining interactive). Could you not include an endpoint that leads to a
flat file with the revocation data?
…On Wed, Oct 16, 2019, 10:42 PM Christopher Allen ***@***.***> wrote:
Though I agree that for many global scale DID Methods that having revoked
keys in the DID itself will not scale.
HOWEVER, some smaller scale DID methods, such as :btcr :peer :git etc.
need to have some consistent way to convey that a key is not only absent or
inactive, but explicitly revoked. These methods can’t use an interactive
service endpoint.
— Christopher Allen
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#14>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABAFSRDBG6MGP54KV2RO7DQO73NLANCNFSM4IYTAHWA>
.
|
I agree with @ChristopherA 's comment above. The did:peer method revokes keys by adding them to a I don't have a strong opinion about this issue in general--I just don't want a decision to be made that invalidates what did:peer is doing. Today, what the method does is all allowed by the spec. |
While this is true, I'm really concerned about doing just this. Here are two attack models to consider: Attack Model 1: I have two devices, each w/ a key that I can use to perform authentication. One of those devices is stolen, I use my software to "deactivate" the stolen device. This means, that the public key is removed from my DID Document. At some point in the future, I'm tricked (somehow) into "reactivating" the device, which adds the previously revoked public key back into the approved verification methods for authentication. Attack Model 2: I'm a developer writing software that modifies DID Documents. I believe that I'm aware of all locations in a DID Document that may refer to a key. When a key is revoked, I go into all of those locations and look for the key in question and remove it. Unfortunately, this particular type of DID Document has 3 extra locations where the key might appear, and I don't clear the key from those locations resulting in a potential for compromise. All this points to either plan 1) we accept these attack models as very real possibilities, or plan 2) we use a revocation list of some kind for cryptographic material. I think we should do plan 2 above, which seems to be workable if we also do the following:
There is a downside here, in that we almost certainly need to fetch the list before doing any sort of key operation to see if the key in use has been revoked (to prevent attacks 1 and 2 above). If we agree to that general plan, the solution space gets pretty small:
Using the service endpoint feels like the correct direction, but that may have us mandating that all DID Documents MUST provide a key revocation list service endpoint. |
I don't understand how a service endpoint approach centralizes revocation.
If the endpoints are to multiple instances of multi-master personal
datastores, it's a scalable, decentralized means of expressing this, and
all manner of other assertions.
…On Thu, Oct 17, 2019, 6:18 AM Daniel Hardman ***@***.***> wrote:
I agree with @ChristopherA <https://github.com/ChristopherA> 's comment
above. The did:peer method revokes keys by adding them to a deleted list.
The list is called deleted rather than revoked because it also includes
other things in the DID doc that have been deleted, such as service
endpoints and authorization rules. This handling is necessary to support
the CRDT semantics used by peer synchronization. A service endpoints
approach won't work, as it requires knowledge of the current state of a
peer's world to be centralized. I believe that many peers *will*
centralize how their state is managed, but I am unwilling to require that
behavior.
I don't have a strong opinion about this issue in general--I just don't
want a decision to be made that invalidates what did:peer is doing. Today,
what the method does is all allowed by the spec.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#14>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABAFSUUSZ4ADTNYRW2XOMDQPBQZVANCNFSM4IYTAHWA>
.
|
@csuwildcat my understanding of how a service endpoint approach centralizes revocation, is that it does so for an individual entity's domain. If the did spec requires there to be a service endpoint for a list of revoked keys (or for any other view into the internal state of a domain), then the did spec is requiring there to be a single authority for that domain's internal state, and that may not work if the entity's domain is fully decentralized. |
Excellent point, @brentzundel -- we should definitely avoid mandating and we may even want to go as far as saying "wherever you point to, we strongly advise that it's also decentralized". The multi-instance mechanism suggested by @csuwildcat is an option (albeit, a bit complicated). An IPFS link may be another acceptable mechanism. Pointing to another "cheaper" document on a DLT could be yet another. |
To clarify, I'm saying I don't think it's a good idea to mandate the use of service endpoints for revocation. I.e., I strongly prefer "a DID Doc SHOULD use a service endpoint for revocations lists." over "a DID Doc MUST use a service endpoint for revocation lists." |
I sympathize with allowing in-Doc revocation listing, I just worry about
devs errantly trying to commit DID Doc modification ops into the majority
of Methods, which I'd imagine will the the most scalable ones, and errantly
include something that invalidates their ops. I suppose the ecosystem will
just need to be super judicious about library/validator code support and
evangelism to ensure devs can navigate the disparate minefield of DID
Methods that do/don't support in-Doc revocation listing, and not lose
money/time on failed ops.
…On Thu, Oct 17, 2019, 3:10 PM Brent ***@***.***> wrote:
To clarify, I'm saying I don't think it's a good idea to mandate the use
of service endpoints for revocation. I.e., I strongly prefer "a DID Doc
SHOULD use a service endpoint for revocations lists." over "a DID Doc MUST
use a service endpoint for revocation lists."
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#14>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABAFSUCJ6GDPSYNRSCZNHTQPDPG3ANCNFSM4IYTAHWA>
.
|
Haven't seen much activity on this thread lately, but I still feel retaining old key objects on DID Docs with properties that declare a revoked status will lead to DID Docs growing far too large for many DID Methods to support, which implicitly means devs will need to actively support at least two completely different mechanisms of revocation (in-doc retained keys and an endpoint-based mechanism). Given anything that involves the definition of complex behaviors/protocols for how to externally handle in-doc revocation properties/values is going to stray outside the scope of data format definition, isn't the most logical move to create a scalable, endpoint-based protocol/mechanism for key revocation that is unified across different DID Methods? |
I think there is general consensus at Digital Bazaar that this is true (even though the Veres One ledger can support this sort of thing). There is not consensus at our organization on what the better approach is -- 1) just removing keys w/ no key revocation list, or 2) removing keys and placing them on an external key revocation list. With 1, there is concern that this won't work for DID Registries that are not capable of doing historical querying (like did:web). With 2, there is concern about having yet another place you have to go before you can see if a signature is valid for a particular DID. |
I'm fine with a a spec that suggests or recommends using revocation lists,
but I'm not at all okay with a spec that requires revocation lists. The
peer did method will not use them.
…On Fri, Nov 1, 2019, 12:46 PM Daniel Buchner ***@***.***> wrote:
Haven't seen much activity on this thread lately, but I still feel
retaining old key objects on DID Docs with properties that declare a
revoked status will lead to DID Docs growing far too large for many DID
Methods to support, which implicitly means devs will need to actively
support at least two completely different mechanisms of revocation (in-doc
retained keys and an endpoint-based mechanism). Given anything that
involves the definition of complex behaviors/protocols for how to
externally handle in-doc revocation properties/values is going to stray
outside the scope of data format definition, isn't the most logical move to
create a scalable, endpoint-based protocol/mechanism for key revocation
that is unified across different DID Methods?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#14?email_source=notifications&email_token=AAQ3JCAIBL5K3XEHTG4YF7TQRR2PBA5CNFSM4IYTAHWKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC32LTQ#issuecomment-548906446>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAQ3JCFCCYNSPGC4H7W4G3LQRR2PBANCNFSM4IYTAHWA>
.
|
I don't believe it would be useful to define an attribute that is sometimes meaningful and sometimes ignored, and whose behavior is undefined. That's not the way that interoperable standards are constructed. I believe we should close this issue with no action, on that basis. |
For Methods that are concerned about such things, use of this property/mechanism would likely need to produce an error to let the user know that amassing old key references is not allowed. How would one describe in a data format spec a property that has such divergent external behavior across Methods, to the point some actually throw when people attempt to use it?
…On Fri, Nov 1, 2019, 2:03 PM Mike Jones ***@***.***> wrote:
I don't believe it would be useful to define an attribute that is
sometimes meaningful and sometimes ignored, and whose behavior is
undefined. That's not the way that interoperable standards are constructed.
I believe we should close this issue with no action, on that basis.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#14?email_source=notifications&email_token=AABAFST6PJCX7IU6RNJ4WU3QRSKQ3A5CNFSM4IYTAHWKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC4E7WI#issuecomment-548949977>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABAFSSMNPKMXT2R5WDFQG3QRSKQ3ANCNFSM4IYTAHWA>
.
|
To dig in a bit on the issue of certain Methods actively blocking this behavior/property from being used, would this mean we need to specify a standard parse error/directive Method implementer must emit when throwing on the unsupported/blocked inclusion of this sort of revocation metadata in their DID ops? I just want to know how we would deal with the downstream consequences. |
Related thought, some method like If we can't formalize revocation beyond the concept of removal from a DID Document at the interop level, I worry about the implications for key life... Time is the enemy, revocation and rotation in a gentle manner seem to be useful, especially if you want short lived keys, that issue credentials which still need to be verified, or which need to be reissued. I'm in favor of MUST language for revocations using service endpoints IF revocation is implemented in any way other than remove from the DID Document. |
I've dug so many holes only to find fool's gold in my search for scalable revocation approaches since my SSL/TLS days, I'm hoping we can avoid falling into them as well. |
@jandrieu "Resolving a DID reveals the latest, authoritative DID Document. If a key is no longer in the DID Document, it is either revoked or was never valid." - you noted on the other Issue that I was incorrect in my understanding of this statement. Can you clarify, because it seemed like you were saying a key no longer in the DID Document authoritatively means it has been revoked. I agree with this, and my agreement above reflects that. I have no issue with leaving the spec open for people/Methods to attempt to retain keys for random reasons, but large DID Docs will be a nonstarter for any Method that seeks robust decentralization + globally indexable resolution of its DIDs (highly desirable features). If folks take out their calculator and enter whatever they believe the average number/size of state change ops a DID from a Big Doc DID Method will generate over its lifetime, then multiply that by, say, 100 billion, the number that appears on the screen should be nothing short of frightening. Some methods are taking this into account, and have protocol limitations on the size of ops, ways to reduce/prune past state, and other optimizations that are all designed to ensure you can run them without requiring a datacenter to operate a single node. The issues that will plague 'Big Doc DID Methods' (at least those that try to scale beyond cottage usage and small time POCs) are some of the same issues Craig Wright and his merry band of Bitcoin SV folks will face if they proceed with their giant block sizes. |
@csuwildcat your last comment is what I read as different from the sense of the other thread:
The resolution is in fact, that we DO pursue a standard/scheme for OPTIONALLY retaining keys and marketing them as revoked. So, I think we may be on the same page but talking past each other.
That is right. To my view, if a key isn't in the DID Document, it is not valid. Whether because it is an old key revoked or because it was never there. That's the "80%" use case in the Pareto principle here. I just want to be sure we leave the door open for the case where the controller sees value in retaining "revoked" keys with some meta-data about why and what that means. Because, yeah, I agree with you. Storing old keys by default will face scaling problems. |
What we may want to do at this point is state something like this: With respect to keys that are revoked, DID Methods may choose express those keys or lists of keys in a method specific way. This specification, by design, does not specify a mechanism for doing so. |
Not helpful for developers... We should be helpful and explicit not vague.... either define it or don't allow it. |
I agree with @msporny that you need to leave the details of key revocation handling outside of the spec, and to each DID method/provider accordingly. Some may wish to use a CRL-like approach while others may prefer an OCSP-like approach. Both are valid and should be supported. |
IMO, a DPKI spec, that does not define revocation explicitly is pretty broken... even GPG has support for this... and look at all the issues with key servers that we have been able to learn from.... Leaving this up to DID Methods creates exponential switch statements regarding "verification" and opens the door to numerous security issues.... |
If your software wants to allow for an expired key to still show up... why don't you augment your DID Document after resolution to support that, and take full responsibility for all the security issues that creates? There is nothing stopping people from using custom resolvers that inject expired / revoked keys into did documents, and hard coding against those interfaces.... just don't ask other developers to support that kind of thing in their implementations. |
+1 that this cannot be left to individual DID methods -- I think that's a total failure to achieve interop. One of the main goals of the did-core spec is to make it so that my application can fetch a DID Document (using some DID method-specific resolver) and then my application knows whether or not, for example, the verification methods found therein are still valid for whatever purpose they are listed under (verification relationship). The application doesn't have to care about any DID-method specific details; those were handled by the resolver and the application can get on with its own business (clean separation of concerns). This is the common form of operation and where we need interop. The simplest way to handle this is to say that any verification method that is expressed in a current DID Document is valid for the purpose it is listed under (verification relationship). If it's not there, it's not. Now, there may be other forms of operation that are not common. For these, I do think it's acceptable for DID methods to provide a way to search through the history of changes to a DID Document and individual applications may have clever ways for relying on that information safely. These I'm happy to leave these as special cases with DID-method specific solutions -- where there may be some level of interop based on DID parameters like "version". |
If we need a way to retain revoked verification methods, then we should allow for individual verification methods to define how they can be marked as revoked. For example, their specifications can indicate that if they have a |
After consideration, I'm rescinding my previous support for adding vague language that encourages unclear in-Document revocation mechanisms, and going to stick by the position that the endeavor to retain revoked keys in the Doc is fraught with security and scalability issues I just can't support. The spec should not specify a mechanism for this, because it is likely to lead to bad outcomes (as Chris/others have noted), and divergence in Method support that will harm the ecosystem. |
@OR13 wrote:
I think that's the problem here. AFAICT, we are not writing a DPKI spec. We are writing a spec about Decentralized Identity. Says so right in the first two sentences of the Abstract:
Identity may contain certificates, it may not. Even if I have certificates, they may be connected to some existing certificate store/model that is based on an existing revocation model (eg. CRL/OCSP). If you are trying to turn both the entire Identity and entire PKI world on their respective heads with this single spec - I think you are shooting for the moon. Why not simply try to solve problems that you can solve? |
Is there a middle ground between revoked and in use? A key that needs to be around for historical purposes but is no longer used to sign new documents? A fine answer to this, and the need for some to retain historical keys, could be to expose a |
@glcohen : I believe what I am about to say is aligned with the thinking of others on this ticket, but I am not sure. So this will be an interesting test of whether we all share the same mental model. My answer: Revocation isn't retroactive; it doesn't undo the status of a key (e.g., the validity of its signatures) in the past. In other words, there is no way to say, "I revoke this key from point-in-time T looking forward, and also from T looking backward." Revocation just covers the forward-looking part. Now, combine that with the fact that you can resolve a DID not just for the present, but for any arbitrary point in time in the past, and you already have the middle ground you're imagining, without exposing a serviceEndpoint to contain old stuff. If key X is revoked at time T, then a resolution of the DID against any time >= T will not contain X, and times < T will contain it (at least as far back as it had valid privileges). |
Is that a requirement of a DID method/resolver? I can see a number of cases where it would not be possible to resolve a DID for any arbitrary time T - but only for present. (but that aside, I agree with your description of revocation) |
@dhh1128 we've been thinking through the case of key compromise where revocation does mean old signatures are now invalid. Perhaps there's another way to express this? And yes, our DID method presently only allows you to view the current state, not history so what you describe is impossible. I am curious if there is a requirement for DID methods to retain all histories. |
@glcohen : I believe the idea of invaliding a key backward in time (as opposed to from this point forward) is not generally described with the word "revoke" but rather "decry." What you are saying to someone is, "Yes, at the time this was signed, the key was considered valid. But we now disclaim its authority. It was actually compromised, and its previous actions are also now suspect." Support for decrying something is not something you can impose on others; all you can do is ask them to consider your assertion that the key was not in your control when it was exercised. If you set up the key to take legally binding actions on your behalf, you might still have to live with the consequences; there's not a simple "undo my signature" feature. But I think decry might be useful (e.g., in a case where a child grabs a parent's cell phone and does something foolish with it). Re. the question that both you and @lrosenthol asked: no, I don't think DID methods are required to support resolution at an arbitrary point in time. However, many do, for exactly this reason. And timestamp and version-of-DID-doc are both standard matrix parameters that are supposed to be defined for all resolvers (even if they aren't supported). @peacekeeper will know more. |
@lrosenthol and @glcohen, you both touched on great points related to history retention, and this specific topic is but one of many that revolve around the same core issue: resolving past DID states over long periods of time (or perpetually). The most significant objective problem is the comically massive amount of resources doing so would implicitly require, for example:
How it relates to this feature: my suggestion would be for the community to orthogonally codify some sort of Service Endpoint-based protocol to allow for detailed, historical key/revocation info, among other things (which can still be chain-anchored/provable). I say this because my calculator tells me ever-growing lists of data in DID Documents are going to require folks to make some tough choices - so in the words of the Grail Knight from Indiana Jones and the Last Crusade, I hope we all "Choose wisely". |
This is one of the best things I have ever read from this wg. |
Related to #279 which has been merged. Unfortunately, it did not include my suggestions. |
@dlongley Please open a PR and tag people for review. |
This is done, marking pending close and waiting 7 days to see if there are objections. |
No comments since marked pending close, closing. |
@satazor moved from CCG (w3c-ccg/did-spec#96)
The text was updated successfully, but these errors were encountered: