允许跨账户 Lambda 函数写入 S3 的 IAM 存储桶策略

IAM bucket policy to allow cross-account Lambda function to write to S3

我很难弄清楚如何完成这项工作。我们的客户端运行 Lambda 函数来生成数据以写入我们的存储桶。 Lambda 承担了一个角色,因此(我认为)我们所有允许客户端的整个帐户访问存储桶的尝试仍然会导致 AccessDenied 错误。

在查看我们的日志时,我看到为 STS 代入角色返回了 AccessDenied。但是,S3 控制台不允许我为通配符主体添加策略,并且假定角色的会话 ID 会在每个会话中更改。

根据稀疏的文档,我的猜测是我们需要为 lambda.amazonaws.com 服务提供信任关系。但是我在任何地方都找不到任何关于如何将其限制为仅从特定 Lambda 函数或帐户访问的文档。

我想要这样的东西,但对 Principal 有进一步的限制,因此任何帐户或 Lambda 函数都无法访问它。

{
    "Version": "2012-10-17",
    "Id": "Policy11111111111111",
    "Statement": [
        {
            "Sid": "Stmt11111111111111",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "lambda.amazonaws.com"
                ]
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::bucket-name-here/*",
                "arn:aws:s3:::bucket-name-here"
            ]
        }
    ]
}

更新

这个政策根本不管用。它仍然 returns 拒绝访问。日志中列出的用户格式为 arn:aws:sts::111111222222:assumed-role/role-name/awslambda_333_201512111822444444.

因此,我什至不知道如何允许 Lambda 函数写入 S3 存储桶。

在 IAM 团队的帮助下,我们最终解决了这个问题。

IAM 角色不会继承帐户的任何权限,因此他们需要明确分配给 Lambda 脚本的 assumed role 权限。

在我们的案例中,Lambda 脚本还试图授予目标存储桶所有者对复制文件的完全控制权。 Lambda 函数担任的角色缺少 s3:PutObjectAcl 的权限。 添加权限后,lambda 函数开始正常工作。

我们现在使用的目标策略是这样的:

{
  "Version": "2012-10-17",
  "Id": "Policy11111111111111",
  "Statement": [
    {
        "Sid": "Stmt11111111111111",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:ListBucket*",
        "Resource": "arn:aws:s3:::bucket-name",
        "Condition": {
            "StringLike": {
                "aws:userid": "ACCOUNT-ID:awslambda_*"
            }
        }
    },
    {
        "Sid": "Stmt11111111111111",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::bucket-name/*",
        "Condition": {
            "StringLike": {
                "aws:userid": "ACCOUNT-ID:awslambda_*"
            }
        }
    },
    {
        "Sid": "Stmt11111111111111",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::0000000000000:root"
        },
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::bucket-name"
    },
    {
        "Sid": "Stmt11111111111111",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::0000000000000:root"
        },
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::bucket-name/*"
    }
  ]
}

To Allow Cross account lambda function to get access of s3 bucket
following policy we need to add to s3 bucket policy externally
{
            "Sid": "AWSLambda",
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com",
                "AWS": "arn:aws:iam::<AccountID>:root"
            },
            "Action": "s3:GetObject",
            "Resource": "<AWS_S3_Bucket_ARN>/*"
        }

Following Template will help you to allow cross account Lambda function to access s3 bucket

Parameters:
  LamdaAccountId:
    Description: AccountId to which allow access
    Type: String
Resources:
  myBucket:
    Type: 'AWS::S3::Bucket'
    Properties: {}
    Metadata:
      'AWS::CloudFormation::Designer':
        id: e5eb9fcf-5fe2-468c-ad54-b9b41ba1926a
  myPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: !Ref myBucket
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: Stmt1580304800238
            Action: 's3:*'
            Effect: Allow
            Resource:
              - !Sub 'arn:aws:s3:::${myBucket}/*'
            Principal:
              Service: lambda.amazonaws.com
              AWS:
                - !Sub '${LamdaAccountId}'