Search code examples
amazon-web-servicesapiamazon-iamaws-api-gateway

Understanding Allow and Deny statements in AWS permission policies


I have a question about my API Gateway configuration.

  1. My ressource policy looks like this
1  {
2    "Version": "2012-10-17",
3    "Statement": [
4        {
5            "Sid": "",
6            "Effect": "Deny",
7            "Principal": "*",
8            "Action": "execute-api:Invoke",
9            "Resource": "arn:aws:execute-api:eu-west-3:999999999999:0123456789/compliance/POST/*",
10           "Condition": {
11               "StringNotEquals": {
12                   "aws:sourceVpce": "vpce-fffffffffffffffff"
13               }
14           }
15       },
16       {
17           "Sid": "",
18           "Effect": "Allow",
19           "Principal": "*",
20           "Action": "execute-api:Invoke",
21           "Resource": "arn:aws:execute-api:eu-west-3:999999999999:0123456789/compliance/POST/*"
22       }
23   ]
24 }
  1. In the settings

Endpoint type for my API is private
I added the VPC endpoint ID I configured for API Gateway : vpce-fffffffffffffffff

Did I configure the same thing twice ?
If I didn't what is the difference then ?
If I did, what should I chose between policy and parameters ?

Last question : is my policy well written ? I feel like I could remove the "Allow" part (lines 16 to 22)

Thank you


Solution

  • No, you do not have the same thing twice, and no, removing the "Allow" statement would break your policy.

    "Deny" statements, such as the one at lines 4-15, can never grant permissions, no matter how they are written. They simply override any "Allow" statements that might also apply (Amazon's documentation). So what you have is "Allow anyone anywhere to POST to this APIGW, unless the call doesn't come from VPC Endpoint vpce-fffffffffffffffff".

    While this is a somewhat odd way to write a policy, it works. However, keep in mind that "Principal": "*" allows unauthenticated access; is this really what you want? The only thing in the policy that prevents Internet randos from calling your APIGW is the restriction to a specific VPC Endpoint in the Deny statement. At the very least, you should change that to something like

    "Principal": {
      "AWS": "999999999999"
    }
    

    That would permit all principals in your account to call the APIGW.

    The empty Sid fields do nothing; you can remove those if you want.

    A more concise, though not completely equivalent, way to write this policy would be:

    1  {
    2    "Version": "2012-10-17",
    3    "Statement": [
    4      {
    5        "Effect": "Allow",
    6        "Principal": {
    7          "AWS": "999999999999"
    8        },
    9        "Action": "execute-api:Invoke",
    10       "Resource": "arn:aws:execute-api:eu-west-3:999999999999:0123456789/compliance/POST/*",
    11       "Condition": {
    12         "StringEquals": {
    13           "aws:sourceVpce": "vpce-fffffffffffffffff"
    14         }
    15       }
    16     }
    17   ]
    18 }
    

    This would allow anyone in your account to call the APIGW through VPC Endpoint vpce-fffffffffffffffff. The main different here is that identity-based policies (ones attached to your users and roles) could give permission to call the APIGW without requiring that VPC Endpoint. Deny statements, no matter where they are located, always override Allow statements, so your policy prevents any policy statement attached to a principal from allowing access to your APIGW without using that VPCE. If this is a concern to you, keep the Deny statement.