Using flat-manager for private app repo

Alexander Larsson alexl at redhat.com
Tue Apr 30 16:11:39 UTC 2019


On Tue, Apr 30, 2019 at 5:30 PM Dan Nicholson <nicholson at endlessm.com> wrote:
>
> On Tue, Apr 30, 2019 at 8:10 AM Alexander Larsson <alexl at redhat.com> wrote:
> >
> > On Mon, Apr 29, 2019 at 8:46 PM Dan Nicholson <nicholson at endlessm.com> wrote:
> > >
> > > To handle this, an additional "read" subject and scope would be
> > > checked in the JSON web token. The existing repos and prefixes in the
> > > token scheme could be reused. For example, consider a token with the
> > > following payload:
> >
> > However, this is less ideal imho. I don't think we want the repo
> > itself to do the mapping from user -> allowed to download. We want
> > some separation of concerns here.
>
> Maybe I wasn't clear, but this is definitely something I was trying to
> pursue. I don't want the repo-server to know about users at all.
> That's why I was using the claims in the web token the same way that
> the API server is currently using. I left the user field in there
> because that's how the tokens are currently generated, but that field
> is not needed.

Ah, ok.

> > The way I imagine it is that the client goes to an authentication
> > server and says "I'm user $foo, with password (or whatever auth) $bar,
> > please give me a token that allows me to download ref $app". The
> > server then verifies things against the service db and sees that the
> > user should be able to download this. Then it generates a token that
> > says "this client is allowed to download $app until $time="now + 10
> > min" and signs it with a private key that only the auth service knows.
>
> This is the same as what I was envisioning except maybe the last part.
> The way I was thinking about it, the authorization server would have a
> long lived token that had read permissions for everything in a
> particular set of repos. After authenticating the user and determining
> what apps they had access to, it would call the flat-manager
> /token_subset API with a subset of repos and apps the user could
> access. Then the authorization server doesn't need a secret key at
> all. flat-manager hands back a more limited token signed by it's
> secret and the authorization server gives this to the user. Then the
> user uses this token to authenticate to flat-manager and it can
> validate the token. I believe this is exactly how the
> flat-manager-client works right now.

Do you mean one token with everything the user has access to? Seems
like that could end up very large. And anyway, to avoid risk of
leaking such a token we need to time limit it anyway, so generating a
token per download seems to make more sense.

But yeah, I see what you mean. Its basically what happens now except
the current limit is on a per-repo basis, and it would need to be
changed to per-commit or per-ref or something more finegrained. It
means each single download would need to hit the master server though,
which seems like it could be a performance problem. I think we should
try our very best to make it at least possible to move the
authentication to the edge.

> > Then the repo server (like flat-manager) can know that certain (or
> > all) refs require authentication and what signatures are needed to
> > download those files.
>
> I'm not sure what you mean here. How does the repo server know what
> refs require authentication and what the allowed signature are?

All the CDN sees is a download of e.g. 04/232121244.commit. Say the
token says the user is allowed to download "org.cool.Game", and that
is part of the token. How does the CDN match the url being downloaded
to the required token? Well, we could have the upstream flatp-manager
set some http header in the reply (for all apps that require a token),
specifying which tokens are needed. Then the CDN can do the upstream
request once and cache this header, letting future requests be cache
only.

So, something like:

user asks central server for a token for org.cool.Game
user passes token to CDN request
CDN does upstream request, gets back result + header that says "need
org.cool.Game token"
CDN verifies passed token based on header + current time
CDN returns results

On a second call the CDN can use a cached value for the token and
avoid an upstream request.

> > Furthermore, I belive that CDN services like fastly has support for
> > tokens like this. For example, see:
> >
> >   https://docs.fastly.com/guides/tutorials/enabling-url-token-validation
> >
> > This means we can authenticate with the central service, and then
> > download directly from the CDN which validates the token.
>
> That's a very neat feature, but I don't believe this is common in
> CDNs. Neither of the 2 we've used at Endless (CloudFront and BunnyCDN)
> have any edge authentication.

CloudFront seems to have something called private content:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html

Not sure if that is useful here.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                Red Hat, Inc
       alexl at redhat.com         alexander.larsson at gmail.com


More information about the Flatpak mailing list