amazon-ecraws-policies

How to make a resource-based policy to allow a single user to access only one repository in AWS ECR


I have created an IAM user (let's call it here "user1") and I want this user to have full access to ECR actions but only on a single repository that is already created (let's call it here "repo1"). This is the json policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ecr:*",
            "Resource": "arn:aws:ecr:eu-west-2:[account_ID]:repository/repo1"
        }
    ]
}

I have checked the ARN and it is correct. However, when I login in the AWS console with user1 account and then go to the ECR service, no repositories are listed even though when I login with my admin account, the repository is definitely there. The following message appears in the console for user1 when I list the repositories in the console:

There was an error fetching the repositories: User:arn:aws:iam::[account_ID]:user/repo1 is not authorized to perform: ecr:DescribeRepositories on resource: arn:aws:ecr:eu-west-2:[account_ID]:repository/* because no identity-based policy allows the ecr:DescribeRepositories action

However, the DescribeRepositories was clearly selected when I built the inline policy and attached it to the user. If the resource is for example:

"Resource": "arn:aws:ecr:eu-west-2:[account_ID]:repository/*"

Then, as logged in with user1, I can see all repositories instead (which is not what I want, I just want user1 to be able to see repo1 in his console). Am I missing any policy?


Solution

  • Someone from AWS is better placed to confirm the following, but here is what I could set:

    1. Using identity-based IAM policy instead of resource based.
    2. Granting pull/push access to the target repo only.
    3. Granting console access, but only using a direct URL to the target repo.
    4. Unable to list only the desired repository (empty list, so the direct link to the target repo).

    The policy is like:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ecr:GetAuthorizationToken"
                ],
                "Resource": "*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "ecr:BatchCheckLayerAvailability",
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:GetRepositoryPolicy",
                    "ecr:ListImages",
                    "ecr:DescribeImages",
                    "ecr:DescribeRepositories",
                    "ecr:BatchGetImage",
                    "ecr:GetLifecyclePolicy",
                    "ecr:GetLifecyclePolicyPreview",
                    "ecr:ListTagsForResource",
                    "ecr:DescribeImageScanFindings",
                    "ecr:InitiateLayerUpload",
                    "ecr:UploadLayerPart",
                    "ecr:CompleteLayerUpload",
                    "ecr:PutImage"
                ],
                "Resource": "arn:aws:ecr:<region>:<account id>:repository/<repo>"
            }
        ]
    }
    

    Users with this policy cannot list repositories at all (point 4). This looks like a limitation of the AWS console. However, these users can access the authorised repo via the API (point 2) and directly in the console with a patterned URL like https://<region>.console.aws.amazon.com/ecr/repositories/private/(account id>/<repo name> (point 3).


    All the confusion comes from the console. It actually works, but there is no cue in the console... The issue comes from how the console deals with ecr:DescribeRepositories. By setting the resource scope to "*", the console works as expected (we can see all repos, but act only on the authorised one). But setting the resource scope to the repo ARN does not seem supported in the console however---it shows an empty list like no repo exists. Yet this last setting is important to ensure users can only describe the intended repo. This just looks like an issue with the console ability to selectively show repos.