Using flat-manager for private app repo

Dan Nicholson nicholson at endlessm.com
Fri May 3 14:38:51 UTC 2019


On Fri, May 3, 2019 at 8:25 AM Alexander Larsson <alexl at redhat.com> wrote:
>
> On Fri, May 3, 2019 at 2:15 PM Dan Nicholson <nicholson at endlessm.com> wrote:
> >
> > Because I believe the CDN signed URLs need to happen in the
> > authorization server or the CDN itself, and neither would have this
> > application specific knowledge.
>
> I guess this depends in general on how flexible the CDN is wrt its
> support of token verification. I was hoping we could avoid doing the
> exact mapping to url ahead of time and just use a signed token that
> represent all urls related to the app, because that is less prone to
> races between the entitlement lookup and the actual ostree pull. But,
> if that is not possible we'd have to generate ahead of time the exact
> list of files that are allowed.

In CloudFront the URL token includes the policy that has the paths, so
you could generate a token that's specific to just the
commit/superblock for the requested ref. In BunnyCDN (the one we're
using now because it's way cheaper), the signed URL token covers the
entire distribution. So, we wouldn't be able to use it except in the
case of a binary access to everything or not.

In Fastly it does look like you could implement this directly in the
CDN with a clever Varnish script.

> > > We do however need to know this. But I don't think you ever need this
> > > full list? Instead what the client does is look at the summary file,
> > > figures out which commit and delta uris to download, and then just
> > > does it, passing in the token the auth server gave it (for this ref)
> > > to every such request. Then the CDN/flat-manager needs to know if this
> > > particular ref requires a token, and if so which token.
> > >
> > > This can happen in two ways:
> > > 1 ) The check happens directly in flat-manager, where it just returns
> > > a 403 error if the token is missing
> > > 2) The check happens in the CDN, but it has no idea initially, so it
> > > proxies the request to flat-manager, and flat-manager knows which/if
> > > any token is needed, and returns the result + a header telling the cdn
> > > which token it needs to apply.
> > >
> > > This is how we support both direct and CDNed access control. Maybe
> > > flat-manager has a known list of CDN ip address sources where it does
> > > 2, and otherwise it does 1. Or maybe the CDN sets some magic secret
> > > when proxying.
> >
> > I don't see how 2 could work generally. If the CDN has an
> > authentication requirement (say, a signed URL), then the CDN will just
> > respond with a 403 if the incoming request isn't appropriately signed.
> > It won't pass the request through to the origin since that would be
> > the opposite of requiring authentication at the edge. I believe the
> > only way this would work would be for the authorization server to know
> > about the CDN authentication scheme and send back tokens that both the
> > CDN and flat-manager understand.
>
> Yeah, looking at the cloudfront signed url things it seems we need to
> know the exact urls. And in fact, we can't use a generic header for
> the entire pull operation but have to use a different one depending on
> which url ostree happened to use (i.e. delta vs commit object). That
> seems to imply that we need to have the entire list of possible signed
> urls, feed it to ostree and have ostree pick the right when doing the
> request.

One way I was thinking about this is that the authorization server
would hand you back the query parameters needed for authorized CDN
access as well as the JWT for flat-manager authorization. Then you
would just tack on the query parameters to all of the URLs in the pull
as well as including the Authorization header. If the CDN then also
passes through the Authorization header, then you're covered in both
cases - the CDN will authenticate the request from the URL and either
return the cached copy or proxy to flat-manager with the Authorization
header.

Unfortunately, adding the query parameters transparently would require
an ostree pull option for that similar to http-headers. It wouldn't be
hard to implement, but it doesn't exist now.

> > Do you have any objection to pulling in the libostree crate in
> > flat-manager. I'd much rather use the ostree API for this kind of
> > stuff than open coding GVariant parsing (bravo to you for that!).
>
> I prefer to have the code pure rust. It makes it much easier to build
> and deploy. I think most of the GVariant parsing code required is
> there already, and I can fill out the rest as needed. Its really not a
> lot of code.

Except for libpq :P. Yeah, I guess if we're not walking the repo and
just parsing a commit object is not too bad. I've just never had a
desire to manually parse GVariants.

> > > 3) Support in flat-manager to optionally verify ref binding vs the
> > > token (this should probably use a separate secret from the one used
> > > for auth:ing the build APIs, and probably a different, simpler token
> > > format).
> >
> > I don't think you really need a separate secret - just because you
> > used it to generate 2 different types of tokens, the risk of losing
> > them is the same. But I don't think coming up with a token format
> > specifically for this use case is best.
>
> But you have to put the secret on the entitlement machine, so that it
> can sign the tokens. Having this secret on two machines seems more
> risky to me.

I mentioned this in an earlier email, but I think you could use the
/token_subset API so that the entitlement server doesn't need the
secret at all. You give it a broad token for the entire repo and then
it requests a subset from flat-manager based on the user's
authorization. That has the advantage that the token format is
primarily maintained in flat-manager. But, yes, if you do need to give
a different secret to the auth/entitlement server, then I think a
separate secret for build vs repo would be desired.


More information about the Flatpak mailing list