Authentication server for Docker Registry 2

Overview

Docker Registry 2 authentication server

The original Docker Registry server (v1) did not provide any support for authentication or authorization. Access control had to be performed externally, typically by deploying Nginx in the reverse proxy mode with Basic or other type of authentication. While performing simple user authentication is pretty straightforward, performing more fine-grained access control was cumbersome.

Docker Registry 2.0 introduced a new, token-based authentication and authorization protocol, but the server to generate them was not released. Thus, most guides found on the internet still describe a set up with a reverse proxy performing access control.

This server fills the gap and implements the protocol described here.

Supported authentication methods:

  • Static list of users
  • Google Sign-In (incl. Google for Work / GApps for domain) (documented here)
  • Github Sign-In
  • LDAP bind (demo)
  • MongoDB user collection
  • MySQL/MariaDB, PostgreSQL, SQLite database table
  • External program

Supported authorization methods:

  • Static ACL
  • MongoDB-backed ACL
  • MySQL/MariaDB, PostgreSQL, SQLite backed ACL
  • External program

Installation and Examples

Using Helm/Kubernetes

A helm chart is available in the folder chart/docker-auth.

Docker

A public Docker image is available on Docker Hub: cesanta/docker_auth.

Tags available:

  • :edge - bleeding edge, usually works but breaking config changes are possible. You probably do not want to use this in production.
  • :latest - latest tagged release, will line up with :1 tag
  • :1 - the 1.x version, will have fixes, no breaking config changes. Previously known as :stable.
  • :1.x - specific release, see here for the list of current releases.

The binary takes a single argument - path to the config file. If no arguments are given, the Dockerfile defaults to /config/auth_config.yml.

Example command line:

$ docker run \
    --rm -it --name docker_auth -p 5001:5001 \
    -v /path/to/config_dir:/config:ro \
    -v /var/log/docker_auth:/logs \
    cesanta/docker_auth:1 /config/auth_config.yml

See the example config files to get an idea of what is possible.

Troubleshooting

Run with increased verbosity:

docker run ... cesanta/docker_auth:1 --v=2 --alsologtostderr /config/auth_config.yml

Contributing

Bug reports, feature requests and pull requests (for small fixes) are welcome. If you require larger changes, please file an issue. We cannot guarantee response but will do our best to address them.

Licensing

Copyright 2015 Cesanta Software Ltd.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at

   https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Issues
  • Add GitHub authn provider

    Add GitHub authn provider

    ~~This is not fully functional yet in my tests…~~

    • [ ] the login on HTTPS (same as Google authn) works and stores the token in the DB.
    • [ ] the auth request calls Authenticate() which returns the token from the DB, but somehow authentication fails at this point

    ~~Because GitHub tokens do not expire, I am currently just storing it forever. We might want to set a static expiration time in config though.~~


    This change is Reviewable

    opened by raphink 51
  • Add MongoDB backend for ACLs

    Add MongoDB backend for ACLs

    This adds the ability to store ACLs in a MongoDB database. There's also a documentation file in docs/ACL_Backend_MongoDB.md that explains the document layout inside MongoDB.

    See also #38 for the initial discussion on this topic.

    Review on Reviewable

    opened by kwk 45
  • auth-server not connecting to secure mongodb replicated cluster

    auth-server not connecting to secure mongodb replicated cluster

    Configured the auth-server same as the example with details modified to connect to my replicated mongodb cluster, we are seeing the following error,

    Failed to create auth server: not authorized for query on dockdb.auth
    {"log":"F0302 15:49:50.027015       1 main.go:46] Failed to create auth server: not authorized for query on
    

    The mongodb cluster has internal authentication and my other java app is able to connect to the same without issues using the credentials, unable to do that through docker-auth.

    Anyone has any experience with mongo auth ?

    opened by mv012004 37
  • Add optional sort_keys field for ACLs.

    Add optional sort_keys field for ACLs.

    Without this you are often forced to delete/recreate records to manipulate natural ordering which is not feasible in large deployments.

    Example results from my dataset:

    Given: sort_keys: ["priority", "Comment"]

    Natural order:

    [
        {"Match":{"account":"admin"},"Actions":["*"],"Comment":"Priority 2"}
        {"Match":{"account":"/.+/","name":"${account}/*"},"Actions":["*"],"Comment":"Priority 1"}
        {"Match":{"account":"/.+/","name":"${account}/*"},"Actions":["*"],"Comment":"Apriority 1"}
        {"Match":{"account":"/.+/","name":"${account}/*"},"Actions":["*"],"Comment":"priority none"}
        {"Match":{"account":"admin"},"Actions":["*"],"Comment":"APriority 0"}
    ]
    

    Sorted order:

    [
        {"Match":{"account":"/.+/","name":"${account}/*"},"Actions":["*"],"Comment":"priority none"} 
        {"Match":{"account":"admin"},"Actions":["*"],"Comment":"APriority 0"} 
        {"Match":{"account":"/.+/","name":"${account}/*"},"Actions":["*"],"Comment":"Apriority 1"} 
        {"Match":{"account":"/.+/","name":"${account}/*"},"Actions":["*"],"Comment":"Priority 1"} 
        {"Match":{"account":"admin"},"Actions":["*"],"Comment":"Priority 2"}
    ]
    

    Note that mongo will continue to work as it used to without sort_keys defined so this won't change anything for existing users. It's a fully-optional feature add. It will also work even if some or all documents are missing the given keys so it's very robust.

    Full dataset dump from mongo for reference:

    /* 1 */
    {
        "_id" : ObjectId("5668ba739f2e3d0001a9af59"),
        "comment" : "Priority 2",
        "actions" : [ 
            "*"
        ],
        "match" : {
            "account" : "admin"
        },
        "priority" : 2
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5668ba739f2e3d0001a9af5d"),
        "comment" : "Priority 1",
        "actions" : [ 
            "*"
        ],
        "match" : {
            "account" : "/.+/",
            "name" : "${account}/*"
        },
        "priority" : 1
    }
    
    /* 3 */
    {
        "_id" : ObjectId("5671e9d1f62858550879b8bc"),
        "comment" : "Apriority 1",
        "actions" : [ 
            "*"
        ],
        "match" : {
            "account" : "/.+/",
            "name" : "${account}/*"
        },
        "priority" : 1
    }
    
    /* 4 */
    {
        "_id" : ObjectId("5671ea04f62858550879b8bd"),
        "comment" : "priority none",
        "actions" : [ 
            "*"
        ],
        "match" : {
            "account" : "/.+/",
            "name" : "${account}/*"
        }
    }
    
    /* 5 */
    {
        "_id" : ObjectId("5671eaa2f62858550879b8be"),
        "comment" : "APriority 0",
        "actions" : [ 
            "*"
        ],
        "match" : {
            "account" : "admin"
        },
        "priority" : 0
    }
    

    Review on Reviewable

    opened by carsonoid 31
  • Can no longer pull with docker 1.8.1 if the user only has pull access

    Can no longer pull with docker 1.8.1 if the user only has pull access

    see

    https://github.com/docker/docker/issues/15640

    I guess it's supposed to return the token with the appropriate rights and it's the registries responsibility to deny access.

    Which makes since from an SSO kind of implementation with a JWT.

    in 1.8.1 docker is requesting push and pull for just a pull, not sure why they changed that.

    opened by silverbp 30
  • Pattern matching for

    Pattern matching for "name"?

    A very common pattern is to allow anyone to access their own named repository. Thus, if I can successfully authenticate as "jimd", then I should be able to access a repo that is at jimd/.

    The current config (seems) not to support it. It should be fairly simple to do the following, though:

    acl:
      # All logged in users can access their own images 
      - match: {account: "/^(.+)$/", name: "/^\1\/*"}
        actions: ["*]
      # alternate pattern, depending on your regexp engine
      - match: {account: "/^(.+)$/", name: "/^\$1\/*"}
        actions: ["*]
    
    opened by deitch 19
  • Add a Redis-based token storage implementation

    Add a Redis-based token storage implementation

    This pull request adds a new type, redisTokenDB, which implements a token storage based on Redis.

    The primary motivation is to allow the authentication server to run in a distributed environments, with multiple instances of the server proxied by a load balancer. The default file-based implementation is insufficient in such a scenario, because each server would have its own database of tokens, and the Google Cloud Storage-based implementation is prohibitive when the service would run eg. on AWS, due to latency issues.

    The Redis-based implementation can work with a single Redis instance or a Redis Cluster — the corresponding client is selected based on the YAML configuration, where the user provides either a single url value as a string, or one or more urls as an array of strings (see the updated reference.yml file).

    The Redis-based implementation adds two additional functions, Encrypt() and Decrypt(), which allow to encrypt the values before storing them, using the AES support in Go standard library, when the encrypt_key is set in the YAML configuration (again, see the updated reference.yml file).

    The pull request also adds support for using the Redis-bases token storage in the Github authentication mechanism (authn/github_auth.go).


    This change is Reviewable

    opened by karmi 18
  • Map LDAP account attributes to labels such as groups #63

    Map LDAP account attributes to labels such as groups #63

    Updated:

    I am proposing a configurable structure to leverage ldap account attributes as labels for access control. Let me know what you think.

    I have added a labels mapping to the configuration, for example:

    ldap_auth:
      ...
      filter: (&(|(userPrincipalName=${account})(userPrincipalName=${account}@example.com)(mail=${account}))(objectClass=person))
      labels:
        groups:
          attribute: memberOf
          parse_cn: true
        title:
          attribute: title
    

    Can then be used with the current labels implementation like so:

     acl:
      - match: {labels: {"title": "Developer"}}
        actions: ["*"]
        comment: "If you call yourself a developer you can do anything."
      - match: {labels: {"groups": "Admin"}}
        actions: ["push"]
        comment: "If you are part of the admin group you can push."	
    

    Using title for an acl is probably a really dumb idea. But it proves you can map arbitary attributes to arbitary labels.

    There is one special option, parse_cn which extracts the common name from a fully qualified value as found in memberOf.

    Original:

    I know little about LDAP and even less GO but I've taken the labels approach in #139 and populated groups to address #63.

      - match: {name: "docker_auth", labels: {"groups": "Admin"}}
        actions: ["*"]
        comment: "Admin users can do anything to docker_auth."
    

    I'm simply looking through the account response for memberOf details. The alternative approach for ldap would be to look up groups and find member accounts.

    A similar approach might be useful for #117


    This change is Reviewable

    opened by kcd83 17
  • auth-server with docker-notary fails with error HTTP 400 response body: invalid character 'B'

    auth-server with docker-notary fails with error HTTP 400 response body: invalid character 'B'

    I have been able to successfully use auth-server with docker registry. Trying to use the same with docker notary and I am seeing following error

    RRO[0000] Could not publish Repository since we could not update: error parsing HTTP 400 response body: invalid character 'B' looking for beginning of value: "Bad request: invalid scope: "repository:xxxxxxxxxxxx:5000/golang:push,pull"\n" Failed to sign "xxxxxxxxxxxx:5000/golang":test - error parsing HTTP 400 response body: invalid character 'B' looking for beginning of value: "Bad request: invalid scope: "repository:xxxxxxxxxx:5000/golang:push,pull"\n" error parsing HTTP 400 response body: invalid character 'B' looking for beginning of value: "Bad request: invalid scope: "repository:xxxxxxxxxxxx:5000/golang:push,pull"\n"

    This happens once I import the auth-server certificate at my docker client end. This is done to establish a trust between auth-server and my docker client host.

    opened by ashishjain14 15
  • Add authorization based on Github teams

    Add authorization based on Github teams

    This pull request improves the Github authentication workflow, and adds authorization based on user's Github teams.

    The improvements add a visually more appealing "Login with Github" page, and a full HTML page for the result page, in order to show the docker login instructions properly formatted.

    The added fetchTeams() function will retrieve a list of user's Github teams per configured organization. It doesn't fetch any teams if an organization is not set in the YAML configuration, with the assumption that the user of the authentication server wants to use it in some kind of private Docker registry, tied to a specific organization. (Moreover, the team names are not unique across organizations, so ignoring organization would make it danegerously ambiguous. We have considered prepending the organization name to the team name, but it looked like unnecessary complication for the imagined use case). The implementation takes pagination into account, parsing the appropriate response headers.

    The updated doGitHubAuthCreateToken() function will call the fetchTeams() function, and store the array of team names in the Labels in the token itself — therefore it relies on the https://github.com/cesanta/docker_auth/pull/217 pull request. The updated Authenticate() function will return the labels, instead of nil, as it originally did.

    This pull request implements the feature request in https://github.com/cesanta/docker_auth/issues/191.


    This change is Reviewable

    opened by karmi 14
  • Mongo authn

    Mongo authn

    I've expanded the MongoDB support to include a collection for authentication. This includes a refactor of mgo sessions and the associated structs to a separate package. I've also implemented the Copy->Close flow for sessions as recommended in the mgo docs.

    Review on Reviewable

    opened by carsonoid 14
  • Add env variable support for configuration

    Add env variable support for configuration

    https://github.com/cesanta/docker_auth/pull/225 updated to current HEAD

    This commit also makes possible to use json files as configuration files via viper configuration library.

    This PR contains breaking changes on configuration to make configuration overridable by the environment variables. To make it support nested struct overrides struct tags are renamed to not contain any underscore in their names. This is going to break old configuration files.

    Because of viper's limitations of detecting new map keys from env variables, a little procedure goes trough prefixed env variables and override viper settings by the parsed value of them. If the configuration file is in yaml format env variables can contain correct yaml strings and they will be parsed correctly. This behaviour is same for json files too.

    PS: viper doesn't use file format parsers for unmarshalling the structures. It parses files as interface{} and the using mapstructure library to unmarshall structs from maps. This is why yaml struct tags converted to mapstructure ones.

    The original author is @Um

    Tagging @techknowlogick frm the other PR https://github.com/techknowlogick

    opened by ewassef 5
  • How to write a new auth backend?

    How to write a new auth backend?

    I'm currently using an external program for validation and have found the server gets fork bombed when many clients try to authenticate at once. My authentication isn't very sophisticated, the login password is a github personal access token, I call a Github API to see what orgs it belongs to, and if someone in my organization they are authorized. To remedy the fork bomb issue I'd like to just patch in a local auth method at compile time to make the HTTP request. Could someone walk me through what would be required to implement this? I've looked at the other authn modules and its not really clear how they get called, it looks like there is more involved then just dropping in a .go file in that directory.

    opened by zfLQ2qx2 1
  • Chart: Optionally deploy an instance of docker-registry alongside docker_auth

    Chart: Optionally deploy an instance of docker-registry alongside docker_auth

    When the Chart was updated to Helm 3 there was some discussion around integrating docker-registry. The idea was dropped because helm-stable was shut down at the time and docker-registry had not found a new home. Still, documentation and Chart reference the (not functional) integration, which is confusing:

    • the "working example" has registry.enabled=true
    • no clear description on how to configure the registry to link certificate/auth configuration

    In the meantime, the docker-registry chart has been picked up by twuni. While not officially maintained by docker, it is a continuation of the chart in helm-stable and actively maintained.

    Would you take a PR adding optional integration with docker-registry sourced from the chart by @twuni? I believe it makes a lot of sense to be able to manage both docker_auth and the registry in a single chart, and having the integration in the chart would also make it easier to understand how to deploy docker_auth alongside an existing registry.

    opened by jthurner 1
  • Gitlab auth: Restrict access to users from a certain group (organization?)

    Gitlab auth: Restrict access to users from a certain group (organization?)

    I need some help setting up authentication via Gitlab. We had been using docker_auth for a while, but are now moving to Gitlab and would like to use it as authentication backend. Using the example files we managed to setup Gitlab authentication in general. But it only requires users to be authenticated via Gitlab. So every user could access our registry, which is of course not the idea.

    We managed to restrict access to individual users, but not to "groups". I checked the code (not a Go developer, but able to read most of the code) and the Gitlab implementation looks like it has an "organization" feature. But I don't see how checkGitlabOrganization is ever called!?

    Could somebody provide a working example on how to restrict access to a Gitlab group / organization?

    opened by domma 0
  • Support of refresh token?

    Support of refresh token?

    From this feature request #61 and this, it seems refresh token is not yet possible with this project.

    Handling expiration of access token without storing user credential at client side or asking user to enter password repeatedly are the critical benefits from refresh tokens. I really want to know if this is possible on this project for now or in short term?

    Thanks

    opened by lgprobert 0
  • how to assign multiple passwords for a single user in configuration yaml file under static user section ?

    how to assign multiple passwords for a single user in configuration yaml file under static user section ?

    Im using admin static user when im trying to pull in different docker clients will have different passwords for their admin user. could anyone help on this ?

    opened by bj1074 0
Releases(1.9.0)
  • 1.9.0(Dec 7, 2021)

    What's Changed

    • Remove httpdown by @YC in https://github.com/cesanta/docker_auth/pull/325
    • Support Unix Domain Sockets by @YC in https://github.com/cesanta/docker_auth/pull/328

    Full Changelog: https://github.com/cesanta/docker_auth/compare/1.8.1...1.9.0

    Source code(tar.gz)
    Source code(zip)
  • 1.8.1(Nov 25, 2021)

    Align GitLab and GitHub signing pages

    What's Changed

    • bugfix: Added sign-in link under gitlab page template by @alekseiapa in https://github.com/cesanta/docker_auth/pull/323

    Full Changelog: https://github.com/cesanta/docker_auth/compare/1.8.0...1.8.1

    Source code(tar.gz)
    Source code(zip)
  • 1.8.0(Oct 4, 2021)

  • 1.7.1(Jul 8, 2021)

  • 1.7.0(Mar 7, 2021)

    Note: Version 1.6.0 was tagged as docker image, but no corresponding git tag was made. This is reason for jump from 1.5 to 1.7

    This release includes:

    • Casbin support
    • Storing Authn & Authz data in a relational database
    • CI Builds for testing pull requests
    • Cross-platform docker images (you can now run docker image on a raspberrypi)
    • Helm chart for installing on a kubernetes cluster
    • Code cleanup
    • And much more!
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(Dec 30, 2019)

    • plugin_authn/authz: SHared object authn/authz for more efficient extensibility (https://github.com/cesanta/docker_auth/commit/bfb15170322adfa5681480a4767cdca4a463e78).
    • Additional TLS configuration options - cipher suites and curve preferences (https://github.com/cesanta/docker_auth/commit/3fb13f1d7eb9bbe0285c3877ed1938e39609e1af).
    • Better OAuth compatibility - support user/password in POST form data and use access_token field.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Apr 12, 2018)

    • Stop quoting meta chars in labels
    • Set custom CA certificate for ldap cert verification
    • Fix Static labels and document supported backends
    • Allow MongoDB connections to use TLS
    • Pass cache dir to the LetsEncrypt manager

    https://github.com/cesanta/docker_auth/compare/1.3...1.3.1

    cesanta/docker_auth:1.3
    cesanta/docker_auth:1.3.1
    
    Source code(tar.gz)
    Source code(zip)
  • 1.3(Sep 15, 2017)

    • Support for LetsEncrypt - automatically acquire and renew certificates
    • Fix non-TLS listener
    • New config option, server.path_prefix: /auth becomes /prefix/auth, etc (@alonbl)
    • Label support for Mongo authn (@carsonoid)
    • Label placeholder matching for ACLs (@carsonoid)
    • GitHub authn: Request read:org scope to be able to check if user is a member of an organization or not (@mgenov)
    • GitHub authn: Google Cloud storage option for tokens (@mgenov)
    cesanta/docker_auth:1.3
    
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Apr 19, 2017)

  • 1.2(Dec 23, 2016)

  • 1.0(Jul 1, 2016)

Owner
Cesanta Software
Embedded Communication
Cesanta Software
Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Paul Greenberg 372 May 15, 2022
A simple passwordless authentication middleware that uses only email as the authentication provider

email auth A simple passwordless authentication middleware that uses only email as the authentication provider. Motivation I wanted to restrict access

Miroslav Šedivý 4 Jan 31, 2022
Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Dinesh Bhattarai 0 Jan 30, 2022
HTTP-server-with-auth# HTTP Server With Authentication

HTTP-server-with-auth# HTTP Server With Authentication Introduction You are to use gin framework package and concurrency in golang and jwt-go to imple

Saba Sahban 12 May 12, 2022
GLAuth 1.4k May 16, 2022
Server bridging Google's OAuth and service using Radius for authentication

Fringe Fringe is an easy workaround for Google Workplace users who need a Radius server to perform authentication on behalf of other services (e.g. 80

Pierre-Luc Simard 5 Mar 7, 2022
Example of a simple application which is powered by a third-party oAuth 2.0 server for it's authentication / authorization. Written in Golang.

go mod init github.com/bartmika/osin-thirdparty-example go get github.com/spf13/cobra go get github.com/openshift/osin go get github.com/openshift/osi

Bartlomiej Mika 0 Jan 4, 2022
Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to create powerful modern API and web authentication.

❗ Cache package has been moved to libcache repository Go-Guardian Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to

Sanad Haj Yahya 366 May 14, 2022
Go login handlers for authentication providers (OAuth1, OAuth2)

gologin Package gologin provides chainable login http.Handler's for Google, Github, Twitter, Facebook, Bitbucket, Tumblr, or any OAuth1 or OAuth2 auth

Dalton Hubble 1.5k May 4, 2022
Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applications.

Goth: Multi-Provider Authentication for Go Package goth provides a simple, clean, and idiomatic way to write authentication packages for Go web applic

Mark Bates 3.7k May 16, 2022
HTTP Authentication middlewares

goji/httpauth httpauth currently provides HTTP Basic Authentication middleware for Go. It is compatible with Go's own net/http, goji, Gin & anything t

Goji 213 Dec 15, 2021
[DEPRECATED] Go package authcookie implements creation and verification of signed authentication cookies.

Package authcookie import "github.com/dchest/authcookie" Package authcookie implements creation and verification of signed authentication cookies. Co

Dmitry Chestnykh 112 Nov 19, 2021
Basic and Digest HTTP Authentication for golang http

HTTP Authentication implementation in Go This is an implementation of HTTP Basic and HTTP Digest authentication in Go language. It is designed as a si

Lev Shamardin 516 May 9, 2022
Herbert Fischer 196 Nov 17, 2021
Go (lang) HTTP session authentication

Go Session Authentication See git tags/releases for information about potentially breaking change. This package uses the Gorilla web toolkit's session

Cameron Little 221 Apr 7, 2022
A reverse proxy that provides authentication with Google, Github or other providers.

A reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain or group.

OAuth2 Proxy 5.2k May 15, 2022
A reverse proxy that provides authentication with Google, Github or other providers.

A reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain

OAuth2 Proxy 5.2k May 17, 2022
Authentication service that keeps you in control without forcing you to be an expert in web security.

Authentication service that keeps you in control without forcing you to be an expert in web security.

Keratin 1.1k Apr 30, 2022
An authentication proxy for Google Cloud managed databases

db-auth-gateway An authentication proxy for Google Cloud managed databases. Based on the ideas of cloudsql-proxy but intended to be run as a standalon

null 24 Apr 6, 2022