boto3 ecr get_authorization_token return incorrect token

Created on 3 Mar 2016  路  12Comments  路  Source: boto/boto3

Hi,
Today I have experienced this issue with boto3 ecr. I used a simple scripts to get token from boto3 to access login docker on 2 machines.

import boto3
from docker import Client
client = boto3.client('ecr', region_name="us-east-1")
response = client.get_authorization_token(
    registryIds=[
        'MY ACCOUNT ID',
    ]
)
print response
token = response["authorizationData"][0]["authorizationToken"]
endpoint = response["authorizationData"][0]["proxyEndpoint"]
cli = Client(base_url='unix://var/run/docker.sock')
cli.login(username="AWS", password=token, registry=endpoint)
print cli

I ran the script on 2 machines with the same full access to ecr role.
2 machines returned same token, however only one machine worked with this token, the other returned 403 Forbidden.

Since I have a cluster of machines using ECR, I need all of them to be able to connect with ECR

closing-soon ecr guidance

Most helpful comment

The solution : the token returned by boto (in fact aws api) is not the password. It's a base64 encoded user:password.
You should do
user, password = base64.b64decode(token).split(':')
Hope it will unblock someone.

All 12 comments

Does the 403 forbidden come from the login()? From the sounds of it boto3 is properly able to make the request as there are no issues with the get_authorization_token call. It seems like it may be a permissions thing, which I am not entirely sure how that is setup or any caveats. I would recommend reaching out in the forums to get help with that: https://forums.aws.amazon.com/forum.jspa?forumID=187

Yes. It seems boto3 get_authorization_token is working fine. But the returned token is somehow invalid, and can not be used in docker login. That made the 403 response.

I noticed that if I run the aws ecr get-login command, the token is totally different from what boto3 returns.

Hmm so the CLI uses get_authorization_token() under the hood: https://github.com/aws/aws-cli/blob/develop/awscli/customizations/ecr.py#L44. It looks like based on the code, the authorization token is a combination of username and password and you have to split on : and in your code snippet you use the authorization token directly to the password. So you may need to do some splitting on :. Let us know if that helps.

The get_authorization_token returns only token string. There is no : and it used to work on one machine, so I guess my implementation is fine. Btw, somehow today the script is working again. I can login docker on both machines using the script.

Maybe the AWS Token service is not stable.

Yeah I am not sure what it must have been. Good to hear that is working now though. Closing issue.

Hey,
Just for completeness as I ran into the same issue yesterday:

get_authorization_token returns the username and password as @kyleknap mentioned but it is base64 encoded, see https://github.com/aws/aws-cli/blob/develop/awscli/customizations/ecr.py#L53:L54

so just copy these 2 lines in your code to get the username/password.
I don't think it was a temporary issue with aws, just a mistake somewhere.

The solution : the token returned by boto (in fact aws api) is not the password. It's a base64 encoded user:password.
You should do
user, password = base64.b64decode(token).split(':')
Hope it will unblock someone.

Hi, Having the same issue here
@stolati token didn't work for me

import boto3
import os
from base64 import b64decode

AWS_ACCESS_KEY=os.getenv("AWS_ACCESS_KEY")
AWS_SECRET_KEY=os.getenv("AWS_SECRET_KEY")

def get_token(region,registry_urls):
    client = boto3.client('ecr',aws_access_key_id=AWS_ACCESS_KEY,aws_secret_access_key=AWS_SECRET_KEY,region_name=region)
    responce = client.get_authorization_token(registryIds=registry_urls)
    raw_data=responce['authorizationData'][0]['authorizationToken']
    user, decoded_data=b64decode(raw_data).decode('UTF-8').split(":")
    print(decoded_data)
    return {"command": "docker login -u AWS -p "+decoded_data}

get_token(region="us-east-1",registry_urls=["ACCOUNTID",])
docker login -u AWS -p "TOKEN"

Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password

@rajivreddy You are getting a token, or the assignment user, decoded_data = ...split
would fail. So the problem may arise from other part of the system.
I would check that the aws acr get-login is working. Double check your user have access to ecr. Then test on a different machine, maybe even a ec2 instance, to avoid docker configuration or time delta problems. Also, use the user given instead of the AWS string, we never know when AWS decide to change it.

@stolati I have admin privs to AWS.

I am able to get token by using aws cli.

@rajivreddy this is the actual code from aws cli ecr :

auth_token = b64decode(auth['authorizationToken']).decode()
username, password = auth_token.split(':')
command = ['docker', 'login', '-u', username, '-p', password]
if parsed_args.include_email:
    command.extend(['-e', 'none'])
command.append(auth['proxyEndpoint'])
sys.stdout.write(' '.join(command))
sys.stdout.write('\n')

I would look at the differences with your own code.

@stolati
pardon me! issue is not with the boto3, its with the command that i was running, i have not passed ECR URL

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danielmorozoff picture danielmorozoff  路  3Comments

chesstrian picture chesstrian  路  3Comments

arnonki picture arnonki  路  3Comments

maoo picture maoo  路  3Comments

boompig picture boompig  路  3Comments