Closed DavidObando closed 7 years ago
Please add documentation for how to use /exchange to obtain the token as well as details for crafting the token.
Could you also explain how a user can manually obtain this token and update their docker config without doing a docker login or use that JWT for docker login
Also please move this to docs/AAD-OAuth.md
@SajayAntony I've updated this. Let me know what you think, I'll go ahead with copying it into docs/AAD-OAuth.md
.
Azure Container Registry integration with Azure Active Directory
The Azure Container Registry allows users to manage a private Docker registry on the cloud. Our service enables customers to store and manage container images across all types of Azure deployments, keep container images near deployments to reduce latency and costs, maintain Windows and Linux container images in a single Docker registry, use familiar, open-source Docker command line interface (CLI) tools, and simplify registry access management with Azure Active Directory.
The integration of Azure Container Registry with Azure Active Directory is crucial in order to enable transparent authentication and authorization of users and headless services using AAD credentials. In this scenario, a user will only have to use their AAD credentials to log-in to their private registry, and the Azure Container Service will take care of the authorization validation of each operation using the provided credentials.
Under the hood Azure Container Service utilizes the oauth2 authorization protocol, as described by the Docker Registry v2 authentication via central service documentation as well as the Docker Registry v2 Bearer token specification. The JWT tokens generated by the Azure Container Registry are easy to observe in jwt.io.
Authenticating to a registry with Azure CLI
The process to log in to the registry, from the user's perspective, is simple. The user will use the Microsoft Azure CLI 2.0:
Internally, the CLI will follow these steps:
/v2
endpoint, without credentials. A bearer token authentication challenge is expected, specifying realm and service values. The realm contains the authentication server's URL./oauth2/exchange
endpoint, with a body indicating the grant type, the service, the tenant, and the credentials.docker login
. From here on, the docker CLI takes care of the authorization cycle using oauth2.At the end Docker will store the refresh token and go through the oauth2 flow on each operation it does against the Azure Container Registry.
Listing a repository with Azure CLI
The Microsoft Azure CLI 2.0 allows users to also list the repositories registries, and list tags for a repository in a registry. Here's how users can achieve listing the repositories in a registry:
Internally, the CLI will follow these steps:
/v2
endpoint, without credentials. A bearer token authentication challenge is expected, specifying realm and service values. The realm contains the authentication server's URL./oauth2/exchange
endpoint, with a body indicating the grant type, the service, the tenant, and the credentials./oauth2/token
endpoint, with a body indicating the grant type, the service, the scope, and the Azure Container Registry refresh token./v2/_catalog
endpoint using the access token as the bearer token.When listing the tags of a repository, every step above is the same except for the call to the endpoint that gives the tags which is
/v2/contosoregistry/tags/list
instead of/v2/_catalog
.Azure Container Registry refresh tokens and access tokens
Let's follow an example call to list a repository:
This will produce a JWT refresh token with the following payload:
Followed by an access token with the following payload:
Getting credentials programatically
In order to sign in to a container you'll need to exchange AAD credentials for ACR credentials. The accepted form of credential exchange are:
Ideally you'll present both the AAD access token and the AAD refresh token. The AAD access token is used to talk to the Azure Resource Manager and query for the set of permissions that the user has for the container registry resource. The AAD refresh token is used in two ways:
The cycle to get credentials looks as follows:
/oauth2/exchange
presenting the AAD refresh token and the AAD access token. The service will return you an ACR refresh token./oauth2/token
presenting the ACR refresh token. The service will return you an ACR access token which you can use to call the Azure Container Registry's APIs.Calling
/oauth2/exchange
to get an ACR refresh tokenAssume you have the following:
contosoregistry.azurecr.io
409520d4-8100-4d1d-ad47-72432ddcc120
.Here's how such a call looks when done via
curl
:The body of the POST message is a querystring-like text that specifies the following values:
grant_type
, which can take a value ofaccess_token_refresh_token
, oraccess_token
, orrefresh_token
.service
, which must indicate the name of your Azure container registry.tenant
, which is the AAD tenant associated to the AAD credentials.refresh_token
, the AAD refresh token, mandatory whengrant_type
isaccess_token_refresh_token
orrefresh_token
.access_token
, the AAD access token, mandatory whengrant_type
isaccess_token_refresh_token
oraccess_token
.The outcome of this operation will be a response with status 200 OK and a body with the following JSON payload:
This response is the ACR refresh token which you can inspect with jwt.io. You can now use it to obtain an ACR access token programmatically or simply send it to the
docker login
command to get docker talking to the Azure Container Registry.Authenticating docker with an ACR refresh token
Once you have obtained an ACR refresh token, you can use the docker CLI to sign in to your registry like this:
The null GUID tells the container registry that this is an ACR refresh token during the login flow.
Calling
/oauth2/token
to get an ACR access tokenAssume you have the following:
contosoregistry.azurecr.io
."registry:catalog:*"
scope that will allow us to call the/v2/_catalog
API.Here's how such a call looks when done via
curl
:The body of the POST message is a querystring-like text that specifies the following values:
grant_type
which is expected to berefresh_token
.service
, which must indicate the name of your Azure container registry.scope
, which is expected to be a valid scope, and can be specified more than once for multiple scope requests.refresh_token
, which must be a valid ACR refresh token, as obtained by calling/oauth2/exchange
.The outcome of this operation will be a response with status 200 OK and a body with the following JSON payload:
This response is the ACR access token which you can inspect with jwt.io. You can now use it to call APIs exposed by the Azure Container Registry
Calling an Azure Container Registry API
Assume you have the following:
contosoregistry.azurecr.io
.Here's how a call to an Azure Container Registry API would look like when done via
curl
:This should result in a status 200 OK, and a body with a JSON payload listing the repositories held in this registry: