Registry-Auth
providers authentication and authorization for Docker Registry.
Docker Registry can be configurated with three kinds of authentications:
-
silly which is only appropriate for development. It simply checks for the existence of the Authorization header in the HTTP request. It does not check the header’s value.
-
htpasswd which supports username and password authentication. Docker Registry loads the
htpasswd
config once when startup. The htpasswd only resolves the authentication problem, but can not provide authorizations. -
token which supports authentication and authorization. It takes the
JWT
format including the token's validation period and authorized actions. You can set each repository's accessibilities for users.For example, user
test1
can only pull from repositoryrepo1
, while usertest2
can push and pull from repositoryrepo2
. -
Besides mentioned above, there is a
proxy
authentication method described in Docker's deploying document. Aproxy
will be deployed before the Docker Registry, which can process the authentication.The references about the
proxy
are here:
Registry-auth has implemented the token and the proxy authentication.
The following script will run a simple Registry-Auth and Docker Registry service. It then tests the docker login and pushes and pulls images.
curl https://raw.githubusercontent.com/alauda/registry-auth/main/scripts/quick-start.sh | bash
When using the token authentication, the Registry-Auth and the Docker Registry will use the same x509 certificate to sign and verify the token. The token is signed by the Registry-Auth and will be verified by the Docker Registry.
When the client (such as docker, containerd, etc.) accesses the Docker Registry firstly, the token does not exist in the HTTP headers. The Docker Registry will respond with an authentication fail with status code 401, and the "WWW-Authenticate" header is added in the response, which includes the Registry-Auth's URL.
Then the client will send the username and password to Registry-Auth by the Basic Authorization method for a valid token. The Registry-Auth will check the username and password and also the user's authorized repositories. After all the checks are passed, it will sign a token for the client.
The client then accesses the Docker Registry secondly with the token. And the Docker Registry will respond with the image content after validating the token.
The sequence of token authentication is here:
sequenceDiagram;
participant c as client
participant r as Docker Registry
participant ra as Registry-Auth
c->>+r: request image
r->>-c: 401 with Registry-Auth URL
c->>+ra: request token by username/password
ra->>ra: authenticate and authorize
ra->>-c: response with token
c->>+r: request image with token
r->>r: validate token
r->>-c: response with image
The Registry-Auth's proxy authentication works with token authentication. The Registry-Auth is deployed before the Docker Registry as a proxy, but token authentication is also taken between Registry-Auth and Docker Registry. When using proxy authentication, only one access endpoint is needed, which will simplify the deployment and reduce the client's requests.
When the client access Registry-Auth (also the Docker Registry) with the Basic Authorization header, the Registry-Auth will check the username and password and also the user's authorized repositories, and then sign a token. The token is transmitted to the Docker Registry with the origin request.
The Docker Registry will respond with the image content after validating the token.
The sequence of proxy authentication is here:
sequenceDiagram;
participant c as client
participant ra as Registry-Auth
participant r as Docker Registry
c->>+ra: request image with username/password
ra->>ra: authenticate and authorize
ra->>ra: generate token
ra->>+r: request image with token
r->>r: validate token
r->>-ra: response with image
ra->>-c: response with image
Registry-auth can load a config file set by the argument --auth-config-file
. The config file contains the usernames, passwords and authorizations for repositories.
The format and example of the configuration are here:
users:
user1: password1 # use the plaintext password for user1
# use the bcrypt encrypted password, the password can be generated by command: `htpasswd -nbB user2 password2`
user2: $2y$05$o.txf8NBl17CimmIKybYYe9SmIcAzctQ84.UbFCObPFxt78W1DEJW
auths:
user1: # user1's configs
- target: usersrepo/test1 # repository name
actions: # allowed actions
- pull
- push
- target: team1repo/.* # use regexp to match repository name
useRegexp: true # stands for the regexp will be used
actions:
- pull
_anonymous: # the configs for anonymous user, the anonymous user need not provide username and password to login
- target: .*
useRegexp: true
actions:
- pull
Registry-auth can load configurations from Kubernetes secrets through the arguments --auth-config-selector
, --auth-config-selector
and --kubeconfig
. The configurations in the secrets are preferred to those loaded from the config file.
The secret example:
apiVersion: v1
kind: Secret
metadata:
name: registry-auth-example
labels:
registry-auth-config: "true"
namespace: default
type: Opaque
data:
config: |
users:
user3: password3
auths:
user3:
- target: userrepo3/.*
useRegexp: true
actions:
- pull
- push
Argument | Default | Description |
---|---|---|
--server-bind-address | The listening IP, all IPs will listen if not defined. | |
--server-port | 8080 | The listening port. |
--server-tls-cert-file | The file path for the HTTPS certificate. It's optional. HTTP will be used if empty. | |
--server-tls-key-file | The file path for the HTTPS private key, used with --server-tls-cert-file. | |
--auth-public-cert-file | The file path of the certificate for signing token, MUST be set. | |
--auth-private-key-file | The file path of the private key for signing token, MUST be set. | |
--auth-config-file | The file path of the config file. It's optional. | |
--auth-config-namespace | The namespace to load config from Kubernetes. It's optional. | |
--auth-config-selector | registry-auth-config=true | The label selector for secrets to load config. It's optional. |
--auth-token-duration | 600 | The token's validation period in seconds. |
--auth-issuer | registry-token-issuer | The token's issuer name. |
--auth-thirdparty-server | The third-party authentication server. It's optional. | |
--registry-backend | 127.0.0.1:5000 | The backend registry address. |
--kubeconfig | The config file to access Kubernetes. It's optional, used with --auth-config-namespace. | |
--log-level | info | The log level. |
The Docker Registry need configure to work with Registry-Auth. You can configure it by config file or environment variables.
You can add the following configs in /etc/docker/registry/config.yml:
auth:
token:
autoredirect: true # Set it true for proxy authentication, set it false for token authentication.
realm: /auth/token # The Registry-Auth's URL. Set relative path for using proxy authentication, but full URL is needed for token authentication.
service: docker-registry # It's used by the authentication server to distinguish different Docker Registry instances, but useless for now.
issuer: registry-token-issuer # Same with Registry-Auth
rootcertbundle: /etc/registry-auth/token.crt # Same with Registry-Auth's --auth-public-cert-file argument.
Or you can exploit the following equivalent environment variables:
Key | Value |
---|---|
REGISTRY_AUTH_TOKEN_AUTOREDIRECT | true |
REGISTRY_AUTH_TOKEN_REALM | /auth/token |
REGISTRY_AUTH_TOKEN_SERVICE | token-service |
REGISTRY_AUTH_TOKEN_ISSUER | registry-token-issuer |
REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE | /etc/registry-auth/token.crt |