-1

I am trying to create an IAM policy that allows some actions on a resource, but only if the access key is used from a specific Elastic Beanstalk application or container. Does anyone know how to do this? I tried this, but to no avail:

"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
    "ArnEquals": {
        "aws:SourceArn": "arn:aws:elasticbeanstalk:..."
    }
}

Restricting by ip instead works, but Elastic Beanstalk environments frequently change the ips of the servers that they create, so this is not a viable option:

"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
    "IpAddress": {
        "aws:SourceIp": "..."
    }
}
kloddant
  • 1,026
  • 12
  • 19
  • 'but to not avail" is not specific. What **exactly** is happening? Any errors? – Marcin Mar 30 '23 at 23:52
  • Yes, the error message says that the IAM user has insufficient permissions. – kloddant Mar 31 '23 at 13:03
  • An error occurred (AccessDenied) when calling the CreateInvalidation operation: User: arn:aws:iam:::user/ is not authorized to perform: cloudfront:CreateInvalidation on resource: arn:aws:cloudfront:::distribution/ because no identity-based policy allows the cloudfront:CreateInvalidation action. – kloddant Mar 31 '23 at 13:17
  • Could we see the whole permission statement that you're trying to use? – user3553031 Apr 07 '23 at 17:20
  • @user3553031 I just added in the sid, effect, and action, if that makes it any clearer. I am trying to allow S3 access to an IAM user whose access key is used from instances created by a specific Elastic Beanstalk application. So the access key is stored in the application's environment variables, and it is used by the instances. I want to restrict it so that it can only be used from those instances, so that if a hacker somehow gets the access key, they would also need to be able to ssh into the instances to use it. – kloddant Apr 10 '23 at 15:04

1 Answers1

0

I'm not familiar with Elastic Beanstalk, but here are two things that you can try.

  1. Are your Elastic Beanstalk Instances in a VPC? If so, you could create a VPC Endpoint for S3, make all of your S3 calls through the Endpoint, and use the aws:SourceVpc condition key:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "s3:*",
          "Resource": "arn:aws:s3:::example-bucket/*",
          "Condition": {
            "StringEquals": {
              "aws:SourceVpc": "vpc-1234abcd"
            }
          }
        }
      ]
    }
    
  2. Unfortunately, aws:SourceArn is only defined for calls made by a Service Principal. Presumably, your calls to S3 are being made by a Role. However, Elastic Beanstalk's Service Principal has to make the call to sts:AssumeRole to get those Role credentials. Rather than putting aws:SourceArn constrains on your calls to S3, you could consider putting them on the Trust Policy that controls access to your Role:

     {
       "Version": "2012-10-17",
       "Statement": [
         {
           "Effect": "Allow",
           "Principal": {
             "Service": "elasticbeanstalk.amazonaws.com"
           },
           "Action": "sts:AssumeRole",
           "Condition": {
             "ArnLike": {
               "aws:SourceArn": "arn:aws:elasticbeanstalk:..."
             }
           }
         }
       ]
     }
    
user3553031
  • 5,990
  • 1
  • 20
  • 40