GopherCon 2018 - An Over-Engineering Disaster with Macaroons
Guillaume J. Charmes for the GopherCon Liveblog
Presenter: Tess Rinearson
Liveblogger: Guillaume J. Charmes
This is a story about cool new technology, over-engineering, and coconut cookies.
Summary
Macaroon is an exciting new technology that promises to solve the authentication/authorization problem.
Tess Rinearson, VP of Engineering at Chain, walk us through the journey of her team about adopting the technology.
An Over-Engineering Disaster with Macaroons
Auth is a common problem
When building a server, auth is a common problem, and by "auth", I mean the twin problem of "who are you", a.k.a. "authentication" and "what can you do" a.k.a. "authorization".
Before Macaroon
When starting, the auth system was using BasicAuth, check that the user/password pair is valid and set the user in the context:
Once the authentication is done, we move on to the authorization. Each route has a "policy", we run the user against that policy to know if the user has access.
This approach seemed quite straightforward, however finding the right approach is not quite that easy.
Capability vs Identity
- Capabilities is directly granting someone the capability to do something specific
- Identity is asking who the entity is and then determining if they’re allowed to do that thing.
Example
As it might be a bit abstract, let's take a look at an example: a Car.
How do we determine if this car can be started? The options are
- Create a Key, anyone with a key can use it: capability based auth system.
- Have the car Ask who the driver is and look it up to check it: identity-based auth system.
But them if we push a little, let's say we need a Valet parking. If we give him the keys, he could, in turn, give them to anyone, even burglars, this is dangerous. On the other hand, we don't know the Valet, so an Identity-based auth system wouldn't work as well.
And worse, relying on identity can be dangerous in any system where there are more then two “principles,” like multiple services.
“The ACL model is unable to make correct access decisions for interactions involving more than two principals, since required information is not retained across message sends.” Tyler Close, ACLs don’t
Identity is not ideal: it often depends on a Deputy to lookup a user, but that Deputy can get confused.
A common case is CSRF: Cross Site Request Forgery which could result in the Deputy to get “confused” and take action on behalf of another actor who doesn't have that authority.
Solution: Create a token unique per session. i.e. increase the security of the Identity system by adding a Capability.
Now, what if something could safely combine the strengths of both the capability and the identity models? What if a bearer token, like our car key, could be attenuated, or limited, in a way that makes it much safer?
Now, if only we could combine the strengths of both world, like having a Bearer token (like our car key) that could be attenuated or limited so it can be much safer.
This would be like we handed the valet a key that Wouldn't work generally, but would work within a one-mile radius, or if the driver was wearing the valet-company uniform or some other set of caveats that are based on the context.
Macaroons
Enters Macaroon. They do exactly that. As the name suggests, from the user perspective, it works like a cookie, but it is a Bearer token, contextually attenuated to limit what it can do.
The Problem
Looking back to basic auth, the problems are:
- user/password required on every request.
- Only Identity based.
The Solution
HMACS is a keyed-hashed message, similar to a hash function, except the output is based on a key. If both parties have the key, then it solves the first problem as we don't need to pass the plaintext login/password each time.
This is nice, it improved authentication but not the authorization to check what the user can do.
Macaroon solves this by adding layers (a.k.a Caveat), chaining HMAC:
Let's take a look at the code:
A Macaroon is quite simple:
Now, we can create out own Macaroon:
And it can easily be authorized:
As the permissions are inside the Macaroon token, no need for extra lookup to identity.
Macaroon can also be used by 3rd party and can be used in similar flow as OAuth for 3rd party support.
Macaroon at Chain
All this seemed very exciting and a great fit for Chain's use case.
The good parts
Ledgerd creates a "golden" macaroon, pass it to the Dashboard who "downgrades" it so it can only do some specific actions.
The transition went quite smoothly and worked quite well... for a while.
The bad parts
- New Availability dependency on Dashboard, i.e. If that comes down, everything goes down.
- Very difficult to use locally. So difficult in fact, we stopped doing it, and the code reflects it.
- Confusing behavior for users.
- Impossible to revoke immediately. The discharge macaroon would not be fetched before 5 minutes. Revokation is hard, and Macaroon doesn't make it easier.
- Tricky format.
- Maybe misnamed?
Eventually, Chain decided to move away from Macaroons.
Removing Macaroon took 5 months while setting up took 2 weeks.
Tried to convert macaroon to new auth, but as it is not stored on the server side, it can't be migrated.
Conclusion
Macaroons are an exciting technology, but it might be too exciting. It is quite young and will improve over time, but the current solution was not the right fit for Chain.