Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More robust authentication #59

Closed
itaysk opened this issue Mar 6, 2018 · 15 comments
Closed

More robust authentication #59

itaysk opened this issue Mar 6, 2018 · 15 comments

Comments

@itaysk
Copy link

itaysk commented Mar 6, 2018

Currently the Helm repo standard is to use anonymous HTTP or HTTP Basic authentication. This is a proposal to support a more robust authentication scheme with Chart Museum. Hopefully it will be embraced by Helm. If it won't, it still shouldn't affect Chart Museum's compliance with the Helm repo standard since this is an additional functionality on top of the standard functionality.

This was originated from the discussion around Multi-tenancy to Chart Museum, but it's a good feature for single-tenant users also hence this issue to kick-off this discussion as well.

OAuth/JWT clarification:
OAuth2 is the common protocol for API authorization. It defines a set of scenarios (flows) that each describe how the client, server (resource server) and authorization server can work together to allow a client application to obtain an access token to some protected resources. The result of this auth dance is a token which the client can use for accessing the resources. The most common type of token is JWT, which is basically a signed JSON document with an agreed upon schema. When a user gets hold of a valid JWT (by following OAuth2, or by any other means), they will present it to the server which will validate the token, after which point the request is authenticated, and may proceed to making authorization decisions which are out of scope for now.

Chart Museum is a server that hosts charts. In OAuth2 lingo it is a resource server which rely on some other party to issue tokens. If we look at Docker Registry for reference, it seem to take similar approach of promoting OAuth2, but the open registry implementation (distribution) does not implement the entire flow (at least not as part of core), it expects the token to be issued by another component.

Taking this approach has the following benefits:

  • Doesn't require a database (as requested by early adopters) but make it optional
  • Cleanly integrate into hosting environments
  • Leverage existing OAuth/JWT frameworks

To implement this, Chart Museum needs to accept JWT token:

  • bootstrap CM using certain configuration like: trusted authorization server URL, valid signing keys, etc
  • add a middleware that will enforce auth
  • extract the token from the Authorization header
  • validate the token
  • examine allowed actions for this token (scopes)
  • allow/disallow the request (disallow should return 401 with information on the required authentication)

References:

@jdolitsky
Copy link
Contributor

@itaysk thanks for the detailed set of requirements!

@liamawhite @SlickNik do you have anything to add here?

@jdolitsky
Copy link
Contributor

@technosophos @bacongobbler @mattfarina @jzelinskie

Hopefully it will be embraced by Helm. If it won't, it still shouldn't affect Chart Museum's compliance with the Helm repo standard since this is an additional functionality on top of the standard functionality.

Lets align this with the Helm 3 repo proposals as they relate to auth

@bacongobbler
Copy link
Member

bacongobbler commented Mar 6, 2018

Just adding a fly-by comment, but assuming that this is adding additional functionality and not removing (or amending) the existing client/repo auth model for Helm, this could be tackled in core during the Helm 2.0 timeline. It doesn't have to be punted down the line to Helm 3. :)

Definitely agree that we should probably visit this proposal when we come to Helm 3 repo discussions.

@jdolitsky
Copy link
Contributor

Like where your heads at!

@SlickNik
Copy link
Member

SlickNik commented Mar 8, 2018

This is all great stuff -- thanks for kicking off the discussion @itaysk and @jdolitsky! I agree that following a similar model to docker/distribution makes sense in this regard. In addition to this, one thing that would be good to flesh out is the scheme and grammar for supported resource scopes.

There is some good documentation about the scopes supported by the docker registry at https://github.com/docker/distribution/blob/master/docs/spec/auth/scope.md -- this would be a good starting point to have the discussion around what resource scopes we should support / enforce in ChartMuseum.

@jzelinskie
Copy link

Let's not forget OCI: the distribution protocol for OCI is in a proposal state. I haven't gone over it enough to know what it carves out around auth, but the closer we can map to that, the better.

@jdolitsky
Copy link
Contributor

@jzelinskie yes, please link that here

@jzelinskie
Copy link

Here's the proposal: opencontainers/tob#35

@subesokun
Copy link

Any progress on that feature? I'd really require it as I'm currently working with a requirements.yaml file in combination with basic auth for authentication against chart museum. This has the ugly side effect that in the requirements.lock file the basic auth credentials are visible in clear text and hence I can't (shouldn't) put this file under version control so I can't lock my dependencies 😔

@subesokun
Copy link

I was giving this issues some more thoughts. I know this is not so much related to chart museum itself but it would be great if helm would provide a login mechanism similar to Azure or other big players.

  • Users can simply login by calling helm login <repo> without passing explicitly any password or user via OAuth2.
  • As OAuth2 requires user interaction this login mechanism won't work for CI/CD. Hence in addition something like a repository principal would be required so that automated CI/CD jobs can login none interactively via helm login -u principalname -p principalpasswd <repo>

This would allow the complete removal of any credentials or tokens from the URLs as the client keeps the access token and could include it into each request towards the repository.

https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli?view=azure-cli-latest

@jdolitsky
Copy link
Contributor

@mattfarina ^^^

@subesokun you are definitely on the right track with this. If you have a solid proposal for how this should work in Helm 3, please open an new PR w/ proposal here: https://github.com/helm/community/tree/master/helm-v3

To solve your basic auth problem short term, I believe that since Helm 2.9, you can add a repo with the --username/--password flags, then in your requirements.yaml you can simply refer to the repository by name instead of url:

helm repo add myrepo https://myrepo.com --username=user --password=pass
dependencies:
- name: myapp
  version: 1.0.0
  repository: '@myrepo'

@subesokun
Copy link

@jdolitsky Thanks a lot for the hint! I've tested it and indeed the helm repo update command could successfully pull the metadatas from my private repository. But unfortunately if I run a helm dependency build . then this command fails with a 401 unauthorized error and hence helm can't fetch the tar.gz archives.

Regarding the Helm 3 proposals, sure I'll try to add my ideas there :)

This was referenced Jul 16, 2018
@joejulian
Copy link

Has anyone considered just running oauth2_proxy as a sidecar to provide authentication?

@subesokun
Copy link

@joejulian I've considered this but to the time I've evaluated oauth2_proxy it didn't support passing in OAuth Bearer Tokens, I think this was the related issue bitly/oauth2_proxy#530. Furthermore the Helm client would need to be able to fetch such token (e.g. via a helm login command) and inject it in every request.

@jdolitsky
Copy link
Contributor

Hi all, this work is finally underway (thank you @zachpuck)

The "latest" ChartMuseum image can now be configured with public key to verify JWT tokens. It does not yet inspect the claims to check for specific allowed actions etc.

Please see this example repo of how this can be used today:

https://github.com/chartmuseum/auth-server-example

The way to configure ChartMuseum to use this new functionality is like so:

docker pull chartmuseum/chartmuseum:latest

docker run --rm -it \
  -v $(pwd)/config:/config:ro \
  -e DEBUG=1 \
  -e STORAGE=local \
  -e STORAGE_LOCAL_ROOTDIR=/charts \
  -e BEARER_AUTH=1 \
  -e AUTH_REALM=https://localhost:5001/auth \
  -e AUTH_SERVICE=chartmuseum \
  -e AUTH_ISSUER=auth-server-example \
  -e AUTH_CERT_PATH=/config/server.pem \
  chartmuseum/chartmuseum:latest

where ./config directory contains a public key server.pem that matches the private key used to sign the JWT token provided by auth server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants