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  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)