Solution 1:

This seems to be a huge missing piece for the API gateway technology, given the way it's pushed. Not being able to call into an internal-facing server in the VPC severely restricts its usefulness as an authentication front-door for internet access. FWIW, in Azure, API Management supports this out of the box - it can accept requests from the internet and call directly into your virtual network which is otherwise firewalled off. The only way this seems to be possible under AWS is using Lambdas, which adds a significant layer of complexity, esp. if you need to support various binary protocols.

Solution 2:

Looks like this support has now been added. Haven't tested, YMMV:

https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/

Solution 3:

We decided to use a header to check to make sure all traffic is coming through API Gateway. We save a secret in our apps environmental variables and tell the API Gateway to inject that when we create the API. Then check for that key in our app.

Here is what we are doing for this:

In our base controller we check for the key (we just have an REST API behind the gateway):

string ApiGatewayPassthroughHeader = context.HttpContext.Request.Headers["ApiGatewayPassthroughHeader"];

if (ApiGatewayPassthroughHeader != Environment.GetEnvironmentVariable("ApiGatewayPassthroughHeader"))
{
    throw new error;
}

In our swagger file (we are using swagger.json as the source of our APIs)

"x-amazon-apigateway-integration": {
    "type": "http_proxy",
    "uri": "https://${stageVariables.url}/path/to/resource",
    "httpMethod": "post",
    "requestParameters": {
      "integration.request.header.ApiGatewayPassthroughHeader": "${ApiGatewayPassthroughHeader}"
    }
  },

In our docker compose file (we are using docker, but the same could be used in any settings file)

services:
  example:
      environment:
        - ApiGatewayPassthroughHeader=9708cc2d-2d42-example-8526-4586b1bcc74d

At build time we take the secret from our settings file and replace it in the swagger.json file. This way we can rotate the key in our settings file and API gateway will update to use the key the app is looking for.

Solution 4:

I know this is an old issue, but I think they may have just recently added support.

"Amazon API Gateway announced the general availability of HTTP APIs, enabling customers to easily build high performance RESTful APIs that offer up to 71% cost savings and 60% latency reduction compared to REST APIs available from API Gateway. As part of this launch, customers will be able to take advantage of several new features including the ability the route requests to private AWS Elastic Load Balancers (ELB), including new support for AWS ALB, and IP-based services registered in AWS CloudMap. "

https://aws.amazon.com/about-aws/whats-new/2020/03/api-gateway-private-integrations-aws-elb-cloudmap-http-apis-release/

Solution 5:

It is now possible to add an authorizer directly to Application Load Balancer (ALB) in front of ECS.

This can be configured directly in the rules of a listener. See this blog post for details:

https://aws.amazon.com/de/blogs/aws/built-in-authentication-in-alb/