sdot257
sdot257

Reputation: 10366

S3 bucket policy multiple conditions

I'm looking to grant access to a bucket that will allow instances in my VPC full access to it along with machines via our Data Center. Without the aws:SouceIp line, I can restrict access to VPC online machines.

I need the policy to work so that the bucket can only be accessible from machines within the VPC AND from my office.

{
    "Version": "2012-10-17",
    "Id": "Policy1496253408968",
    "Statement": [
        {
            "Sid": "Stmt1496253402061",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::xyz-sam-test/*",
                "arn:aws:s3:::xyz-sam-test"
            ],
            "Condition": {
                "StringLike": {
                    "aws:sourceVpc": "vpc-dcb634bf",
                    "aws:SourceIp": "<MY PUBLIC IP>"                                  
                }
            }
        }
    ]
}

Upvotes: 9

Views: 14221

Answers (3)

Tom
Tom

Reputation: 2888

this is an old question, but I think that there is a better solution with AWS new capabilities. Especially, I don't really like the deny / StringNotLike combination, because denying on an s3 policy can have unexpected effects such as locking your own S3 bucket down, by denying yourself (this could only be fixed by using the root account, which you may not have easily accessible in a professional context)

So the solution I have in mind is to use ForAnyValue in your condition (source). e.g something like this:

{
    "Version": "2012-10-17",
    "Id": "Policy1496253408968",
    "Statement": [
        {
            "Sid": "Stmt1496253402061",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::xyz-sam-test/*",
                "arn:aws:s3:::xyz-sam-test"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:sourceVpc": [
                         "vpc-dcb634bf",
                         "<MY PUBLIC IP>"       
                    ]                              
                }
            }
        }
    ]
}

Upvotes: 3

chocokoala
chocokoala

Reputation: 351

AWS has predefined condition operators and keys (like aws:CurrentTime). Individual AWS services also define service-specific keys.

As an example, assume that you want to let user John access your Amazon SQS queue under the following conditions:

The time is after 12:00 p.m. on 7/16/2019

The time is before 3:00 p.m. on 7/16/2019

The request comes from an IP address within the range 192.0.2.0 to 192.0.2.255 or 203.0.113.0 to 203.0.113.255.

Your condition block has three separate condition operators, and all three of them must be met for John to have access to your queue, topic, or resource.

The following shows what the condition block looks like in your policy. The two values for aws:SourceIp are evaluated using OR. The three separate condition operators are evaluated using AND.

"Condition" :  {
      "DateGreaterThan" : {
         "aws:CurrentTime" : "2019-07-16T12:00:00Z"
       },
      "DateLessThan": {
         "aws:CurrentTime" : "2019-07-16T15:00:00Z"
       },
       "IpAddress" : {
          "aws:SourceIp" : ["192.0.2.0/24", "203.0.113.0/24"]
      }
}

reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_multi-value-conditions.html

Upvotes: 2

Oluwafemi Sule
Oluwafemi Sule

Reputation: 38982

You can generate a policy whose Effect is to Deny access to the bucket when StringNotLike Condition for both keys matches those specific wildcards.

{
    "Version": "2012-10-17",
    "Id": "Policy1496253408968",
    "Statement": [
        {
            "Sid": "Stmt1496253402061",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::xyz-sam-test/*",
                "arn:aws:s3:::xyz-sam-test"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:sourceVpc": "vpc-dcb634bf",
                    "aws:SourceIp": "<MY PUBLIC IP>"                                  
                }
            }
        }
    ]
}

The second condition could also be separated to its own statement. AWS applies a logical OR across the statements. 1

{
    "Version": "2012-10-17",
    "Id": "Policy1496253408968",
    "Statement": [
        {
            "Sid": "Stmt1496253402061",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::xyz-sam-test/*",
                "arn:aws:s3:::xyz-sam-test"
            ],
            "Condition": {
                "StringLike": {
                    "aws:sourceVpc": "vpc-dcb634bf",                                
                }
            }
        },
        {
            "Sid": "Stmt1496253402062",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::xyz-sam-test/*",
                "arn:aws:s3:::xyz-sam-test"
            ],
            "Condition": {
                "StringLike": {
                    "aws:SourceIp": "<MY PUBLIC IP>"                                  
                }
            }
        }
    ]
}

Upvotes: 4

Related Questions