docker_auth

repository·main·Indexed 23 days ago

https://github.com/cesanta/docker_auth

A Docker Registry 2 authentication server implementing the official token-based authentication and authorization protocol. It provides fine-grained access control (ACL) and supports multiple authentication methods including static users, Google, GitHub, GitLab, LDAP, MongoDB, and SQL databases (MySQL, PostgreSQL, SQLite). The project includes an auth_server package and a Helm chart for Kubernetes deployment.

Tokens
6.3K
Snippets
20
Records
33
Agent score
80%

What's inside docker_auth

  1. What is docker_auth?

    main

    docker_auth is an implementation of the Docker Registry 2.0 token-based authentication and authorization protocol. It fills the gap in the Docker Registry ecosystem by providing a dedicated server to generate authentication tokens and manage fine-grained access control (ACL).

    It supports various authentication and authorization methods, including:

    Authentication Methods:

    • Static list of users
    • Google Sign-In (including Google for Work / GApps)
    • GitHub Sign-In
    • GitLab Sign-In
    • LDAP bind
    • MongoDB user collection
    • SQL databases (MySQL/MariaDB, PostgreSQL, SQLite)
    • External programs

    Authorization Methods:

    • Static ACL
    • MongoDB-backed ACL
    • SQL-backed ACL (MySQL/MariaDB, PostgreSQL, SQLite)
    • External programs
  2. Match multiple labels in a single ACL rule

    main

    You can use multiple label placeholders within a single match field. When doing so, the server tests all possible combinations of the labels provided.

    Warning: The number of combinations grows rapidly as you add more placeholders. For example, using 3 labels with 2 values each results in $2^3 = 8$ combinations. It is recommended to limit multiple label matching whenever possible to maintain performance.

    {
      "match": { "name": "${labels:project}/${labels:group}-${labels:tier}" },
      "actions": [ "push", "pull" ],
      "comment": "Contrived multiple label match rule"
    }
  3. Configure ACL backend in MongoDB

    main

    Access Control Lists (ACLs) can be stored in MongoDB to allow external management. Each ACL document must include a seq field, which is a required unique integer used to enforce a reliable processing order (since MongoDB does not guarantee natural sorting by default). Documents missing the seq key will be excluded.

    ACL documents support:

    • match: Criteria for the rule (e.g., account, name, or labels). Supports regular expressions and placeholders like ${account} or ${labels:group}.
    • actions: An array of permitted actions (e.g., ["push", "pull"] or ["*"]).
    • comment: A descriptive string.
    • seq: A required unique integer for ordering.
    {"seq": 10, "match" : {"account" : "admin"}, "actions" : ["*"], "comment" : "Admin has full access to everything."}
  4. Use label placeholders in ACL matches

    main

    Labels allow you to reduce the number of Access Control Lists (ACLs) required in large installations by using placeholders in match fields. This feature is currently only supported when using Static Authentication or Mongo Authentication.

    To use a label in an ACL, use the syntax ${labels:LABEL_NAME}. The server will attempt to match the requested resource against the values assigned to that label in the user's record.

    Single label matching is efficient and is tested in the order the labels are listed in the user record.

    {
      "match": { "name": "${labels:project}/*" },
      "actions": [ "push", "pull" ],
      "comment": "Users can push to any project they are assigned to"
    }
  5. Import reference ACLs into MongoDB

    main

    To import a set of reference ACLs into your MongoDB instance, follow these steps:

    1. Start MongoDB: If not already running, start a MongoDB container:

      docker run --name mongo-acl -d mongo

      Wait for the logs to show waiting for connections on port 27017.

    2. Install mongoimport: On Ubuntu, install the client tools using:

      sudo apt-get install mongodb-clients
    3. Execute Import: Use mongoimport to load your JSON file into the docker_auth database and acl collection. Ensure your JSON file contains one document per line.

    Note: Each document in your JSON file must span exactly one line for mongoimport to process it correctly.

    MONGO_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongo-acl)
    mongoimport --host $MONGO_IP --db docker_auth --collection acl < reference_acl.json
  6. Implement user-based access control using labels

    main

    To minimize the number of ACLs, you can define generic ACL rules that reference specific label keys, and then control access by managing the values within those labels in the user's record. This approach works best with dynamic authentication methods like mongo or ext_auth (supported since v1.3).

    Workflow:

    1. Define ACLs that match specific label keys (e.g., full-access or read-only-access).
    2. Assign resource patterns (e.g., test/*) to those labels in the user's profile.
    3. Grant or revoke access by adding or removing patterns from the user's label lists.
    # ACL Configuration
    - match: {name: "${labels:full-access}"}
      actions: ["*"]
    - match: {name: "${labels:read-only-access}"}
      actions: ["pull"]
    // User Record
    {
        "username" : "test-user",
        "labels" : {
            "full-access" : [
                "test/*"
            ],
            "read-only-access" : [
                "prod/*"
            ]
        }
    }
  7. Configure Github OAuth authentication

    main

    To use Github for authentication, you must first create a Github OAuth Application.

    Set the Callback URL in your Github application settings to: $fqdn:5001/github_auth

    • Replace $fqdn with the domain where docker_auth is hosted.
    • Replace 5001 with the port specified in your server configuration block.

    After setting up the Github application, add a github_auth block to your docker_auth configuration file.

    github_auth:
      organization: "my-org-name"
      client_id: "..."
      client_secret: "..." # or client_secret_file
      level_token_db:
        path: /data/tokens.db
        # Optional token hash cost for bcrypt hashing
        # token_hash_cost: 5
  8. Generate self-signed certificates for docker_auth

    main

    If you are not using an existing certificate provider, you can generate self-signed certificates using OpenSSL. These can then be base64 encoded and provided to the Helm chart via secret.data.server.certificate and secret.data.server.key.

    openssl req -new -newkey rsa:4096 -days 5000 -nodes -x509 \
        -subj "/C=DE/ST=BW/L=Mannheim/O=ACME/CN=docker-auth" \
        -keyout generated-docker-auth-server.key \
        -out generated-docker-auth-server.pem
    
    CERT_PEM_BASE64=`cat generated-docker-auth-server.pem | base64`
    CERT_KEY_BASE64=`cat generated-docker-auth-server.key | base64`
    openssl req -new -newkey rsa:4096 -days 5000 -nodes -x509 \
        -subj "/C=DE/ST=BW/L=Mannheim/O=ACME/CN=docker-auth" \
        -keyout generated-docker-auth-server.key \
        -out generated-docker-auth-server.pem
    
    CERT_PEM_BASE64=`cat generated-docker-auth-server.pem | base64`
    CERT_KEY_BASE64=`cat generated-docker-auth-server.key | base64`
  9. Build the auth_server local Docker image

    main

    To build the auth_server Docker image locally, you must first clone the repository into a Go workspace structure and then use the make command within the auth_server directory. This process requires git and make to be installed on your system.

    mkdir -p /var/tmp/go/src/github.com/cesanta
    cd /var/tmp/go/src/github.com/cesanta
    git clone https://github.com/cesanta/docker_auth.git
    cd docker_auth/auth_server
    make docker-build
  10. Integrate docker_auth with a Docker Registry

    main

    To use docker_auth as the authentication backend for a Docker Registry, the registry must be configured to point to the docker_auth realm.

    Important: The issuer field in the registry configuration must match the configmap.data.token.issuer value defined in your Helm deployment.

    Example Registry configuration:

    auth:
      token:
        realm: https://docker-auth.example.com/auth
        service: token-service
        issuer: docker-auth-prod
        rootcertbundle: /path/to/docker-auth.crt
    auth:
      token:
        realm: https://docker-auth.example.com/auth
        service: token-service
        issuer: docker-auth-prod
        rootcertbundle: /path/to/docker-auth.crt
  11. Install the docker_auth Helm chart

    main

    To deploy docker_auth on Kubernetes, first add the Cesanta Helm repository and update your local cache. You can then perform a basic installation or use a custom values.yaml file for configuration.

    Prerequisites

    • Kubernetes 1.25+
    • Helm 3.0+

    Installation Steps

    1. Add the repository
    helm repo add cesanta https://cesanta.github.io/docker_auth/
    helm repo update
    1. Basic Installation
    helm install my-docker-auth cesanta/docker-auth
    1. Installation with Custom Values
    helm install docker-auth cesanta/docker-auth -f values.yaml
    helm repo add cesanta https://cesanta.github.io/docker_auth/
    helm repo update
    helm install my-docker-auth cesanta/docker-auth