# amazon-ecr-login: the GitHub Action that runs docker login for you

> aws-actions/amazon-ecr-login is a JavaScript GitHub Action that authenticates the runner's Docker client against Amazon ECR private or public registries. It is small, it is maintained by AWS, and its v2 release changed one default that broke workflows which read the credentials as job outputs.

**aws-actions/amazon-ecr-login** — Logs into Amazon ECR with the local Docker client.

- Repository: https://github.com/aws-actions/amazon-ecr-login
- Stars: 1,062 · Forks: 214
- Language: JavaScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/aws-actions-amazon-ecr-login

## It is a login step, and nothing more

The scope of this action is narrow and worth stating before anything else. It logs the local Docker client to one or more Amazon ECR Private registries, or to an Amazon ECR Public registry. It does not build, it does not tag, it does not push, and it does not pull.

That boundary is what makes it a pleasant piece of infrastructure. The action hands you two things: a registry value in its outputs and a Docker credential written into the runner's credential store. Your own steps then do the ordinary work, and the README's examples show exactly that shape, with a login step carrying the id login-ecr, followed by a build, tag and push step that reads the registry from the step output.

The registry output is the quiet detail that saves the most typing. Instead of hard coding an account-specific hostname in every job, the value comes from the step, so the same workflow body works across accounts. The public registry case needs one extra path segment, a registry alias, because a public repository address includes the alias between the registry and the repository name, and the README's public example carries that alias in its own environment variable.

## v2 changed the mask-password default and broke the output consumers

The most important thing to know about this action is a breaking change in its second major version. In v2, the default value of the mask-password input changed from false to true.

The flag controls whether the Docker password is masked in the workflow log. Masking is the safe default, so the change is sensible in isolation, but it interacts with a feature: the action can output the Docker credentials as job outputs so that a later job can use them. With mask-password set to false, the password appears in the logs in clear text, and the README carries a warning that this will happen specifically if debug logging is enabled on GitHub.

The upgrade path the README gives is precise. If you are not consuming the Docker credentials as outputs in subsequent jobs, you can simply move to aws-actions/amazon-ecr-login@v2. If you are, and you were relying on the v1 default, your workflow will break, and the fix is to set the input explicitly:

```yaml
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
        with:
          mask-password: 'false'
```

If you were already setting mask-password to false, the version bump is enough. The README points to issue 526 for the reasoning behind the change, which is the right place to read what the maintainers intended.

## One login step can cover several AWS accounts at once

The action accepts a registries input, a comma separated list of AWS account IDs, and the README's example logs in to two of them in a single step:

```yaml
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/my-github-actions-role
          aws-region: aws-region-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
        with:
          registries: "123456789012,998877665544"
```

The mechanism here is worth understanding, because the second account is the part that surprises people. The credentials used for the login come from the credentials step that runs first, in this case an assumed IAM role. Access to the second account is therefore not granted by this action. The repository in account 998877665544 has to explicitly grant access to the role arn:aws:iam::123456789012:role/my-github-actions-role for the cross-account flow to work, and the README sends you to the AWS documentation for how to configure ECR policies.

So the failure mode here is a permission problem that looks like an authentication problem. If a second registry is missing from the login, the cause is nearly always the repository policy in the other account, not the action.

## Handing credentials to a later job versus logging in inside the job

There are two supported ways to use the credential output, and they carry different risk.

The first is the pattern most pipelines use: log in inside the job that needs it, then build and push there. The README's private and public examples both follow it, and the registry value is read from the step output into an environment variable that the docker build and docker push commands use. The credential never leaves the job.

The second is the pattern the README calls running an image as a service, where a first job outputs the Docker credentials so a different job can run the private image. This is the pattern the mask-password default was changed for, and the warning attached to it is the point to weigh: with mask-password set to false, the password is written into the log, and a repository that enables debug logging will capture it in full.

The output names are also more specific than a single pair. The README's example shows an output named docker_username_123456789012_dkr_ecr_us_east_1_amazonaws_com, so the credential is exposed per registry and per account, and the consumer has to name the specific one it wants. That granularity is what lets one login job serve several accounts, but it also means a consumer that hard codes the wrong account id fails at run time with an empty value rather than a clear error.

## Helm works without a second credential because the store is shared

The README notes that Helm uses the same credential store as Docker, so Helm can authenticate with the same credentials used for Docker. That is why the Helm examples need nothing beyond the login step: the action writes the credential into the Docker config, Helm reads the same file, and the chart push works.

The Helm path differs from the image path in the shape of the artifact. An image is tagged and pushed to a repository path, while a chart is packaged first with helm package and then pushed as an OCI artifact with helm push to an oci:// target. The public registry example pushes to oci://$REGISTRY/$REGISTRY_ALIAS, which shows the alias segment again in the artifact path.

This is a good demonstration of why the action is useful beyond the obvious case. Because it authenticates the client rather than the artifact, anything that speaks the same credential store, including Helm, inherits the login for free. The action does not need to know about chart packaging at all.

## The repository ships bundled JavaScript and a cleanup script

The repository layout tells you how the action is built and shipped. The root holds action.yml, index.js and cleanup.js, a dist directory, package.json, package-lock.json, a THIRD-PARTY file, CHANGELOG.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md and a LICENSE. There are also eslint.config.js, .mergify.yml and .versionrc.json.

The build script in package.json is the important part for anyone reviewing the action:

```json
  "scripts": {
    "lint": "eslint **.js",
    "package": "ncc build index.js -o dist && ncc build cleanup.js -o dist/cleanup",
    "test": "eslint **.js && NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --coverage --verbose"
  },
```

Two entries are compiled by ncc into dist, one for the main action and one for the cleanup step, which is the convention for JavaScript actions because the runner executes what is committed rather than installing dependencies at run time. The test command runs eslint and then jest with coverage, and the dev dependencies include aws-sdk-client-mock, which is how the AWS calls are faked in unit tests.

The runtime dependencies are narrow: @actions/core and @actions/exec for the action plumbing, @aws-sdk/client-ecr and @aws-sdk/client-ecr-public for the two registry types, @aws-sdk/credential-providers and @aws-sdk/node-http-handler for the credential and HTTP layers, and https-proxy-agent. The presence of a proxy agent package connects to the self-hosted runner and proxy configuration sections the README's table of contents lists, which matters for runners inside a corporate network.

## MIT licensed, released often, and a dependency on a vendor cadence

The licence is MIT, with the details in the LICENSE file at the root of the repository. For an action whose output is a Docker credential, the licence is the least interesting part of the risk picture. The more relevant question is where the code comes from, and here the answer is that the package metadata names AWS as the author and the repository lives under the aws-actions organisation, with the package name aws-actions-amazon-ecr-login.

The release cadence is visible and healthy by the usual measures. Tags v2.1.5 on 2026-05-06, v2.1.6 on 2026-06-12 and v2.1.7 on 2026-08-19, and the last push to the repository was on 2026-10-14, with package.json carrying version 2.1.7. The README also links a continuous pre-release badge, so a newer build can be tried before it is tagged.

The upgrade cost is therefore low for the common case, because pinning to aws-actions/amazon-ecr-login@v2 keeps you on the major line and lets the tag float within it. The cost concentrates in two places. A major version boundary, as v2 showed, can change a default and break workflows that consumed outputs. And the action's own reach into your pipeline is wider than its name suggests: it holds AWS credentials, it decides what appears in the log, and it sits between your build step and the registry. Treat a major version bump as a change to review, not a routine bump.

## Conclusion

Use amazon-ecr-login if your workflow already runs on GitHub Actions and pushes to ECR, because it removes the hand rolled login step and hands you a registry output you can build tags from. Do not adopt it if your pipeline is not on GitHub Actions, or if your organisation forbids a credential output step entirely. Before you upgrade an existing workflow from v1 to v2, grep the pipeline for steps.login-ecr.outputs.docker_password, because that consumer silently depends on the mask-password default that v2 changed from false to true.

## FAQ

### What does the amazon-ecr-login GitHub Action actually do?

It logs the local Docker client to one or more Amazon ECR Private registries or an ECR Public registry. It does not build, tag or push images; it authenticates the client so that later steps in the same job can use it.

### Why did upgrading to v2 of amazon-ecr-login break my workflow?

In v2 the default of the mask-password input changed from false to true. Workflows that read the Docker password as a step output and relied on the old default break, and the README's fix is to set mask-password: 'false' explicitly in the login step.

### How do I log in to ECR registries in more than one AWS account?

Pass the accounts in the registries input as a comma separated list, for example registries: "123456789012,998877665544". The repository in the second account must explicitly grant access to the IAM role the workflow assumes, otherwise the cross-account login fails.

### Can I push a Helm chart to ECR with the amazon-ecr-login Action?

Yes. The README states that Helm uses the same credential store as Docker, so the login step covers Helm as well, and the chart is then packaged with helm package and pushed with helm push to an oci:// target.

### Is amazon-ecr-login still maintained?

The last push to the repository was on 2026-10-14, after tagged releases v2.1.5 on 2026-05-06, v2.1.6 on 2026-06-12 and v2.1.7 on 2026-08-19. The repository is licensed under MIT and the package metadata names AWS as the author.

## Sources

- [aws-actions/amazon-ecr-login on GitHub](https://github.com/aws-actions/amazon-ecr-login)
- [Issues](https://github.com/aws-actions/amazon-ecr-login/issues)
- [License: MIT](https://github.com/aws-actions/amazon-ecr-login/blob/main/LICENSE)
- [README](https://github.com/aws-actions/amazon-ecr-login/blob/main/README.md)
- [Releases](https://github.com/aws-actions/amazon-ecr-login/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aws-actions-amazon-ecr-login
