ucan-wg / spec

User Controlled Authorization Network (UCAN) Specification
https://ucan.xyz
Other
191 stars 18 forks source link

What does delegation with empty attenuations imply ? #129

Closed Gozala closed 1 year ago

Gozala commented 1 year ago

Following delegation is valid according to the specification

{
   iss: "did:key:zAlpha",
   aud: "did:key:zBeta",
   att: [],
   exp: null
}

Intuitively one would think it is meaningless, nothing was delegated from one agent to the other. However it seems like a waste to not use this short form for something more useful perhaps delegation of all current and future capabilities it may poses. Seem very useful for delegating all capabilities from stable to the one under rotation

Gozala commented 1 year ago

I have end up abusing this here https://github.com/web3-storage/specs/pull/7/files although perhaps something a bit more explicit would be a better option

expede commented 1 year ago

@Gozala we need this for cases like AWAKE, where you prove that you have access to some capabilities without delegating them while still authenticating that it's not a replay

expede commented 1 year ago

From your WIP spec:

Expample below illustrates did:dns:w3.storage delegating own resource to did:key:zService, which in turn redelegates it to did:key:zRotation.

If I'm reading it correctly, you actually need it to delegate all of its authority to the key service, and in the example it delegates none. I think you'd need to do something like your second example:

Example below illustrates did:key:zRotation delegating did:key:zAli capabilities derived from did:dns:w3.storage through did:key:zService. It embeds adove described delegation chain inside fact to provide a verifiable evidence that it can redelegate capbilities on did:dns:w3.storage bahalf

I not sure that you can use the certificate chain directly like this to rotate keys if you want to actually disallow the previous key. A malicious agent with a stolen key could just not include the rotation in their chain, and keep using the old key. Revocation is fundamentally stateful, which is why systems most DID systems like ION and Ceramic use "anchoring" in external systems to form the source of truth for rotation.

@matheus23 came up with something similar recently for WNFS, which I'll adapt here to your DID management system.

{
  iss: "did:w3s:zAlice",
  aud: "did:key:zIDP",
  exp: null,
  att: [
    {
      with: "did:w3s:zAlice",
      can: "did/update",
     nb: { to: "did:key:zNewAlice" }
    }
  ],
  prf: []
}

Here, the action only allowed is to rotate the key to another specific key. This doesn't have to go to web3.storage per se, but can also be gossiped around directly.

Anchoring in this model does require checking if known delegations using a previous key were valid at that time. Since Alice above knows the certificates that she delegated, and can register a sorted Merkle tree of those. This is public, signed information that does not have to live in a single location (w.g. can be distributed on a DHT).

This does push the active key check outside of the certificate chain, but I'm fairly certain from looking at previous attempts with chained certificate that this is unavoidable.

expede commented 1 year ago

Going to move this to your PR :)

Gozala commented 1 year ago

I not sure that you can use the certificate chain directly like this to rotate keys if you want to actually disallow the previous key. A malicious agent with a stolen key could just not include the rotation in their chain, and keep using the old key. Revocation is fundamentally stateful, which is why systems most DID systems like ION and Ceramic use "anchoring" in external systems to form the source of truth for rotation.

I probably need to clarify this if it was not clear in the writup. During rotation service can decide whether to revoke capabilities granted to an old key or not. If rotation was due to compromise it can issue regular UCAN revocation so validation with old embedded chain will fail because delegation there would be revoked.

However in most cases rotation will be just a custom and no revocation would be desired, in that case service will rotate key without revoking the previous one. This way delegations with old key would still continue to work until one of them is revoked.

Does this make sense ?

expede commented 1 year ago

@Gozala that totally makes sense! If I have the old key around, can I continue to use it to generate new UCANs? (i.e. strictly "inflationary" key membership)

Gozala commented 1 year ago

Back to the original question

you prove that you have access to some capabilities without delegating them while still authenticating that it's not a replay

Seems like it has a specific meaning, might be worth including it in the spec.

expede commented 1 year ago

Seems like it has a specific meaning, might be worth including it in the spec.

Good feedback — can do!


Aside, but while we're thinking about the 1.0, if the other way around makes more sense, we could discuss flipping the delegation semantics. (I don't think that we need to, just signalling that it has come up before)

Right now UCAN requires explicit "reexporting" of capabilities, which makes the intention extremely clear at the top-level. It also makes doing multiple resource/ability pairs straightforward.

The "other" way is to add caveats at each level, so you only include updates. Typically this makes it less clear how to union capabilities together (e.g. you're usually taking the intersection, so need special constructs for unions). You typically end up passing around separate credentials per resource/ability pair.

Gozala commented 1 year ago

Closing this. Answer here is clear to the question, what I was looking for instead is covered in #131