How can I deny public access to an AWS API gateway while allowing access by only a specific role?

◇◆丶佛笑我妖孽 提交于 2021-02-11 04:38:09

问题


I would like to deny public access to an AWS API Gateway and only allow access when the API is invoked with a specific role. In my test there are two gateways, and one calls the other:

Public Gateway -> Private Gateway

I want to be able to visit Public Gateway endpoints in a browser and receive a 2XX response, and when visiting the Private Gateway directly I should receive a 4XX response. The only way to access the Private Gateway should be via the Public Gateway (which proxies to the Private Gateway with each endpoint).

I've tried several policies. All of these always result in the Public Gateway error logs showing the following:

User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:********9012:abcd123456/dev/GET/products

That error message is received by the Public Gateway as a response from the Private Gateway.

Here are policies I've tried (separately):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::123456789012:role/test-apigateway-role"
                }
            }
        }
    ]
}

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::123456789012:role/test-apigateway-role",
                    "arn:aws:iam::123456789012:root"
                ]
            },
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*"
        }
    ]
}

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*/*/*",
            "Condition": {
                "ArnNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::123456789012:role/test-apigateway-role"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*/*/*"
        }
    ]
}

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::123456789012:role/test-apigateway-role"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*/*/*"
        }
    ]
}

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::123456789012:role/test-apigateway-role"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*/*/*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::123456789012:role/test-apigateway-role"
                }
            }
        }
    ]
}

I've redeployed with each Resource Policy change and waited one minute before testing.

The role is assigned in the Public Gateway's serverless.yml settings:

service: test-gateway

provider:
  name: aws
  runtime: nodejs12.x
  apiGateway:
    shouldStartNameWithService: true
  role: arn:aws:iam::123456789012:role/test-apigateway-role

回答1:


How about trying this?

According to the docs, if you don't specify an explicit Deny, and then provide a specific Allow, it should work. If it doesn't, keep sharing your outputs, I'm intrigued.

Update: I removed the Deny * part, this means we'll get an implicit deny for requests that are not specifically declared in an Allow statement. This is according to Sessions policies (see docs link)

Update 2: Check this answer's comments, the author also mentioned - added authorizer: aws_iam to serverless.yml

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::123456789012:role/test-apigateway-role"
                ]
            },
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws:execute-api:us-east-1:123456789012:abcd123456/*"
            ]
        }
    ]
}


来源:https://stackoverflow.com/questions/65958741/how-can-i-deny-public-access-to-an-aws-api-gateway-while-allowing-access-by-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!