0

I have an Amazon S3 bucket "my-bucket" on a AWS account. Right now everyone on the account can download and put objects to "my-bucket. However, I would like everyone to be able to download/delete objects from the bucket, and only one service role (lambda) to be able to put objects to the bucket.

The lambda role already have access to PutObjects to the bucket, so I guess I would want to make a bucket policy to only allow my lambda role to PutObjects but still allow everyone else to download/delete objects on the bucket. I am however not sure how that bucket policy would look like. I guess I have to use a condition? Something like?

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"MyRule",
      "Effect": "Deny",
      "Action":["s3:PutObject"],
      "Resource": ["arn:aws:s3:::my-bucket/*", "arn:aws:s3:::my-bucket*"],
      "Condition":{"NOT EQUAL TO LAMBDA ROLE???"}
    }
  ]
}
smac2020
  • 9,637
  • 4
  • 24
  • 38
smallbirds
  • 877
  • 12
  • 35

2 Answers2

2

Bucket policy is resourced based policy so principle can be used to restrict the access to specific identity you can prepare policy like below for everyone to download and delete object

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"PublicReadDelete",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject","s3:DeleteObject"],
      "Resource":["arn:aws-cn:s3:::/*"]
    }
  ]
}

below policy for lambda to put objects

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"LambdaUpload",
      "Effect":"Allow",
      "Principal": "<your lambda function ARN>",
      "Action":["s3:PutObject"],
      "Resource":["arn:aws-cn:s3:::/*"]
    }
  ]
}

you can combine both statement in same policy. you just need replace your lambda function ARN and S3 bucket ARN or name

Deepak Gupta
  • 387
  • 2
  • 17
1

You can achieve this in two ways:

  1. By using Principal, where you will explicitly list your Lambda role arn
  2. By using a Deny statement with a Condition (the method you are suggesting).

With option 1, you will have something like:

      "Sid": "AllowPutForLambda",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::01234567890:role/my-lambda-role"
        ]
      },
      "Action": [
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/*"
    }

With Option 2, it will look like this:

    {
      "Sid": "DenyAllExceptMyPreciousLambda",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket/*",
        "arn:aws:s3:::my-bucket"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userid": [
            "AROAID1GMAMBDAROLEID:*",

          ]
        }
      }

where the "AROAID1GMAMBDAROLEID" string is the unique identifier of the calling entity (in this case the IAM UserId for the Lambda IAM role).

You can get the unique ID of your lambda role by using the get-role aws-cli command:

aws iam get-role --role-name MyLambdaRoleName

Nick
  • 1,203
  • 5
  • 8