amazon-web-servicesamazon-s3aws-lambdaaws-sam

Restrict public access to S3 bucket, but allow access for Lambdas


I'm trying define an S3 bucket which has public access disabled, but my other defined Lambdas can access it. I keep receiving an error on deployment about "Invalid principal in policy".

This is my resource definition...

ResultsBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref ResultsBucket
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Deny
          Action: s3:GetObject
          Resource: !Sub '${ResultsBucket.Arn}/*'
          Principal: '*'
        - Effect: Allow
          Action: s3:GetObject
          Resource: !Sub '${ResultsBucket.Arn}/*'
          Principal:
            AWS:
              - !GetAtt ExampleFunction.Role
              - !GetAtt AnotherExampleFunction.Role

I've also tried...

- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${ExampleFunction.Arn}'
- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${AnotherExampleFunction.Arn}'

And

- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${ExampleFunction.Arn}'
- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${AnotherExampleFunction.Arn}'

Solution

  • Amazon S3 buckets are private by default. Therefore, you do not need to do anything to prohibit public access.

    Instead, just add an Allow policy to the IAM Role used by the AWS Lambda function.

    An IAM Role is preferable to creating a Bucket Policy. In general, Bucket Policies are only used for:

    It is more appropriate to add the policy to the IAM Role used by the Lambda function since it can be deployed together with the Lambda function, without impacting what might already be in the Bucket Policy.