Macaroon granularity

71 views
Skip to first unread message

Jonathan Rudenberg

unread,
Dec 12, 2015, 5:03:15 PM12/12/15
to maca...@googlegroups.com
I’m designing a macaroon-based authorization system for a standard REST-style API, and I was wondering where others have landed on the granularity of individual macaroons.

The API server will not care about policies for individual users, it will rely on the service that is discharging authentication caveats to enforce policy via capabilities in the form of additional caveats when issuing discharges.

The question then becomes how granular the individual macaroons should be.

One extreme is for the API to issue a single macaroon with no scoping and then have the authentication service load up *all* of the capabilities for a given user into the discharge caveats. I’m not convinced this is a great idea, but the only major flaw I can see is that the macaroon bundle will be bloated with extra caveats that are irrelevant for any individual request.

The other option under consideration is to have a macaroon per “endpoint” like /widgets/:id, and the authentication service would then add caveats like the ability to read/write and the specific widget ids, and other filters like owner ids, group ids, etc. that are allowed. The main downside here is that the client will have to do a discharge dance with the authentication server(s) before requests to new unique endpoints and after timestamps expire and so on, so there could be more of a latency hit than front-loading all of the capabilities into a single macaroon.

Another option would be object-centric macaroons which is even more granular, it seems like the authentication service would become even more aware of object schemas in this case.

How are you handling this? Am I thinking about anything from the wrong perspective?

Thanks,

Jonathan

Robert Escriva

unread,
Dec 12, 2015, 5:40:01 PM12/12/15
to maca...@googlegroups.com
Hi Jonathan,

When thinking of macaroons, think of each macaroon as granting absolute
access to a specific resource. For example, there could be one secret
per profile in a social network.

Once you figure out the resource/secret coupling, the use of caveats
falls out naturally. For example, in the social network example, the
application can take the macaroon for my profile, add the caveats "post
to wall" as a 1st party caveat and "is friends with Robert" as a third
party caveat, and publish this macaroon in a place where every user can
see it. This macaroon is only useful for principals posting to my wall,
and only after they can obtain the third party discharge that they are
friends with me. That discharge can, of course, include further
caveats.

The caveats themselves form the policy to be verified. In your system,
I would assign one macaroon secret per widget. A macaroon minted with
this secret provides complete, unfettered access to the widget. You can
then do things like I described above, and publish a widget that says,
"You can play with this widget" as a first party caveat and "The
authorization system says you are in the 'playful people' group" as a
third party caveat. You could make these available like
/macaroons/widgets/:id/play. Again, there's no need to provide
authorization on these with the third party caveats because the
macaroons are unusable without the discharge.

Done right, you could even prevent the client from contacting the
discharge server to prove it's a member of the 'playful people' group
more than once.

If you want to really change your view on macaroons, you could even
consider a scenario in which macaroons are obtainable only after
presenting other macaroons. For example, in a social network, you could
have one macaroon per image uploaded by users. The owner of an image
has a macaroon with absolute authority over the image. The service
could have a single copy of this macaroon with a read caveat on it
hidden behind a service that requires that you prove yourself to be
logged in and friends with the image owner before retrieving the
image-access macaroon.

-Robert

Jonathan Rudenberg

unread,
Dec 12, 2015, 5:54:06 PM12/12/15
to Robert Escriva, maca...@googlegroups.com

> On Dec 12, 2015, at 5:40 PM, Robert Escriva <rob...@rescrv.net> wrote:
>
> Hi Jonathan,
>
> When thinking of macaroons, think of each macaroon as granting absolute
> access to a specific resource. For example, there could be one secret
> per profile in a social network.

How would a listing endpoint work in this case? Is a list of profiles a separate resource?

Your feedback has been useful, thanks!

Robert Escriva

unread,
Dec 12, 2015, 6:18:02 PM12/12/15
to Jonathan Rudenberg, maca...@googlegroups.com
I would model it as having a "Widget" and a "WidgetSet". Creating a new
Widget requires the appropriate access to the WidgetSet. List would
then be just another operation on that set.

Of course, you should be careful that the "list" doesn't bypass anything
else. Maybe assume that list-access to the WidgetSet implies that you
can see just a unique ID for each widget, and then reading the widget
requires accessing the widget object.

-Robert

roger peppe

unread,
Dec 13, 2015, 4:06:49 PM12/13/15
to maca...@googlegroups.com, Jonathan Rudenberg
I think that list/search functionality is a really interesting question, and one
that I still struggle with somewhat. For example, if I provide a
search endpoint,
how can I guard against providing information that clients shouldn't have?
Even if I send a response which is a just list of ids, the client
knows that there are that
many ids that have satisfied the search criteria, so they've obtained
information
that perhaps I should not be giving away.

Even setting that aside, if I've got a list of 300 results, it doesn't
seem great
to require the client to acquire 300 macaroons and discharge
caveats for all of them in order to see the desired results.

I'm very interested in other possible approaches in this area.

rog.
Reply all
Reply to author
Forward
0 new messages