github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/docs/spec/auth/token.md (about)

     1  <!--[metadata]>
     2  +++
     3  title = "Token Authentication Specification"
     4  description = "Specifies the Docker Registry v2 authentication"
     5  keywords = ["registry, on-prem, images, tags, repository, distribution, Bearer authentication, advanced"]
     6  [menu.main]
     7  parent="smn_registry_ref"
     8  +++
     9  <![end-metadata]-->
    10  
    11  # Docker Registry v2 authentication via central service
    12  
    13  This document outlines the v2 Docker registry authentication scheme:
    14  
    15  ![v2 registry auth](https://docs.google.com/drawings/d/1EHZU9uBLmcH0kytDClBv6jv6WR4xZjE8RKEUw1mARJA/pub?w=480&h=360)
    16  
    17  1. Attempt to begin a push/pull operation with the registry.
    18  2. If the registry requires authorization it will return a `401 Unauthorized`
    19     HTTP response with information on how to authenticate.
    20  3. The registry client makes a request to the authorization service for a
    21     Bearer token.
    22  4. The authorization service returns an opaque Bearer token representing the
    23     client's authorized access.
    24  5. The client retries the original request with the Bearer token embedded in
    25     the request's Authorization header.
    26  6. The Registry authorizes the client by validating the Bearer token and the
    27     claim set embedded within it and begins the push/pull session as usual. 
    28  
    29  ## Requirements
    30  
    31  - Registry clients which can understand and respond to token auth challenges
    32    returned by the resource server.
    33  - An authorization server capable of managing access controls to their
    34    resources hosted by any given service (such as repositories in a Docker
    35    Registry).
    36  - A Docker Registry capable of trusting the authorization server to sign tokens
    37    which clients can use for authorization and the ability to verify these
    38    tokens for single use or for use during a sufficiently short period of time.
    39  
    40  ## Authorization Server Endpoint Descriptions
    41  
    42  The described server is meant to serve as a standalone access control manager
    43  for resources hosted by other services which wish to authenticate and manage
    44  authorizations using a separate access control manager.
    45  
    46  A service like this is used by the official Docker Registry to authenticate
    47  clients and verify their authorization to Docker image repositories.
    48  
    49  As of Docker 1.6, the registry client within the Docker Engine has been updated
    50  to handle such an authorization workflow.
    51  
    52  ## How to authenticate
    53  
    54  Registry V1 clients first contact the index to initiate a push or pull. Under
    55  the Registry V2 workflow, clients should contact the registry first. If the
    56  registry server requires authentication it will return a `401 Unauthorized`
    57  response with a `WWW-Authenticate` header detailing how to authenticate to this
    58  registry.
    59  
    60  For example, say I (username `jlhawn`) am attempting to push an image to the
    61  repository `samalba/my-app`. For the registry to authorize this, I will need
    62  `push` access to the `samalba/my-app` repository. The registry will first
    63  return this response:
    64  
    65  ```
    66  HTTP/1.1 401 Unauthorized
    67  Content-Type: application/json; charset=utf-8
    68  Docker-Distribution-Api-Version: registry/2.0
    69  Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:samalba/my-app:pull,push"
    70  Date: Thu, 10 Sep 2015 19:32:31 GMT
    71  Content-Length: 235
    72  Strict-Transport-Security: max-age=31536000
    73  
    74  {"errors":[{"code":"UNAUTHORIZED","message":"access to the requested resource is not authorized","detail":[{"Type":"repository","Name":"samalba/my-app","Action":"pull"},{"Type":"repository","Name":"samalba/my-app","Action":"push"}]}]}
    75  ```
    76  
    77  Note the HTTP Response Header indicating the auth challenge:
    78  
    79  ```
    80  Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:samalba/my-app:pull,push"
    81  ```
    82  
    83  This format is documented in [Section 3 of RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-3)
    84  
    85  This challenge indicates that the registry requires a token issued by the
    86  specified token server and that the request the client is attempting will
    87  need to include sufficient access entries in its claim set. To respond to this
    88  challenge, the client will need to make a `GET` request to the URL
    89  `https://auth.docker.io/token` using the `service` and `scope` values from the
    90  `WWW-Authenticate` header.
    91  
    92  ## Requesting a Token
    93  
    94  #### Query Parameters
    95  
    96  <dl>
    97      <dt>
    98          <code>service</code>
    99      </dt>
   100      <dd>
   101          The name of the service which hosts the resource.
   102      </dd>
   103      <dt>
   104          <code>scope</code>
   105      </dt>
   106      <dd>
   107          The resource in question, formatted as one of the space-delimited
   108          entries from the <code>scope</code> parameters from the <code>WWW-Authenticate</code> header
   109          shown above. This query parameter should be specified multiple times if
   110          there is more than one <code>scope</code> entry from the <code>WWW-Authenticate</code>
   111          header. The above example would be specified as:
   112          <code>scope=repository:samalba/my-app:push</code>.
   113      </dd>
   114  </dl>
   115  
   116  
   117  #### Token Response Fields
   118  
   119  <dl>
   120      <dt>
   121          <code>token</code>
   122      </dt>
   123      <dd>
   124          An opaque <code>Bearer</code> token that clients should supply to subsequent
   125          requests in the <code>Authorization</code> header.
   126      </dd>
   127      <dt>
   128          <code>access_token</code>
   129      </dt>
   130      <dd>
   131          For compatibility with OAuth 2.0, we will also accept <code>token</code> under the name
   132          <code>access_token</code>.  At least one of these fields <b>must</b> be specified, but
   133          both may also appear (for compatibility with older clients).  When both are specified,
   134          they should be equivalent; if they differ the client's choice is undefined.
   135      </dd>
   136      <dt>
   137          <code>expires_in</code>
   138      </dt>
   139      <dd>
   140          (Optional) The duration in seconds since the token was issued that it 
   141          will remain valid.  When omitted, this defaults to 60 seconds.  For
   142          compatibility with older clients, a token should never be returned with
   143          less than 60 seconds to live.
   144      </dd>
   145      <dt>
   146          <code>issued_at</code>
   147      </dt>
   148      <dd>
   149          (Optional) The <a href="https://www.ietf.org/rfc/rfc3339.txt">RFC3339</a>-serialized UTC
   150          standard time at which a given token was issued. If <code>issued_at</code> is omitted, the
   151          expiration is from when the token exchange completed.
   152      </dd>
   153  </dl>
   154  
   155  #### Example
   156  
   157  For this example, the client makes an HTTP GET request to the following URL:
   158  
   159  ```
   160  https://auth.docker.io/token?service=registry.docker.io&scope=repository:samalba/my-app:pull,push
   161  ```
   162  
   163  The token server should first attempt to authenticate the client using any
   164  authentication credentials provided with the request. As of Docker 1.8, the
   165  registry client in the Docker Engine only supports Basic Authentication to
   166  these token servers. If an attempt to authenticate to the token server fails,
   167  the token server should return a `401 Unauthorized` response indicating that
   168  the provided credentials are invalid.
   169  
   170  Whether the token server requires authentication is up to the policy of that
   171  access control provider. Some requests may require authentication to determine
   172  access (such as pushing or pulling a private repository) while others may not
   173  (such as pulling from a public repository).
   174  
   175  After authenticating the client (which may simply be an anonymous client if
   176  no attempt was made to authenticate), the token server must next query its
   177  access control list to determine whether the client has the requested scope. In
   178  this example request, if I have authenticated as user `jlhawn`, the token
   179  server will determine what access I have to the repository `samalba/my-app`
   180  hosted by the entity `registry.docker.io`.
   181  
   182  Once the token server has determined what access the client has to the
   183  resources requested in the `scope` parameter, it will take the intersection of
   184  the set of requested actions on each resource and the set of actions that the
   185  client has in fact been granted. If the client only has a subset of the
   186  requested access **it must not be considered an error** as it is not the
   187  responsibility of the token server to indicate authorization errors as part of
   188  this workflow.
   189  
   190  Continuing with the example request, the token server will find that the
   191  client's set of granted access to the repository is `[pull, push]` which when
   192  intersected with the requested access `[pull, push]` yields an equal set. If
   193  the granted access set was found only to be `[pull]` then the intersected set
   194  would only be `[pull]`. If the client has no access to the repository then the
   195  intersected set would be empty, `[]`.
   196  
   197  It is this intersected set of access which is placed in the returned token.
   198  
   199  The server then constructs an implementation-specific token with this
   200  intersected set of access, and returns it to the Docker client to use to
   201  authenticate to the audience service (within the indicated window of time):
   202  
   203  ```
   204  HTTP/1.1 200 OK
   205  Content-Type: application/json
   206  
   207  {"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IlBZWU86VEVXVTpWN0pIOjI2SlY6QVFUWjpMSkMzOlNYVko6WEdIQTozNEYyOjJMQVE6WlJNSzpaN1E2In0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJqbGhhd24iLCJhdWQiOiJyZWdpc3RyeS5kb2NrZXIuY29tIiwiZXhwIjoxNDE1Mzg3MzE1LCJuYmYiOjE0MTUzODcwMTUsImlhdCI6MTQxNTM4NzAxNSwianRpIjoidFlKQ08xYzZjbnl5N2tBbjBjN3JLUGdiVjFIMWJGd3MiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InNhbWFsYmEvbXktYXBwIiwiYWN0aW9ucyI6WyJwdXNoIl19XX0.QhflHPfbd6eVF4lM9bwYpFZIV0PfikbyXuLx959ykRTBpe3CYnzs6YBK8FToVb5R47920PVLrh8zuLzdCr9t3w", "expires_in": "3600","issued_at": "2009-11-10T23:00:00Z"}
   208  ```
   209  
   210  
   211  ## Using the Bearer token
   212  
   213  Once the client has a token, it will try the registry request again with the
   214  token placed in the HTTP `Authorization` header like so:
   215  
   216  ```
   217  Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IkJWM0Q6MkFWWjpVQjVaOktJQVA6SU5QTDo1RU42Ok40SjQ6Nk1XTzpEUktFOkJWUUs6M0ZKTDpQT1RMIn0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJCQ0NZOk9VNlo6UUVKNTpXTjJDOjJBVkM6WTdZRDpBM0xZOjQ1VVc6NE9HRDpLQUxMOkNOSjU6NUlVTCIsImF1ZCI6InJlZ2lzdHJ5LmRvY2tlci5jb20iLCJleHAiOjE0MTUzODczMTUsIm5iZiI6MTQxNTM4NzAxNSwiaWF0IjoxNDE1Mzg3MDE1LCJqdGkiOiJ0WUpDTzFjNmNueXk3a0FuMGM3cktQZ2JWMUgxYkZ3cyIsInNjb3BlIjoiamxoYXduOnJlcG9zaXRvcnk6c2FtYWxiYS9teS1hcHA6cHVzaCxwdWxsIGpsaGF3bjpuYW1lc3BhY2U6c2FtYWxiYTpwdWxsIn0.Y3zZSwaZPqy4y9oRBVRImZyv3m_S9XDHF1tWwN7mL52C_IiA73SJkWVNsvNqpJIn5h7A2F8biv_S2ppQ1lgkbw
   218  ```
   219  
   220  This is also described in [Section 2.1 of RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-2.1)