Local delegation with webkeys
"Karp, Alan H" <[email protected]>
| Newsgroups | gmane.comp.capabilities.general |
|---|---|
| Message-ID | <8AD823089998C849A832D86972E69CD5419C26BE@G4W3222.americas.hpqcorp.net> |
I got an idea while reading the Macaroon paper that I think it could be useful in some circumstances. What I'm proposing can be used with any capability represented as data. Here I'll explain the idea in terms of OAuth tokens. An OAuth 2 request looks like https://example.com/resource with Authorization: Bearer xx2hi5444qatl2 plus some other stuff we don't care about in the header. Alice has a token to Carol. She wants to get a separately revocable token that she can send to Bob but does not want to set up a proxy. Instead, she invokes the delegate method of "resource" and gets back a token she can send to Bob. This pattern is similar to both of the IETF drafts for re-delegation in OAuth 2. The problem with this approach is the round trip to Carol. It can be a performance issue, or it might be that Alice can't reach Carol when she wants to delegate. The question, then, is can Alice delegate to Bob without setting up a proxy or involving Carol? Start with a token, Authorization: Bearer xx2hi5444qatl2 Alice could produce a delegation by hashing the capability secret (Do you like ccret better that zecret?), Authorization: Bearer H(xx2hi5444qatl2). Carol (or more properly the infrastructure running Carol) can verify that this delegation is valid by hashing xx2hi5444qatl2. Unfortunately, most of the time there are many capabilities. We can avoid having to test them all by including a capability identifier https://example.com/resource?cid=7 and https://example.com/resource?cid=7 Authorization: Bearer xx2hi5444qatl2 Authorization: Bearer H(xx2hi5444qatl2) Now we know which one to test, but we don't have a way to attenuate. Let's expand the query for that. https://example.com/resource?cid=7&a=r&a=w Authorization: Bearer H(r+w+xx2hi5444qatl2) We still have a problem. Say that Alice delegates to both Bob and David. They both get the above token, but we want them to be separately revocable. We avoid that problem by adding another identifier provided by Alice. I don't think it's a problem if it's easy to guess; it just needs to be unique to delegations of this token. The delegation now is https://example.com/resource/?cid=7&d=1&a=r&a=w Authorization: Bearer H(1+r+w+xx2hi5444qatl2) for Bob, and https://example.com/resource/?cid=7&d=2&a=r&a=w Authorization: Bearer H(2+r+w+xx2hi5444qatl2) for David. There is a problem if Alice shares her capability with Bob instead of delegating. They might use the same delegation identifier when doing further delegations. We can address this problem by using a random nonce for the delegation id or by requiring that Alice and Bob coordinate when picking a delegation id for a shared token. For simplicity, I'll assume the latter. Bob can now do an attenuated delegation. https://example.com/?cid=7&d=1&a=r&d=1&a=r&a=w Authorization: Bearer H(1+r+H(1+r+w+xx2hi5444qatl2)) If a token starts getting too big, the holder of the token can always ask Carol for a new one, effectively starting over. I suppose you can include any kind of other conditions, the way the Macaroons people do. In that case, I guess the only difference is that Macaroons uses signing, and this proposal uses hashing. We have to revoke the tokens delegated from a revoked token. Let's say that Alice revokes the token she gave to Bob. Since we have to compute H(1+r+w+xx2hi5444qatl2) when validating H(1+r+ H(1+r+w+xx2hi5444qatl2)), Carol only has to remember that H(1+r+w+ xx2hi5444qatl2) has been revoked in order to effectively revoke all downstream delegations. Since the list of revoked tokens can grow without bound, we might want to include an expiration time. OK, so what did I get wrong? ________________________ Alan Karp Principal Scientist Enterprise Services, Office of the CTO Hewlett-Packard Company 1501 Page Mill Road Palo Alto, CA 94304 (650) 857-3967, fax (650) 857-7029 http://www.hpl.hp.com/personal/Alan_Karp