当我通过假设角色尝试访问不同帐户中的s3存储桶来尝试我的lambda时。我得到GetObject操作:访问被拒绝

时间:2017-12-22 00:36:10

标签: amazon-web-services amazon-s3 amazon-iam

我有一个关于s3和角色如何跨帐户工作的问题。

我有一种情况,我有一个lambda函数,在帐户A中有一个角色,在帐户B中有一个lambda函数需要访问的存储桶。来自帐户A的角色对帐户B中的存储桶具有s3:*权限。我们在帐户B中设置存储桶上的主体以接受来自帐户A的角色。存储桶策略还允许存储桶上的s3:*。像下面的东西。

帐户角色:

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

帐户B广告系列政策:

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

我们遇到的问题是帐户A中的角色能够对帐户B中的存储桶执行所有LIST操作,但是当我们尝试任何GET操作时,我们会拒绝访问。哪个没有意义,因为我们双方都有s3:*权限。

我们在设置存储桶或IAM策略时是否会错过任何能够按预期工作的内容?我们使用与帐户A中的角色相同的策略尝试了一个假定角色,但是在帐户B中并且在帐户B中的存储桶上没有LIST或GET操作的问题。所以有一个解决方法,但我们想看看是否我们可以让原始设置正常工作。

这是我收到的错误消息。

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

1 个答案:

答案 0 :(得分:0)

以下是我从AWS获得的回复....

在s3中,我们拥有拥有该桶的Bucket Owner和拥有该对象的Object Owner。除非对象所有者授予对象权限,否则除了Object所有者之外没有人可以访问它。作为存储桶拥有者或已被授予存储桶权限的任何人都可以列出存储桶,但读/写操作将导致403拒绝访问对象。 对象所有者可以使用--acl bucket-owner-full-control向存储桶拥有者授予权限,这是我在这个S3对象中看到的。

如果对象不属于存储桶拥有者,则存储桶策略不会继承。在这种情况下,桶所有者可以复制对象以获得所有权。完成此操作后,由Bucket Policy授予访问权限的帐户C或X可以访问该对象。

这是我的工作。创建角色" XXX"在帐户B中。并授予访问权限以从帐户B中的s3存储桶读取。

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')