How to Whitelist IPs with API Gateway

Use an API Gateway Resource Policy to allow access to your APIs only from certain IPs. This is a handy approach for locking down your non-production APIs so that they are not publicly accessible.

TL;DR

Use an OpenAPI specification with the x-amazon-apigateway-policy API Gateway Extension to OpenAPI to apply an API Gateway Resource Policy when deploying:

---
openapi: 3.0.0

...

x-amazon-apigateway-policy:
  Version: '2012-10-17'
  Statement:
    - Effect: Allow
      Principal: '*'
      Action: execute-api:Invoke
      Resource:
        - execute-api:/*/*/*
      Condition:
        IpAddress:
          'aws:SourceIp':
            Ref: ApiIpWhitelist

...

Where ApiIpWhitelist is a comma separated list of IPs or CIDR blocks defined as a parameter in your CloudFormation template.

Source Code

The source code and instructions to build and deploy this example to AWS can be found here: https://github.com/karlkyck/api-gateway-ip-whitelist. Running this example on AWS will incur costs so be sure to delete the CloudFormation stacks when you are finished experimenting.

Rationale

When it comes to accessing and consuming resources on the cloud a least privileged approach is best. IP restriction on your API Gateway APIs can help.

It is possible to apply an API Gateway Resource Policy to API Gateway API during deployment via CloudFormation.

Serverless Application Model

Your API Gateway API definition and reference to your OpenAPI specification is defined in your SAM (Serverless Application Model) template.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  DeploymentBucket:
    Type: String
  ApiIpWhitelist:
    Type: List<String>

Globals:
  Function:
    Runtime: nodejs8.10
    Timeout: 180
    Tracing: Active
    AutoPublishAlias: live

Resources:

  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: live
      EndpointConfiguration: REGIONAL
      DefinitionBody:
        'Fn::Transform':
          Name: AWS::Include
          Parameters:
            Location: !Sub s3://${DeploymentBucket}/openapi.yaml

  ExampleFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: Handler.handler
      CodeUri: ./dist
      Events:
        ApiGatewayApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref ApiGatewayApi
            Path: /api/example
            Method: get

The DefinitionBody property of the ApiGatewayApi allows the use of the Include Transform function to include and transform an OpenAPI specification file located in an S3 bucket.

The list of whitelisted IPs is passed to the SAM template as the ApiIpWhitelist parameter. This parameter is referenced from within the OpenAPI specification using the Ref function.

OpenAPI Specification

The OpenAPI specification contains the definition of your API. The API Gateway Resource Policy is declared in the specification as an API Gateway Extension to OpenAPI.

---
openapi: 3.0.0
info:
  title: API Gateway IP Whitelisting Example API
  version: 1.0.0

x-amazon-apigateway-policy:
  Version: '2012-10-17'
  Statement:
    - Effect: Allow
      Principal: '*'
      Action: execute-api:Invoke
      Resource:
        - execute-api:/*/*/*
      Condition:
        IpAddress:
          'aws:SourceIp':
            Ref: ApiIpWhitelist

paths:
  /api/example:
    get:
      summary: Example API Endpoint
      operationId: example
      responses:
        '200':
          description: Success
      x-amazon-apigateway-integration:
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ExampleFunction.Arn}:live/invocations
        httpMethod: POST
        type: aws_proxy

Here we see the Ref function referring to the ApiIpWhitelist parameter.

This API Gateway Resource Policy is allowing all invocations where the source IP is in the list of IPs supplied.