AWS : User is not authorized to perform <Action> on on resource <Resource>

398 views Asked by At

I'm trying to invoke Entity Resolution APIs

IAM User Details:

  • IAM User: user1
  • Policy Name: AssumeRolePolicy

I generated Access key and secret for user1 and using those in my spring boot application.

Policy Attached to user1 (AssumeRolePolicy):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::004724176825:role/scv-er-poc-er-service-sbox"
        }
    ]
}

Role Details (scv-er-poc-er-service-sbox). This role has AWSEntityResolutionConsoleFullAccess policy attached to it.:

In Trusted Entities:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::004724176825:user/user1",
                "Service": "entityresolution.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Despite the policies and role configuration, an error occurs with the message:

User: arn:aws:iam::004724176825:user/user1 is not authorized to perform: entityresolution:GetMatchId on resource: arn:aws:entityresolution:eu-west.

Which is the step iam missing in this flow ?

enter image description here

My Java code :

   @Bean
    public EntityResolutionClient entityResolutionClient() {
        AwsCredentials credentials = AwsBasicCredentials.create("<Access key>",
                "<Secret>");
        StaticCredentialsProvider staticProvider = StaticCredentialsProvider.create(credentials);

        Region region = Region.EU_WEST_1;
        EntityResolutionClient entityResolutionClient = EntityResolutionClient.builder()
                .region(region)
                .credentialsProvider(staticProvider)
                .build();
        return entityResolutionClient;
    }
2

There are 2 answers

0
Arpit Jain On BEST ANSWER

The IAM user has to assume the role with the AWS Security Token Service (AWS STS) AssumeRole API operation. This operation will provide you with temporary security credentials (AccessKeyId, SecretAccessKey, SessionToken) that will enable the user to access the AWS resources (in your case Entity Resolution). The below AWS doc example shows how to obtain temporary security credentials and use them to authenticate your requests to Amazon S3 in Java:

public class MakingRequestsWithIAMTempCredentials {
    public static void main(String[] args) {
        String clientRegion = "*** Client region ***";
        String roleARN = "*** ARN for role to be assumed ***";
        String roleSessionName = "*** Role session name ***";
        String bucketName = "*** Bucket name ***";

        try {
            // Creating the STS client is part of your trusted code. It has
            // the security credentials you use to obtain temporary security credentials.
            AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
                                                    .withCredentials(new ProfileCredentialsProvider())
                                                    .withRegion(clientRegion)
                                                    .build();

            // Obtain credentials for the IAM role. Note that you cannot assume the role of an AWS root account;
            // Amazon S3 will deny access. You must use credentials for an IAM user or an IAM role.
            AssumeRoleRequest roleRequest = new AssumeRoleRequest()
                                                    .withRoleArn(roleARN)
                                                    .withRoleSessionName(roleSessionName);
            AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
            Credentials sessionCredentials = roleResponse.getCredentials();
            
            // Create a BasicSessionCredentials object that contains the credentials you just retrieved.
            BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
                    sessionCredentials.getAccessKeyId(),
                    sessionCredentials.getSecretAccessKey(),
                    sessionCredentials.getSessionToken());

            // Provide temporary security credentials so that the Amazon S3 client 
        // can send authenticated requests to Amazon S3. You create the client 
        // using the sessionCredentials object.
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                                    .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                                    .withRegion(clientRegion)
                                    .build();

            // Verify that assuming the role worked and the permissions are set correctly
            // by getting a set of object keys from the bucket.
            ObjectListing objects = s3Client.listObjects(bucketName);
            System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
        }
        catch(AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process 
            // it, so it returned an error response.
            e.printStackTrace();
        }
        catch(SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}

You can also use AWS STS GetCallerIdentity to verify that you assumed the scv-er-poc-er-service-sbox.

Hope it helps.

0
Dingo On

You must assume the role first, then use those credentials (since they have the permission to call via AWSEntityResolutionConsoleFullAccess).

Assuming a role example:

        RoleArn=assume_role_arn,
        RoleSessionName=session_name,
        SerialNumber=mfa_serial_number,
        TokenCode=mfa_totp,
    )
    temp_credentials = response["Credentials"]
    print(f"Assumed role {assume_role_arn} and got temporary credentials.")

    s3_resource = boto3.resource(
        "s3",
        aws_access_key_id=temp_credentials["AccessKeyId"],
        aws_secret_access_key=temp_credentials["SecretAccessKey"],
        aws_session_token=temp_credentials["SessionToken"],
    )

    print(f"Listing buckets for the assumed role's account:")
    for bucket in s3_resource.buckets.all():
        print(bucket.name)