'Cross account access to a CodeArtifact repo

I have an IAM user in account A with admin privileges and arn:aws:iam::aws:policy/AWSCodeArtifactReadOnlyAccess attached for good measure.

The iam user from account A has an arn of arn:aws:iam::***:user/test-user.

Account B has a CodeArtifact repo with an arn of arn:aws:codeartifact:***:***:domain/test-repo. This repo has a resource policy of

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::***:user/test-user"
            },
            "Action": "codeartifact:*",
            "Resource": "*"
        }
    ]
}

When running AWS CLI commands, I'm using the access keys for the IAM user from account A. The following command works:

$ aws codeartifact get-repository-endpoint --domain test-repo --domain-owner *** --query repositoryEndpoint --output text --repository test --format pypi

Results in

https://test-repo-***.d.codeartifact.***.amazonaws.com/pypi/test/

This demonstrates that my resource policy is working (flipping the Effect to a Deny successful makes the above command fail).

However, the following command

$ aws codeartifact get-authorization-token --domain test-repo --domain-owner *** --query authorizationToken --output text

fails with

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam:::user/test-user is not authorized to perform: codeartifact:GetAuthorizationToken on resource: arn:aws:codeartifact::***:domain/test-repo

I believe I've followed the docs here:

I would like to accomplish this with the specified principal and would like to not assume a role as it complicates my CI/CD pipeline



Solution 1:[1]

I was having this same issue for a couple days, finally figured out there needs to be a policy applied to both the repository AND the codeartifact domain.

This example uses an organization based policy but any principal should work, the only other important part is the permission of sts:GetServiceBearerToken

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ContributorPolicy",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "codeartifact:*",
                "sts:GetServiceBearerToken"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-xxxxxxxxxx"
                }
            }
        }
    }
}

Solution 2:[2]

As per the documentation, you will be required to add "sts:GetServiceBearerToken" access in your access policy as well.

The codeartifact:GetAuthorizationToken and sts:GetServiceBearerToken permissions are required to call the GetAuthorizationToken API.

Secondly, in your user's permissions, explicitly mention the codeartifact resource in your access policy, same as you have mentioned the IAM User in the resource policy.

e.g.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "codeartifact:*"
            ],
            "Effect": "Allow",
            "Resource": "<insert cross account resource's ARN>"
        },
        {
            "Effect": "Allow",
            "Action": "sts:GetServiceBearerToken",
            "Resource": "<insert cross account resource's ARN>",
            "Condition": {
                "StringEquals": {
                    "sts:AWSServiceName": "codeartifact.amazonaws.com"
                }
            }
        }
    ]
}

Solution 3:[3]

We had to do a few things:

  1. AWS Account with CodeArtifact: (Domain level) > Edit/Create Policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<OTHER_AWS_ACCCOUNT_ID>:root"
            },
            "Action": "codeartifact:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}
  1. AWS Account with CodeArtifact: (Repository level) > Edit/Create Policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<OTHER_AWS_ACCCOUNT_ID>:root"
            },
            "Action": [
                "codeartifact:GetRepositoryEndpoint",
                "codeartifact:ReadFromRepository"
            ],
            "Resource": "arn:aws:codeartifact:*:<CURRENT_AWS_ACCCOUNT_ID>:repository/<REPOSITORY_NAME>/*"
        }
    ]
}
  1. AWS Account with Amplify App: (different account than 1 & 2 above) General > Service Role > Edit/Create Service Role
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "codeartifact:GetAuthorizationToken",
                "codeartifact:GetRepositoryEndpoint",
                "codeartifact:ReadFromRepository",
                "sts:GetServiceBearerToken"
            ],
            "Resource": "*"
        }
    ]
}

This solved our cross-account NPM package running angular app.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 user1653042