Entitlement server and protected repos support

Alexander Larsson alexl at redhat.com
Thu May 23 07:19:06 UTC 2019


On Thu, May 23, 2019 at 12:56 AM Damián Nohales <damian at endlessm.com> wrote:
>
> Hello there,
>
> I'm Damián from Endless, we are implementing a private repo support
> for Flatpak and friends with the objective to have a generic way of
> supporting purchases and things like that, Dan Nicholson already
> talked to you about the flat-manager part of this project [1].
>
> I'm working on the Flatpak side of things and I want to make I'm
> getting peer review of the approach, so this makes it to upstream.
>
> The idea is that, before pulling a ref from a private remote, Flatpak
> requests to a special server a token to then be used in the subsequent
> commits/superblocks/etc requests to the repo, somehow then, the repo
> CDN and flat-manager will deal with the verification of that token to
> send the objects, as we discussed in the other thread.
>
> I was planning to add a new remote option called
> xa.entitlements-server-url or xa.auth-server-url (for some reason, we
> are struggling on deciding the name of the option :) ) with the base
> URL of the special server for which we have a WIP implementation
> called flatpak-entitlements-server.
>
> So, the steps are:
>
> 1. A ref is about to be pulled (repo_pull is called).
> 2. Before calling ostree_repo_pull_with_options, we get a token from
> the entitlements server (if configured) usable to download just the
> ref_to_fetch that expires in a short period of time .
> 3. We set the token in http-headers pull option as a Bearer token
> Authorization header.
> 4. We call ostree_repo_pull_with_options with the pull options.
>
> Then we have the P2P case:
>
> 1. A ref is about to be pulled (repo_pull is called).
> 2. The P2P code path is used (we have a collection_id)
> 3. ostree_repo_find_remotes_async is called
> 4. For each finder result, we set a new "OstreeRepoFinderResult {
> GVariant *options }" field that will override the common
> ostree_repo_pull_from_remotes_async's options argument. That new field
> is populated with the Bearer token in the http-headers field of the
> finder result option.
> 5. ostree_repo_pull_from_remotes_async will use the options specific
> to the remote to fetch the objects.

I think this will do the right thing for the actual upstream remote.
However, the p2p case is interesting, because what does it even mean
in terms of a private repo? What ensures that some random p2p node
doesn't give you the commits even without the bearer token? Maybe that
node did do an authenticated download, and now its just another commit
in the local repo that it is being nice to the peers on the local
network by giving out.

I guess nothing really technicallty disallows a node from ignoring
that some app should not be freely downloadable, but at the very least
we should have some kind of idea how a "proper" p2p node should handle
this.

> The only thing I cannot see integrating well to upstream is the
> mechanism to get the credentials to talk to the entitlements server.
> In our specific case, these credentials lives in the user's keychain,
> so it's fetched using libsecret and an Endless specific SecretSchema.
>
> So maybe we can create some sort of entitlements-server credentials
> providers that are dynamically loaded as plugins so each distro can
> provide their own .so files with the specific implementations?

Yeah, this is really the crux. Once we have a token everything is
pretty simple, but getting the token fundamentally depends on details
about the authentication system used by the particular system.

On a system like Endless (or even RHEL) your host OS would already
have some kind of entilement which is kept up-to date by the OS
itself. This could easily be passed by flatpak to a http API with some
standard API, which returns the token you would use for the pull.

I imagine the for each remote you configure a url to the authenticator
service, and a path name to the entitlement (or alternatively a
commandline you run to generate the entilement). Then flatpak would
load/run this, and send the extracted entitlement data to the
configured url. Flatpak wouldn't need to understand the entitlement
data, it would just forward it, and while the API is generic the
backend is specific and will know the entitlement format.

However, that only works because there is some kind of constantly
running entitlement system. What about systems that don't do this.
Consider for instance if steam was using flatpak, and you ran flatpak
update. How would it know to pass the steam username and password to
the steam auth server? I wonder if we can define a standardized
interactive way to solve this. This sounds *exactly* like OAuth2, so
maybe we can use that? Like, have a standardized API in libflatpak
that allows the client to implement oauth for the authentication
stuff. I mean, it would mean having the client having to render a
webpage for the login, but in practice you just take a dep on some
webkit thing.

I wonder if oauth is flexible enough to handle the pre-entitled case
too. Then Oauth2 could be the standardized authorization API for both
of these cases.

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


More information about the Flatpak mailing list