decentralized-identity / decentralized-web-node

Decentralized data storage and message relay for decentralized identity and apps.
https://identity.foundation/decentralized-web-node/spec/
Apache License 2.0
402 stars 79 forks source link

Revocation Subtleties #138

Open alanhkarp opened 2 years ago

alanhkarp commented 2 years ago

Revocation is a trickier subject than it first appears. Who has permission to revoke? What can be revoked with that permission? One point that is obvious but should be called out is that revoking a capability effectively revokes any capability delegated from it.

Can the delegatee revoke a capability it was given? There would seem to be no need; the delegatee can just not use the capability. However, it might be useful to prevent accidental use and to provide deniability if the delegatee can revoke its own capabilities.

Permission to revoke is implied by being on the delegation chain, but there are two possible interpretations of that permission. It could be only the next delegation on the chain or any downstream delegation. There are arguments for both.

Say that Alice delegates to Bob who delegates to Carol and to David. Bob might be unpleasantly surprised if Alice revokes Carol's capability. On the other hand, Alice might be in a position of responsibility and knows that Carol should not have the permission Bob granted to her, but Bob is unavailable to revoke Carol's capability. In that case, it is important to allow Alice to revoke Carol's capability without affecting David's.

These two cases could be policies implemented by different verifiers, but the capability itself might specify the desired policy.

andorsk commented 1 year ago

I think this can be addressed partly in the companion guide that's being built out. But great question. We'll discuss over a DIF call in the near future this issue.

LiranCohen commented 1 year ago

Thanks for bringing this up, we are looking to tackle this as a part of permissions sometime in May.

Keeping it open for now as this might be a good place for discussion.

andorsk commented 1 year ago

Discussed on DIF : @alanhkarp to elaborate on use case.

alanhkarp commented 1 year ago

Revoking a public key is harder than revoking a certificate capability. You don't know who will be relying on a public key, so you need some sort of widely accessible list of the revoked public keys. For a capability, you know that only the verifier for the resource the capability designates needs to know that the capability has been revoked. While simpler, any capability revocation scheme must have a way to know if a revocation request is authorized. You also need a way to tell the resource server to stop honoring a specific capability and any delegations from it. That could be a problem if you've replaced parts of the delegation chain with proofs that the delegation is legal. There's also the complication of a distributed system. Is the revocation effective when received by the first node? The last? A quorum?

There are a number of options when deciding how to do revocation, some of which are in conflict. The design will have to make choices based on requirements specific to the system. The key difference among these choices is who is authorized to revoke a capability.

1. No revocation; rely on short-lived capabilities.

This is the approach taken by Simple Public Key Infrastructure (SKPI, pronounced spooky), RFC 2693, 1999. One problem with this approach is the need to continually reissue capabilities that are needed beyond the expiration time. Another is picking the lifetime. Too long, and there's too much opportunity for abuse; too short and the refresh overhead is too high. One example of the problem is OAuth 2. They originally recommended a 5 minute lifetime for bearer tokens, which later was increased to hours and then days.

2. Revocation is a specific permission.

You might want a specific revoke capability that you can delegate to someone else. For example, Alice delegates a capability to Bob and delegates the revoke permission to HR. When Bob changes jobs or leaves the company, HR can revoke all capabilities delegated to Bob without needing to be in the delegation chain.

3. The holder of a capability can revoke it.

It seems unnecessary for the holder of a capability to revoke it. You could just stop using it. However, explicitly revoking a capability you hold prevents accidental use of it or use by a successful hack.

4. The delegator of a capability can revoke direct delegations.

This choice is the most natural. In fact, it's necessary, but there are cases, discussed below, where it is not sufficient.

5. The delegator of a capability can revoke any delegation deeper in the chain.

There are enterprise use cases in which #4 can cause problems. Imagine Alice, a director, delegates a capability to Bob , a department manager, who subsequently delegates that capability to Carol, David, and perhaps many more. Alice finds out that David should not have been given the permission, but Bob is unavailable to revoke David's capability. With #4, Alice can revoke Bob's capability, but then Carol and the other can't do their jobs. With #5 Alice can revoke the capability given to David. This use case presumes that Alice knows David got a delegation, but such auditing is necessary in an enterprise.

6. Revoke the public key the certificate capability is issued to.

Telling the resource server that the public key a capability was issued to is revoked effectively revokes the capability, but you need a separate mechanism to know who has permission to revoke that public key. If the public key was used for more than one capability, you might inadvertently revoke that capability as well. Consider the case where Alice is a contractor for Bob, who gives her a capability to some resource. Alice is also a contractor for Carol, who gives Alice a different capability to the same resource, a common situation in the enterprise. A problem arises if Alice uses the same public key for both capabilities. Bob will revoke the public key when his contract with Alice ends, but that will also revoke the capability Alice got from Carol, whose contract is still active. If the intent is to revoke all capabilities issued to Alice by revoking one key, then you need a widely accessible place to list revoked public keys so that all capability verifiers can find them. However, you lose the privacy that comes from using different public key for each capability.

andorsk commented 1 year ago

Discussed @DIF call: @andorsk to give a response on this before the next DIF meeting.

andorsk commented 1 year ago

@alanhkarp have you seen the following:

I don't think the spec implements any timing scopes, but that would sit above the DWN call. Will want to ask over the DIF call.

I think most these other cases are covered, but let's discuss over the next call in more detail

alanhkarp commented 1 year ago

My comments on 10.4.1 PermissionsRequest

The Message Descriptor link doesn't work.

Throughout you talk about "the DID URI string of the party" implying that there's only one.  I think the phrase "a DID URI string controlled by the party" is more precise.

Why does the PermissionsRequest include a grantedBy field? Isn't it sufficient to send the request to the party that will construct the grant? In fact, the recipient of the PermissionsRequest might not be the one granting the permission

Should the method property be limited to a single item, or can it be a list, e.g., ["read", "append"].

What if none of schema, protocol, recordId, or contextId are included in the request?  Shouldn't you require at least one of these so that the request will be for something?

In the attestation you say "signed using a key linked to the DID of the owner." I think saying "a DID of the owner" unless you're using "owner" to mean something specific to DWN.

The encryption section refers to "the owner of a Decentralized Web Node." Should you include "or authoring party" as you did in the attestation section?

The delegation property must be dropped for reasons I've explained elsewhere. It can be included if the meaning is changed to "Please do not delegate."

How do you enforce a "Do Not Publish" property?

The sharedAccess property appears to be a clever solution of DWN not being able to return a capability when a new object is created. Of course, there's no reason the grantee of such a capability can't also have one or more to individual objects.

alanhkarp commented 1 year ago

My comments on 1.4.2 PermissionsGrant

If the granted permission is in response to a PermissionsRequest, it MUST contain the UUID of the PermissionsRequest. However, the description of PermissionsRequest does not mention a UUID.

The delegation property must be removed for reasons I've explained elsewhere.

alanhkarp commented 1 year ago

My comments on 1.4.3 PermissionsRevoke and 1.4.4 PermissionsQuery

Section 1.4.3 needs a lot more content as described in https://github.com/decentralized-identity/decentralized-web-node/issues/138. For just one example, how do you know that the revoker is authorized to revoke this capability?

Section 1.4.4 doesn't say if permissions are needed to query.

andorsk commented 6 months ago

@andorsk to get done by next call

andorsk commented 6 months ago

Discussed at DIF:

I will add better language around the actual permission revocation normative language as well by next call. To share: the ability to show how delegated revocation works. Protocol definition driven changes things.

@andorsk to check the current permission revocation state by next call.

andorsk commented 2 months ago

310 initially addresses. Needs more work.