Nagalakshmi Srirama
Nagalakshmi Srirama

Reputation: 1021

when I try my lambda by assuming role tried to access s3 bucket in different account. I get GetObject operation: Access Denied

I have a question regarding how s3 and roles work across accounts.

I have a situation where I have a lambda function with a role in account A and a bucket in account B that the lambda function needs to access. The role from account A has s3:* permissions on the bucket in account B. We set the principal on the bucket in account B to accept the role from account A. The bucket policy also allows s3:* on the bucket. Something like below.

Account A Role:

{
    "Action": [
        "s3:*"
    ],
    "Resource": [
        "arn:aws:s3:::bucket/*",
        "arn:aws:s3:::bucket"
    ],
    "Effect": "Allow"
}

Account B Bucket Policy:

{
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::account:role/role"
    },
    "Action": "s3:*",
    "Resource": ["arn:aws:s3:::bucket/*","arn:aws:s3:::bucket"]
}

The problem we are running into is that the role in account A is able to do all LIST actions on the bucket in account B, but when we try any GET actions we get access denied. Which doesn't make sense because we have s3:* permissions on both sides.

Is there something that we missed in the setup of the bucket or IAM policy that would get this working as we expect? We tried an assume role with the same policy as the role in account A , but in account B and had no issues with LIST or GET actions on the bucket in account B. So there is a work around, but we would like to see if we can get the original setup working.

This is the error message I am getting.

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

Upvotes: 0

Views: 1674

Answers (1)

Nagalakshmi Srirama
Nagalakshmi Srirama

Reputation: 1021

Here is the response I got from AWS....

In s3, we have Bucket Owner who owns the bucket and Object Owner who owns the object. Unless the Object Owner grants permission to the object no one apart from the Object owner has access to it. As bucket owner or anyone who has been granted permission to the bucket can LIST the bucket, but read / write operations would result into 403 Access Denied for the objects. An object owner could grant permissions to the bucket owner using --acl bucket-owner-full-control which is what I see for this S3 object in question.

When you objects NOT owned by the bucket owner, bucket policies do not inherit. In such case, the bucket owner may copy over the object to gain the ownership. Once this is done, Account C or X which are granted access by the Bucket Policy would have access to the object.

Here is my work around for that. Create a role "XXX" in Account B. And grant access to read from s3 bucket in account B.

import boto3
sts_client = boto3.client('sts')
assumed_role_object = sts_client.assume_role(
        RoleArn="<ARN of role XXX>",
        RoleSessionName="AssumeRoleSession1"
    )
# From the response that contains the assumed role, get the temporary
# credentials that can be used to make subsequent API calls

credentials = assumed_role_object['Credentials']
s3_client = boto3.client(
    service_name='s3',
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken']
)
response = s3_client.get_object(Bucket=self.bucket, Key=file_name)
file_content = response['Body'].read().decode('utf-8')

Upvotes: 1

Related Questions