-
Notifications
You must be signed in to change notification settings - Fork 18
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
Syntax for an unattenuated delegation #131
Comments
Does above description clarify it ? In regards to DID specifics, I have hard time putting a finger on it. I suppose it is indirection. Explaining that ability to |
Ok I have a better explanation. In the context of https://github.com/web3-storage/specs/pull/7/files we would like some key to represent If we were to use |
Clarity
AHA! Oh wow okay this is what we've been talking past each other for many months about! Yes, I see what you want now. The diagrams and wording are so similar. I think I was missing the pipelining idea. PipeliningAside from some lingering intuition about possible attacks, I think that your "pipeline" idea is awesome. If this were a "live"/dynamic ocap system, this would probably get modeled as a forwarder proxy. UCANs are "static", but I don't see why we can't express the same thing. You can always revoke the relevant UCAN. I'm going to ask around to see if my intuition on danger is valid, but otherwise we should make this happen IMO.
|
Even though pipelining is a really cool idea, I also wonder if we can solve this with DIDs directly. Let me noodle on it 🤔 |
Revocation ForwardingWould this also grant you the ability to revoke UCANs that the root DID delegated in a different chain?
|
👍 For what it's worth I think
That was my interpretation as well, which is why it did not cover this
I would argue that this kind of meets that criteria but also isn't necessarily different from UCAN itself
|
...is it different? 😳 |
If we create another I feel it is equivalent to what I want to do with resources I want to express delegation to resources that I own but also ones that I may own in the future. |
Oh, indeed it covers any extension that you would add later |
I assumed it would not, but perhaps it should. I think I could be convinced into either |
Yup yup! I meant it more as an example of trying to being explicit about the selector.
I'm not necessarily endorsing the idea yet, but we should definitely think about it more. From a workflow perspective, this pipe-lining idea basically replaces a traditional DID document. In a lot of ways, it says "this other DID is fully equivalent to me". If that's the case, and I'm going to say rotate (or lose!) my key, I probably want the ability to disable misbehaving delegates. One could argue that this is mixing concerns, and is better handled at an identity layer. As I've been thinking about the pipeline/forwarder in "live" ocap terms, this on/off switch is a capability that I could hand to someone else. It does add a lot of possible states to the system. The forwarder idea in general adds some minor complexity to delegation checking, too, but possibly pays off. Root Key Revocation🤔 This also doesn't solve for the case where the root key is misbehaving.
Alice can always revoke Bob. One could argue that Bob should never be able to revoke Alice, because it would immedietly negate the revocation. If you want to do "true" group management (admins can revoke each other), then a DID is probably the correct layer. Anyhow I'm getting off topic 😅 |
I’m not sure I fully follow, but that someone in our scenario was second key in chain of command. It can switch on/off rotating keys ability to represent did |
I would agree. Now that I think about it I also don’t like idea of I think it would be a lot simpler to not allow revoking delegations not issued by the key & say that say they should accomplish that by going up the command chain. This does seem inconvenient in my scenario as after we burn key revoking delegation from it would involve waking the warm key, but then again we could insert one more key in the command chain to address it. The thing that bothers me the most however is that if we revoke in the parent we affect whole lot of other delegations as opposed to individual one we’d like to revoke |
Sorry, the original text included pictures in my head that I failed to actually write down. Yes, basically a "second in command" like you described 💯 In a live, running ocap system, you push messages around like in the actor model (or like messages over a network). A fairly common pattern is to delegate to proxies instead of handling out access to objects directly. This the "second in command". I could add all of my capabilities to this object (in a big table or something), and have others delegate to it instead of me. I then grant you access to everything in the proxy. If I go offline, my proxy is the one being delegated to. This version has more moving pieces, but they're all built up from consistent parts ("just" a design pattern). It depends on local state and the proxy being reachable, though. In that dynamic scenario, I would keep updating that table "live" as things came in. With UCAN, this is deferred to read time using a static certificate that communicates my intent to implement this kind of capability forwarding. |
Same here. As much as I'd there to be a workaround, I don't think it's possible without reference to some external state (e.g. updating a DID document). |
this is precisely what I want form pipelining. Capture just enough of the table in signed form to proof ability to proxy |
Maybe there’s some clues on how to approach revocation in live systems ? |
Just thinking out load here: The way we validate if claimed capability is warranted is:
It seems to me that we’d need slightly different approach if resource is When evaluated as such I think it seems reasonable to allow such a proxy to revoke any capability it proxied and therefor allow it to be revoked. |
In a live system, you have mutable state and a single source of truth for where it lives. On one hand this is very convenient because... well you can turn things off and on at will. The downside is that it often requires making network calls, so it's not partition tolerant and you have to check this state every time. |
Let me know if it would be good to talk through more how these systems work. I recently finished a re-read of Mark Miller's dissertation, so I have a lot of this hot loaded.
Something like this algorithm makes sense to me, yeah 💯
Just to make sure we're on the same page:
☝️ David is proxied all from Alice, and can thus revoke Bob (and Carol) in the top chain 👇 But we cannot let David revoke Alice, because if so, we end up in this situation:
If David can revoke Alice, who gets revoked depends on the order that you receive the messages. I'm pretty sure that Alice always has to remain the source from which all authority flows |
Sorry for being late to the game. I finally got a chance to catch up on the discussion on wildcards. I use the definition:
By that definition, a UCAN delegation chain that only contains with:* is not a capability, since it cannot be used to designate the resource you wish to operate on. However, a UCAN delegation that only contains w:* can be used in a proof. (Something that isn't a capability appearing in a capability delegation chain seems odd to me.) The implication is that given such a delegation chain, you have to delegate one more time to create a UCAN that designates the specific resource you wish to use. Has that been noted in the proposal? |
Thanks @alanhkarp! I'd love to get your thoughts on how you'd solve what we're trying to solve in a noninteractive setting (i.e. we can't rely on live processes that can hold state and respond to messages). ScenarioAlice has two devices: a phone and a laptop. She wants anything delegated to her phone to be automatically redelegated to her laptop. (You can imagine more scenarios, but using devices makes this easy to reason about) Classic SolutionWe'd use a powerbox, and grant both devices access control over the powerbox DID SolutionWith more complex DIDs than Proposed SolutionWe think that we don't need anything other than certificate capability. Using Our reasoning has been that this is a bit like a powerbox, but given as a noninteractive expression of intention rather than a live process. Does that make sense, or are we on the wrong track here? |
@expede That makes perfect sense. Using such a UCAN in an invocation is the missing piece. When Alice wants to read one of her files, she needs to designate which file. A UCAN containing with:* doesn't to that. If instead she designates the file elsewhere in the invocation, she's separated designation from authorization, the root cause of the confused deputy. The answer is for Alice to delegate to herself a new UCAN containing with:my_file and the with:* UCAN as the proof. This pattern is one I don't recall seeing before, a delegation with a proof that isn't a capability but that unambiguously proves the specific permission. I'll bring this up at our capability group meeting tomorrow. Let me know if you'd like to participate. The invocations in all the UCAN use cases I've seen involve designating only a single resource. Do you envision invocations that involve more than one resource, e.g., copy filea fileb or that involve more than one service? That's when things get interesting as I showed in my transitive access paper. |
Thanks @alanhkarp!
Yeah absolutley. I think that you won't be able to construct an invocation that uses
Depending on how you mean. In IPVM, we have atomic invocations (e.g. compare and swap) that require multiple read and write access to multiple resources at the same time.
Hmm interesting. Using that analogy, how would I grant access to any file on a networked file system? Would I need to delegate each file separately? I haven't had a chance to read your transitive access paper at time of writing this comment, but is that more like a more coarse-grained solution by granting access to a filesystem managing agent that in turns controls the file system and all of its files by parenthood?
Same!
🙏
I'd love to, depending on the time! 👀 At least from the abstact, we're attempting to do this in various places in production, yeah |
I just finished the transative access paper. A bunch of it felt familiar! I don't see any reason why the proposal here would go against the content of the paper. Perhaps to clarify the flow of authority with the wildcard, in case it helps explain the intention:
|
I believe that's the correct thing to do. At least it's what we did in our Zebra Copy work. In your invocation you designate the resource as
which is not connected to the capability at all. You can run into problems when the invocation involves multiple resources. What you should do instead is specify the capability UCAN, perhaps as
or some such, where UCAN-ID is the unique identifier of the UCAN at the end of the delegation chain in the proof. That UCAN MUST grant the requested permission, "call/send," to the specific resource you are operating on, "mailto:alice@example.com" in your example.
Alice can delegate to Bob a UCAN granting him permission to read everything in a particular directory, e.g., /alice/photos/*. Bob can then delegate to the program he's planning to run a UCAN good for just the single file he wants to read, e.g., /alice/photos/vegas.jpg. That's actually good practice anyway, since it's enforcing the Principle of Least Privilege on the program Bob is running.
That's the kind of thing that can get you in trouble if you separate designation from authorization. For example, with your invocation scheme, you can have a single can:*, with:* UCAN that grants permission to both files. If someone else has specified the file to be written you've got the potential for a confused deputy. The meeting is every Friday (50 weeks a year) at 10 AM Pacific time. Contact me by email if you or someone you designate wants to join via Google Meet. |
Our comments "crossed in the mail."
I agree as long as you're careful not to separate designation from authorization.
I believe my previous comment explains how that works. If Alice gives Bob a UCAN specifying with:/alice/photos/*, Bob will have permission to read any photo in that directory no matter when it was added. |
Good to hear 🙌 I've seen the Zebra Copy paper before, but always good for me to brush up 👀
The invocation token has a field
Agreed!
Agreed 💯 This may be signal that we need to expand some text in the invocation spec — thanks! Our approach for invocations to get really specific with what it's operating on, which is equal-to-or narrower than the UCAN (normal delegation rules). We experimented with adding another layer of UCAN that scopes down to the percise resource, but found a couple subtle problems, though the big one is that the contract is confusing with promises. People thought that the promise scoped the authority down to the output of the previous step, but that's not posisble to enforce if both steps are executed by the same agent. Hence, you need to be clear about the scope of what's actually being delegated, and showing that you're delegating e.g. |
The important thing is to associate each argument with its corresponding capability. The simplest approach is to use the appropriate capability as the argument, e.g.,
but any approach that unambiguously associates the argument with the capability works. Note that the method being invoked is designated with a proof. In the above example, the photo service has chosen an API that takes a delegation for the input and output parameters in case it wants to outsource those functions, as in the transitive access example. It could, of course, also accept a proof, but then outsourcing would be a breaking change.
Since anyone holding a UCAN is able to create an attenuated delegation, there's no reason not to require that the capability designate exactly the desired resource or method as in the above example. You not only better enforce Least Privilege on the program running on your behalf, but you avoid several potential foot guns. For example, Bob could have R/W permission to Alice's photo. Using a R/O capability protects him from certain mistakes.
I have worked with two different capability systems that supported promises, but neither used certificates as capabilities. I'll have to see an example of the problem to understand the issue.
I have found that only using simple use cases, like read or copy, leads to designs that work poorly for other realistic uses. I picked the backup service in the transitive access paper as the simplest example that covered every usage pattern I could think of. |
Closed by #132 |
Pulling this out of https://github.com/web3-storage/specs/pull/7/files#r1027388060. I would like to propose clear syntax for an unattenuated delegation between principals.
I am not sure if
"with": "own://did:key:zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV/*"
implies exactly that, if so it does not seem very intuitive, I would find"with": "*"
far more intuitive and seems like it would align with"can": "*"
too.That said I think following would be most compact and most on point IMO:
I would expect ☝️ to be equivalent of "also known as" in DID spec or elsewhere, implying that
did:key:zTo
could be used anywhere in place ofdid:key:zFrom
.The text was updated successfully, but these errors were encountered: