Like many things AWS all this information can be found in the AWS docs themselves, but scattered everywhere. This article on service policies (or resource policies) vs IAM permissions provides some background for what we’ll do here.
There are two pieces here:
- 1. The Elastic Container Repository (ECR) in one AWS account (account ID
1111111111
in the examples below). - 2. Another AWS account and IAM entity that needs access to the ECR repo in #1 (account ID
2222222222
in the examples below).
1. Allow Other AWS Accounts to Access ECR
First off, the ECR repository will need a repository policy that says, “Account 2222222222
can access this repository.” In this situation we want to allow read-only access: account 2222222222
should only be able to pull the images.
This repository policy, in JSON, should look something like this:
{ "Version": "2012-10-17", "Statement": [{ "Sid": "Allow2222222222Access", "Effect": "Allow", "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ], "Principal": { "AWS": "arn:aws:iam::2222222222:root" } }] }
This policy will allow any IAM entity in account 2222222222
read-only access to the repository. This can be restricted to specific IAM entities by adjusting the principal ARN.
2. Allow the IAM Entity in the Client Account to Talk to ECR
The thing about service policies is that they only define what entities are allowed to access the resource, but those entities still need permissions to do so within the IAM system of the account itself.
More concretely: the repository policy above says, “Yeah, account 2222222222
can get images from this repository,” but the IAM system in account 2222222222
still has to allow those ECR actions to be called. An IAM policy for this looks nearly identical to the repository policy — just swap the Principal
for Resources
. We also need to allow the IAM entity to get an authorization token to authenticate with docker login
{ "Version": "2012-10-17", "Statement": [{ "Sid": "AllowAccessToExampleRepo", "Effect": "Allow", "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ], "Resource": [ "arn:aws:ecr:us-east-1:1111111111:repository/example" ] }, { "Sid": "AllowLogin", "Effect": "Allow", "Action": [ "ecr:GetAuthorizationToken" ], "Resource": ["*"] }] }
This will only allow an IAM entity (user, group, role, etc) access to the example repository. Note that entitys with power user access or admin access (the dreaded "Action": "*:*"
won’t need this. When I had to do this earlier this year, it was to allow a IAM user used by TravisCI access to a repository and I did use this restricted permission set.
3. Getting ECR Credentials for docker login
If using the AWS CLI, set the --registry-ids
flag when invoking the ecr get-login
command:
aws ecr get-login --registry-ids 1111111111
A registryIds
can also be set if using the ecr:GetAuthorizationToken API.
The important thing here is that the ecr:GetAuthorizationToken
call (via the CLI or otherwise) is happening on the calling account (2222222222
in our exmaple). The IAM entity is not getting an authorization token from account 1111111111
where the repository resides. The registry IDs only impact the generate docker login
command when using the AWS CLI, in other words.