Skip to content

Latest commit

 

History

History
 
 

bucket-owner-full-control

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

bucket-owner-full-control

AWS Lambda function to grant the bucket owner full control over an S3 object.

Setup

Prerequisites

This setup assumes two AWS accounts. The main account (Account A) grants another account (Account B) access to an S3 bucket via bucket policy, e.g. the following:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT_ID:root"
      },
      "Action": "s3:*",
      "Resource": ["arn:aws:s3:::BUCKET_NAME", "arn:aws:s3:::BUCKET_NAME/*"]
    }
  ]
}

Ideally this bucket policy would restrict S3 uploads to always set the bucket-owner-full-control canned ACL.

A sample bucket policy with this restriction would be the following:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT_ID:root"
      },
      "Action": "s3:*",
      "Resource": ["arn:aws:s3:::BUCKET_NAME", "arn:aws:s3:::BUCKET_NAME/*"]
    },
    {
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT_ID:root"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::BUCKET_NAME/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    }
  ]
}

A sample s3 put-object command with the required bucket-owner-full-control ACL as argument:

aws s3api put-object \
  --bucket BUCKET_NAME \
  --key test.txt \
  --body test.txt \
  --acl bucket-owner-full-control

In cases where this is not possible, e.g. when allowing uploads with an S3 application like Cyberduck, this Lambda function comes in handy.

IAM roles creation

In Account B, create a new cross-account IAM role. Fill in the account ID of Account A as account that can use this role. As role name, choose bucket-owner-full-control-role.

After creating the role, attach the following inline policy, replacing BUCKET_NAME with the name of your bucket:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:PutObjectAcl",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      },
      "Resource": "arn:aws:s3:::BUCKET_NAME/*"
    }
  ]
}

In Account A, create a new Lambda service role with the managed AWSLambdaBasicExecutionRole attached. As role name choose aws-lambda-bucket-owner-role.

After creating the role, attach the following inline policy, replacing ACCOUNT_ID with the account ID of Account B:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::ACCOUNT_ID:role/bucket-owner-full-control-role"
    }
  ]
}

Function configuration

Add the function code to AWS Lambda with the following configuration options:

Key Value
Runtime Node.js 10.x
Handler index.handler
Role aws-lambda-bucket-owner-role
Memory 128 (MB)
Timeout 3 sec

Environment variables

Set the following required environment variable for the Lambda function:

Key Value
rolearn The ARN of the bucket-owner-full-control-role of Account B.

Trigger configuration

Add an S3 trigger for your bucket with the PUT event type.
test-event.json contains a sample S3 PUT event.

License

Released under the MIT license.

Author

Sebastian Tschan