Reputation: 3176
Based on some resource that mostly show how to restrict by separate option such as IP or by VPC or VPCE, this is what I'm trying to use, would this work?
Trying to open access to S3 bucket only from public IP: "12.34.56.78/32" and VPC endpoint: "vpce-xxxxxxxx"
{
"Version": "2008-10-17",
"Id": "S3Policy-Restrict-Access",
"Statement": [
{
"Sid": "IPDeny",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws-us-gov:s3:::myrestrict-access-test/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"12.34.56.78/32"
]
},
"StringNotEquals": {
"aws:sourceVpce": "vpce-xxxxxxxx"
}
}
}
]
}
Upvotes: 0
Views: 2131
Reputation: 10943
The answer is on AWS documentation related to ...IfExists Condition Operators
You can add IfExists to the end of any condition operator name except the Null condition—for example, StringLikeIfExists. You do this to say "If the policy key is present in the context of the request, process the key as specified in the policy. If the key is not present, I don't care; don't fail the comparison because of its absence." Other condition elements in the statement can still result in a nonmatch, but not a missing key when checked with ...IfExists.
Example using IfExists
Many condition keys describe information about a certain type of resource and only exist when accessing that type of resource. These condition keys are not present on other types of resources. This doesn't cause an issue when the policy statement applies to only one type of resource. However, there are cases where a single statement can apply to multiple types of resources, such as when the policy statement references actions from multiple services or when a given action within a service accesses several different resource types within the same service. In such cases, including a condition key that applies to only one of the resources in the policy statement can cause the Condition element in the policy statement to fail such that the statement's "Effect" does not apply.
{
"Version": "2012-10-17",
"Statement": {
"Sid": "THISPOLICYDOESNOTWORK",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {"StringLike": {"ec2:InstanceType": [
"t1.*",
"t2.*",
"m3.*"
]}}
}
}
The intent of the preceding policy is to enable the user to launch any instance that is type t1, t2 or m3. However, launching an instance actually requires accessing many resources in addition to the instance itself; for example, images, key pairs, security groups, etc. The entire statement is evaluated against every resource that is required to launch the instance. These additional resources do not have the ec2:InstanceType condition key, so the StringLike check fails, and the user is not granted the ability to launch any instance type. To address this, use the StringLikeIfExists condition operator instead. This way, the test only happens if the condition key exists. You could read the following as: "If the resource being checked has an "ec2:InstanceType" condition key, then allow the action only if the key value begins with "t1.", "t2.", or "m3.*". If the resource being checked does not have that condition key, then don't worry about it."
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {"StringLikeIfExists": {"ec2:InstanceType": [
"t1.*",
"t2.*",
"m3.*"
]}}
}
}
You condition should be:
"Condition": {
"NotIpAddressIfExists": {
"aws:SourceIp": [
"12.34.56.78/32"
]
},
"StringNotEqualsIfExists": {
"aws:sourceVpce": "vpce-xxxxxxxx"
}
}
Explanation
When defining policies, if the request is coming through a VPC Endpoint, source IP key is not available. Similarly, if the request is coming outside of VPC endpoint, VPC related keys are not available. IfExists needs to be used to evaluate keys that are conditionally available.
Upvotes: 2