Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws ecr get-login should use --password-stdin if available #2875

Closed
lvh-zapier opened this issue Oct 6, 2017 · 36 comments
Closed

aws ecr get-login should use --password-stdin if available #2875

lvh-zapier opened this issue Oct 6, 2017 · 36 comments
Assignees
Labels

Comments

@lvh-zapier
Copy link

Currently, on Docker 17.07+, when evaling the output of aws ecr get-login, the following error message appears:

WARNING! Using --password via the CLI is insecure. Use --password-stdin.

It would be nice if aws ecr get-login could use --password-stdin if it's available. The workaround is to use get-authorization-token, but that involves everyone writing code, whereas --password-stdin is a good idea for everyone who'd ever use aws ecr get-login.

@kyleknap
Copy link
Contributor

kyleknap commented Oct 6, 2017

So I realize getting the warning is not ideal, but the CLI is already using get-authorization-token under the hood. To use --password-stdin and preserve backwards compatibility by printing the command to run to stdout, the command would need to output:

echo <authorizaton-token> | docker login -u AWS  -e none https://123456789012.dkr.ecr.us-west-2.amazonaws.com --password-stdin

which defeats the purpose because the password is still getting printed out. Furthermore, the CLI would have to handle the proper redirection expressions based on the operating system it is being ran from. Is the main reason for this request to just ignore the warning?

@kyleknap kyleknap added the closing-soon This issue will automatically close in 4 days unless further comments are made. label Oct 6, 2017
@lvh-zapier
Copy link
Author

When I referred to the get-authorization-token workaround, I meant a workaround where users essentially write an ecr get-login themselves, but one that pipes the output of get-authorization-token to docker login themselves -- I understand that ecr get-login is already using that functionality right now.

I imagine the warning is really about leaking the token in two places: process lists and shell history. I agree that echoing the bare token doesn't resolve either issue any more than passing it via -p is. Presumably there's no contract to what gets output other than "if you eval it with sh docker will be logged in to ECR", so presumably (assuming we can get that expression in a reasonable, cross-platform manner) an expression that itself uses ecr get-authorization-token instead of its output is fine. (I'd understand if e.g. it wouldn't be OK for the expression to do IO, but you have to log in to ECR so that part is moot). This would have the benefit of not leaking the token under any circumstances: not via process lists, and not via shell history.

@jamesls jamesls removed the closing-soon This issue will automatically close in 4 days unless further comments are made. label Oct 9, 2017
@jamesls jamesls added the investigating This issue is being investigated and/or work is in progress to resolve the issue. label Oct 10, 2017
@dsdenes
Copy link

dsdenes commented Nov 3, 2017

echo $(aws ecr get-authorization-token --region eu-central-1 --output text --query 'authorizationData[].authorizationToken' | base64 -d | cut -d: -f2) | docker login -u AWS https://123456.dkr.ecr.eu-central-1.amazonaws.com --password-stdin

@closedLoop
Copy link

This is more friendly for Windows (git bash) and related clients.

export _DOCKER_REPO="$(aws ecr get-authorization-token --output text  --query 'authorizationData[].proxyEndpoint')"
aws ecr get-login --no-include-email --region us-east-1 | awk '{print $6}' | docker login -u AWS --password-stdin $_DOCKER_REPO

Its also similar to @dsdenes but doesn't hardcode the repo

@bewestphal
Copy link

@closedLoop Command works but make sure to include --region argument in the first line if not in us-east-1 or it will default to there.

@jlr2k8
Copy link

jlr2k8 commented Apr 23, 2018

Late to the party, but I was tired of seeing the login warning too 🙂

aws ecr get-login --no-include-email --region ${REGION} --profile ${PROFILE} | awk '{printf $6}' | docker login -u AWS ${REPOSITORY} --password-stdin

@rlees85
Copy link

rlees85 commented May 4, 2018

Docker seems to have made this a warning that now requires explicit input, meaning that aws-cli ecr get-login can no longer work in a script....

@jlr2k8
Copy link

jlr2k8 commented May 4, 2018

@rlees85 - did you try any of the suggestions above? get-login certainly should work in scripts - I imagine that's the major use case for the command, anyhow.

@rlees85
Copy link

rlees85 commented May 4, 2018

[root@xps13 ~]# export AWS_PROFILE=<blah>
[root@xps13 ~]# systemctl start docker
[root@xps13 ~]# docker --version
Docker version 18.04.0-ce, build 3d479c0af6
[root@xps13 ~]# eval $(aws ecr get-login --region eu-west-1 --no-include-email)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Are you sure you want to proceed? [y/N] 

Workaround: yes | eval $(aws ecr get-login --region eu-west-1 --no-include-email) but thats hacky

Actually I think this is unrelated to the issue/warning that this thread is about... my bad

@jfly
Copy link

jfly commented Jun 14, 2018

For the record, this is less of an immediate issue because docker has reverted the prompt. See docker/cli#1008.

It sounds like their long time plan is to re-introduce this prompt, so it still would probably be good for aws ecr get-login to switch to using --password-stdin.

@ChiragMoradiya
Copy link

Any idea about timeline for the fix of this issue?
When "aws ecr get-login" will output which uses --password-stdin instead of --password?

@kpx-dev
Copy link

kpx-dev commented Aug 22, 2018

What if we introduce the --password-stdin flag at aws ecr get-login --password-stdin, that will solve the backward compatibility issue for older Docker folk. With this flag pass in, we'll generate the echo <auth> | docker login --passwrod-stdin ... version. Without it, we'll generate login normally with the -p option.

@wichert
Copy link

wichert commented Aug 23, 2018

Generating an echo statement is not ideal, since it exposes the password in the process listing. The only way to do this securely is to just run docker login directly from the aws tool instead of relying on a user to copy & paste its output.

@kpx-dev
Copy link

kpx-dev commented Aug 23, 2018

@wichert We would evaluate the command and run it instead of copy and paste it. For example:
$(aws ecr get-login --no-include-email --region us-east-1 --password-stdin)

I think that is the use case anyway, user want to generate that token and to be run at the same machine. I don't think this method is less secure than existing one?

@wichert
Copy link

wichert commented Aug 24, 2018

The whole point of the change in docker login is to improve security by making sure the password is never exposed via the process list. If aws ecr get-login just invokes a shell with the password in the command line you are completely negating that improvement. What imho should happen is that aws ecr get-login just invokes docker login directly and passes the password via stdin. Anything that relies on evaluating the output of aws ecr will be insecure.

@jamesls jamesls added v2 and removed investigating This issue is being investigated and/or work is in progress to resolve the issue. labels Sep 24, 2018
@theY4Kman
Copy link

theY4Kman commented Oct 26, 2018

EDIT [2020/02/14]
Since #4874, piping the password into docker login --password-stdin is now possible!
Just use:

aws ecr get-login-password | docker login --username AWS --password-stdin https://<aws_account_id>.dkr.ecr.<region>.amazonaws.com

Presuming pipes are supported in the terminal, it seems to me there needn't be a need to use echo — just have a different aws ecr command/flag to only print the password, and pipe that to docker login --password-stdin:

# NOTE: --password-stdin IS HYPOTHETICAL! DO NOT EXPECT IT TO WORK

$ aws ecr get-login --no-include-email --region us-east-1 --password-stdin
aws ecr get-login --region us-east-1 --print-password-only | docker login -u AWS --password-stdin https://12345.dkr.ecr.us-east-1.amazonaws.com

$ aws ecr get-login --region us-east-1 --print-password-only
pCwnxiDQWSN1nx9uaphdzRK7dQHxZUSlzMKi4IViZOCvnAE9K1P0qJkH5UMISmbkJlrjut96yzPOb82Jpoc0BEvKeZUlXWtSX4JA

$ aws ecr get-login --region us-east-1 --print-password-only | docker login -u AWS --password-stdin https://12345.dkr.ecr.us-east-1.amazonaws.com
Login Succeeded

$ $(aws ecr get-login --no-include-email --region us-east-1 --password-stdin)
Login Succeeded

@oceaneLonneux
Copy link

Presuming pipes are supported in the terminal, it seems to me there needn't be a need to use echo — just have a different aws ecr command/flag to only print the password, and pipe that to docker login --password-stdin:

$ aws ecr get-login --no-include-email --region us-east-1 --password-stdin
aws ecr get-login --region us-east-1 --print-password-only | docker login -u AWS --password-stdin https://12345.dkr.ecr.us-east-1.amazonaws.com

$ aws ecr get-login --region us-east-1 --print-password-only
pCwnxiDQWSN1nx9uaphdzRK7dQHxZUSlzMKi4IViZOCvnAE9K1P0qJkH5UMISmbkJlrjut96yzPOb82Jpoc0BEvKeZUlXWtSX4JA

$ aws ecr get-login --region us-east-1 --print-password-only | docker login -u AWS --password-stdin https://12345.dkr.ecr.us-east-1.amazonaws.com
Login Succeeded

$ $(aws ecr get-login --no-include-email --region us-east-1 --password-stdin)
Login Succeeded

I have been trying your fix but I am not sure I am proceeding correctly...?
I do aws ecr get-login --no-include-email --region eu-west-1 --password-stdin
and it returns Unknown options: --password-stdin
--print-password-only is unknows as well.

Have I missed steps before? Thanks!

@ORESoftware
Copy link

this should be fine

pwd="$(aws ecr get-login --no-include-email --region us-east-1 | awk '{print $6}')"
docker login -u AWS --password "$pwd"

@theY4Kman
Copy link

theY4Kman commented Apr 27, 2019

Using $pwd on the command-line would defeat the purpose, as the password would then be available for reading in /proc/N/cmdline. By passing it through a pipe, only the program emitting it (aws and awk) and the program reading it (docker) can see the password:

# one-liner
aws ecr get-login --no-include-email --region us-east-1 | awk '{print $6}' | docker login -u AWS --password-stdin $(aws ecr get-login --no-include-email --region us-east-1 | awk '{print $7}')

# long-form
cmd="aws ecr get-login --no-include-email --region us-east-1"
url=$($cmd | awk '{ print $7 }')
$cmd | awk '{ print $6 }' | docker login -u AWS --password-stdin $url

@apolegoshko
Copy link

By the way, there is no flag in latest aws cli installed via pip

--print-password-only

@Cloudmersive
Copy link

This is completely broken by the way. How is this still not fixed?

@theY4Kman
Copy link

To be clear, --print-password-only was just a suggestion; it's not a feature offered or supported by aws-cli, at time of writing.

@oceaneLonneux
Copy link

Okay so I've had this problem. The CD tool we are using logged the warning as an error so no choice but to avoid it.

Here is what I have used with Powershell to push to AWS ECR:
#First step to create the file
aws ecr get-login --no-include-email --region $region | Out-File -FilePath $FILEPATH
#Second step to filter the file and just get the password.
-split @(Get-Content -Path $FILEPATH) | Select-Object -Index 5 | Out-File -FilePath $FILEPATH
cat $FILEPATH | docker login -u AWS --password-stdin ECR-URL

Hopefully this works. You will need the credentials (on aws configure) as well. It is however a very long process (I literally crashed through PS with this so there might be faster ways).

@antgustech
Copy link

Would be nice to get rid of this warning. Sure there are work arounds but they are larger than my entire build script so it adds a lot of clutter.

@ddspell
Copy link

ddspell commented Jun 5, 2019

If all you want to do is get rid of the warning, just do this:
$(aws ecr get-login --no-include-email --region us-east-1) 2>/dev/null

@pauldraper
Copy link

pauldraper commented Jun 8, 2019

Lots of misunderstanding here.

Point 1: (#2875 (comment))

If you are worried about seeing the warning,

it's because you should be worried about what aws-cli is doing

Putting passwords into shell commands is BAD, BAD, BAD, BAD, BAD. By invoking aws ecr get-login,

You have just now LEAKED the password in plaintext to every single user on the system.

(Unless you are are using exotic configurations like mounting /proc with hidepid)

Developers suggesting hiding stderr or suggesting passing it as shell args to other commands like echo are sticking their collective head in the sand, caring more for untroubled logs than for security. See Passing Passwords.


Point 2: It's currently possible to pass the password from AWS CLI to docker in a secure way (#2875 (comment)) though it's ugly and requires other tools (cut, awk).

I'm in no position to be casting stones, but it's surprising AWS has left this security issue unaddressed for almost two years.

@moritzheiber
Copy link

Does this official helper address the concerns voiced in this issue?

https://github.com/awslabs/amazon-ecr-credential-helper

@pauldraper
Copy link

pauldraper commented Jun 8, 2019

I was unaware of that. It is indeed a suitable method. It uses docker's credStore/credHelpers interface.

Docker invokes the docker-credential-ecr-login executable and the executable produces on stdout

{
    "Username": "george",
    "Secret": "passw0rd"
}

In fact, it would be convenient if the AWS CLI itself offered this interface, so there wasn't separate install. amazon-ecr-credential-helper has several install methods, but none of them are the pip install used by AWS CLI :/

@moritzheiber
Copy link

moritzheiber commented Jun 8, 2019

If you take a look at the README, it even mentions (as it is with other helpers) that Docker will automatically pick up any credentials required for ECR repositories without having to store or pass any usernames or passwords in the future.

I’d call that a win-win :)

@pauldraper I reckon if it’s easy enough to install it doesn’t matter to most users (which, in this case, at least for me, it is!)

@pauldraper
Copy link

Indeed using credHelpers is the best way.

@pauldraper
Copy link

Apparently amazon-ecr-credential-helper only has Ubuntu packages for non-LTS Ubuntu versions :/

So I did the same thing with a four-line script.

/usr/local/bin/docker-credential-ecr-login

#!/bin/sh
grep -q 'dkr.ecr.[^.]\+.amazonaws.com' - || exit
aws --output text ecr get-authorization-token --query authorizationData[0].authorizationToken \
  | base64 --decode \
  | sed -e 's/:/", "Secret":"/' -e 's/^/{"Username":"/' -e 's/$/"}/'

~/.docker/config

{"credsStore": "ecr-login"}

Now docker pull and docker push without an extra steps.

https://gist.github.com/pauldraper/b74a24f869b0acbc3bd488d67f9a53b4

matthew-russo pushed a commit to matthew-russo/aws-cli that referenced this issue Jan 24, 2020
as proposed in aws#4867,
and previously discussed in
aws#2875 (comment)
aws#3687 (comment)

this commit adds a new customization command for ECR that only
returns the password to login to a registry. this approach is
composable, is compatible with other container clients, allows
use of functionality like Docker's --password-stdin flag, and
is more resilient to changes in client APIs
matthew-russo pushed a commit to matthew-russo/aws-cli that referenced this issue Jan 24, 2020
as proposed in aws#4867,
and previously discussed in
aws#2875 (comment)
aws#3687 (comment)

this commit adds a new customization command for ECR that only
returns the password to login to a registry. this approach is
composable, is compatible with other container clients, allows
use of functionality like Docker's --password-stdin flag, and
is more resilient to changes in client APIs
matthew-russo pushed a commit to matthew-russo/aws-cli that referenced this issue Jan 24, 2020
as proposed in aws#4867,
and previously discussed in
aws#2875 (comment)
aws#3687 (comment)

this commit adds a new customization command for ECR that only
returns the password to login to a registry. this approach is
composable, is compatible with other container clients, allows
use of functionality like Docker's --password-stdin flag, and
is more resilient to changes in client APIs
matthew-russo pushed a commit to matthew-russo/aws-cli that referenced this issue Jan 24, 2020
as proposed in aws#4867,
and previously discussed in
aws#2875 (comment)
aws#3687 (comment)

this commit adds a new customization command for ECR that only
returns the password to login to a registry. this approach is
composable, is compatible with other container clients, allows
use of functionality like Docker's --password-stdin flag, and
is more resilient to changes in client APIs
matthew-russo pushed a commit to matthew-russo/aws-cli that referenced this issue Jan 24, 2020
as proposed in aws#4867,
and previously discussed in
aws#2875 (comment)
aws#3687 (comment)

this commit adds a new customization command for ECR that only
returns the password to login to a registry. this approach is
composable, is compatible with other container clients, allows
use of functionality like Docker's --password-stdin flag, and
is more resilient to changes in client APIs
@joguSD
Copy link
Contributor

joguSD commented Feb 5, 2020

Yesterday's release (v1.17.10) included a new command aws ecr get-login-password which performs the needed conversion to format the password for docker. For a more detailed write-up see: aws/containers-roadmap#735.

@kyleknap
Copy link
Contributor

kyleknap commented Feb 5, 2020

We also removed ecr get-login in favor of ecr get-login-password in v2 as well. We recommend using the ecr get-login-password going forward. Closing issue.

@stelsemeyer
Copy link

stelsemeyer commented Feb 15, 2020

The following works for me:

aws --region ${aws_region} ecr get-login-password \
    | docker login \
        --password-stdin \
        --username AWS \
        "${aws_account_id}.dkr.ecr.${aws_region}.amazonaws.com"

Ref.: #4962 (comment), credit to @matthew-russo!

@pgilad
Copy link

pgilad commented Feb 17, 2020

Or an even more automatic version where your account id is already detected using credentials (Replace us-east-1 with relevant region):

$ aws ecr get-login-password --region us-east-1 \
    | docker login \
        --password-stdin \
        --username AWS \
        "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com"

@aradwyr
Copy link

aradwyr commented Apr 28, 2020

None of the above solutions are working for me, so far I've tried various iterations of the aws ecr get-login-password in a Docker image.

For ex:

 aws ecr get-login-password --region us-west-2 | docker login --password-stdin --username AWS "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-west-2.amazonaws.com"

Results in:

Unable to locate credentials. You can configure credentials by running "aws configure".
Error: Cannot perform an interactive login from a non TTY device

Vast majority of the time I'm encountering this error: no basic auth credentials but I'm only facing this error once I'm at the last step trying to push the image:

- eval $(aws ecr get-login-password --region us-west-2 | docker login --password-stdin --username AWS "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-west-2.amazonaws.com")
- docker build -t $IMAGE_NAME .
- docker tag <ecr_repo>:<tag> <image_uri>
- docker push <image_uri>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests