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.3
...
x-amazon-apigateway-policy:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
Condition:
IpAddress:
'aws:SourceIp':
Ref: AllowedIpsList
...
Where AllowedIpsList is a comma separated list of IPs or CIDR blocks defined as a parameter in your CloudFormation template.
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 an API Gateway API during deployment via CloudFormation.
CloudFormation Template
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:
AllowedIpsList:
Type: List<String>
Globals:
Function:
Runtime: nodejs12.x
Timeout: 30
AutoPublishAlias: live
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: live
EndpointConfiguration: REGIONAL
DefinitionBody:
openapi: 3.0.3
info:
title: API Gateway IP Filtering 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: AllowedIpsList
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
ExampleFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
InlineCode: |
exports.handler = (event, context, callback) => {
callback(
null,
{
statusCode: 200,
body: JSON.stringify({
message: 'Hello World'
})
});
};
Events:
ApiGatewayApiEvent:
Type: Api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /api/example
Method: get
The DefinitionBody property of the ApiGatewayApi allows you to specify an OpenAPI specification definition which is transformed and applied by CloudFormation upon deployment.
The list of allowed IPs is passed to the SAM template as the AllowedIpsList parameter. This parameter is referenced from within the OpenAPI specification using the Ref function.
OpenAPI Specification
The OpenAPI specification, embedded in the CloudFormation template above, 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.3
info:
title: API Gateway IP Filtering 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: AllowedIpsList
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 AllowedIpsList parameter.
This API Gateway Resource Policy is allowing all invocations where the source IP is in the list of IPs supplied.
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-filtering. Running this example on AWS will incur costs so be sure to delete the CloudFormation stacks when you are finished experimenting.
Conclusion
This is a simple, cheap way to allow access to your API Gateway APIs only from certain IP addresses. AWS WAF is an alternative, but it incurs costs.