Search code examples
amazon-web-servicesamazon-cloudfrontaws-api-gateway

Restrict API Gateway so only CloudFront can hit it


I currently have a CloudFront distribution which restricts access to an S3 bucket for static content using Origin Access Control.

I want to do the same with an API Gateway. The goal is for the architecture to look like this:

                     ┌───────────────────────────────────────────────────────────────────────────┐
                     │AWS Account                                                                │
                     │                                               ┌──────────────────────┐    │
                     │                                        *      │     S3 Bucket        │    │
                     │                                       ┌──────►│  (static content)    │    │
                     │                                       │       └──────────────────────┘    │
┌─────────────┐      │  ┌────────────────────────────┐       │                                   │
│             │      │  │                            │       │                                   │
│    Client   ├──────┼─►│  CloudFront Distribution   ├───────┤                                   │
│             │      │  │                            │       │       ┌──────────────────────┐    │
└─────────────┘      │  └────────────────────────────┘       │       │     API Gateway      │    │
                     │                                       └──────►│  (dynamic content)   │    │
                     │                                        /api/* └──────────────────────┘    │
                     │                                                                           │
                     │                                                                           │
                     └───────────────────────────────────────────────────────────────────────────┘

Traffic not from the CloudFront distribution should not be able to reach the API Gateway - ideally by not giving it a public URL, but it would also be acceptable to restrict it via a policy.

I have seen this answer which authorises the request based on a secret header value from the distribution, which is not ideal when compared to a method like OAC.


Solution

  • You can make this work by having a Private API Gateway.

    1. Create a VPC endpoint for your API Gateway
    2. Create a private API Gateway
    3. Configure CloudFront to use the private API Gateway endpoint

    Your endpoint won't be public in this setup. You can further improve the design by adding resource policies and security groups/network ACLs.

    Reference: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html