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
.
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?
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.
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
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
@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.
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
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....
@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.
[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
For the record, this is less of an immediate issue because docker has reverted the prompt. See https://github.com/docker/cli/pull/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
.
Any idea about timeline for the fix of this issue?
When "aws ecr get-login" will output which uses --password-stdin
instead of --password
?
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.
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.
@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?
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.
EDIT [2020/02/14]
Since #4874, piping the password intodocker 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
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 todocker 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!
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"
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
By the way, there is no flag in latest aws cli installed via pip
--print-password-only
This is completely broken by the way. How is this still not fixed?
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.
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:
aws ecr get-login --no-include-email --region $region | Out-File -FilePath $FILEPATH
-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).
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.
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
Lots of misunderstanding here.
Point 1: (https://github.com/aws/aws-cli/issues/2875#issuecomment-415668165)
Putting passwords into shell commands is BAD, BAD, BAD, BAD, BAD. By invoking aws ecr get-login
,
(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 (https://github.com/aws/aws-cli/issues/2875#issuecomment-342821099) 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.
Does this official helper address the concerns voiced in this issue?
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 :/
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!)
Indeed using credHelpers is the best way.
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
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: https://github.com/aws/containers-roadmap/issues/735.
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.
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.: https://github.com/aws/aws-cli/issues/4962#issuecomment-586486939, credit to @matthew-russo!
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"
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>
Most helpful comment
This is more friendly for Windows (git bash) and related clients.
Its also similar to @dsdenes but doesn't hardcode the repo