- Knowledge Base
- Amazon Web Services
- Amazon API Gateway
- Private Endpoint
Ensure that the APIs created with Amazon API Gateway service are only accessible via private API endpoints and not visible to the Internet. When the Amazon API Gateway API is private, it can be accessed only privately through the VPC endpoint.
This rule can help you with the following compliance standards:
- MAS
- NIST4
For further details on compliance standards supported by Conformity, see here.
This rule can help you work with the AWS Well-Architected Framework.
This rule resolution is part of the Conformity Security & Compliance tool for AWS.
With a private API endpoint configuration, the traffic to your Amazon API Gateway APIs is using secure connections and does not leave the AWS network. Having private API endpoints for your REST APIs allows you to use all API Gateway service features, while securely connecting them to other AWS cloud services and resources inside your Virtual Private Cloud (VPC).
Audit
To determine if your Amazon API Gateway APIs are using private endpoints, perform the following actions:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to API Gateway console at https://console.aws.amazon.com/apigateway/.
03 In the main navigation panel, select APIs to access your API Gateway APIs.
04 Click on the name (link) of the API that you want to examine.
05 Choose Settings from the API menu to access the configuration settings available for the selected API.
06 In the Endpoint Configuration section, check the configuration value selected for the Endpoint Type dropdown list. If the selected value is either Regional (publicly accessible and deployed within the current AWS region) or Edge Optimized (publicly accessible and deployed to an Amazon CloudFront distribution), the selected Amazon API Gateway API is not private, therefore your API is visible on the Internet.
07 Repeat steps no. 4 – 6 to check the endpoint type for each Amazon API Gateway API available within the current AWS region.
08 Change the AWS region from the navigation bar and repeat the Audit process for other regions.
Using AWS CLI
01 Run get-rest-apis command (OSX/Linux/UNIX) using custom query filters to list the ID of each API Gateway API available in the selected AWS region:
aws apigateway get-rest-apis --region us-east-1 --output table --query 'items[*].id'
02 The command output should return a table with the requested API ID(s):
---------------- | GetRestApis | +--------------+ | aabbccaabb | | abcaabbcca | | abcdabcdab | +--------------+
03 Run get-rest-api command (OSX/Linux/UNIX) using the ID of the Amazon API Gateway API that you want to examine as the identifier parameter and custom query filters to describe the endpoint type configured for the selected API:
aws apigateway get-rest-api --region us-east-1 --rest-api-id aabbccaabb --query 'endpointConfiguration.types'
04 The command output should return the endpoint type configured for the selected API:
[ "REGIONAL" ]
If the get-rest-api command output returns "REGIONAL" (deployed within the current AWS region and publicly accessible on the Internet) or "EDGE" (deployed to a CloudFront distribution network and accessible through the Internet), the selected Amazon API Gateway API is publicly accessible.
05 Repeat step no. 3 and 4 to check the endpoint type for each Amazon API Gateway API available in the selected AWS region.
06 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 5 to perform the Audit process for other regions.
Remediation / Resolution
To change the endpoint type for your Amazon API Gateway APIs in order to be accessible only through private VPC endpoints, perform the following actions:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{
"AWSTemplateFormatVersion":"2010-09-09",
"Description":"Configure Private Endpoints for REST APIs",
"Resources":{
"RestAPI": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "WebServiceAPI",
"Description" : "A simple API Gateway REST API",
"EndpointConfiguration": {
"Types": ["PRIVATE"]
}
,
"Policy": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": {
"Fn::Sub": "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*"
},
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": {
"Fn::Sub": "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*"
},
"Condition" : {
"StringNotEquals": {
"aws:SourceVpce": "vpc-abcd1234"
}
}
}
]
}
}
}
}
}
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Description: Configure Private Endpoints for REST APIs Resources: RestAPI: Type: AWS::ApiGateway::RestApi Properties: Name: WebServiceAPI Description: A simple API Gateway REST APIEndpointConfiguration:
Types:
- PRIVATE
Policy: Version: '2012-10-17' Statement: - Effect: Deny Principal: '*' Action: execute-api:Invoke Resource: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*' Condition: StringNotEquals: aws:SourceVpce: vpc-abcd1234
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.27"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
profile = "default"
region = "us-east-1"
}
resource "aws_api_gateway_rest_api" "rest-api" {
name = "web-service-api"
description = "A simple API Gateway REST API"
# Configure Private Endpoint
endpoint_configuration {
types = ["PRIVATE"]
}
}
# Grant access to the API from VPC endpoints
resource "aws_api_gateway_rest_api_policy" "api-resource-policy" {
rest_api_id = aws_api_gateway_rest_api.rest-api.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "execute-api:Invoke",
"Resource": "${aws_api_gateway_rest_api.rest-api.execution_arn}"
},
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "execute-api:Invoke",
"Resource": "${aws_api_gateway_rest_api.rest-api.execution_arn}",
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": "vpc-abcd1234"
}
}
}
]
}
EOF
}
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to API Gateway console at https://console.aws.amazon.com/apigateway/.
03 In the main navigation panel, select APIs to access your API Gateway APIs.
04 Click on the name of the API that you want to reconfigure.
05 Choose Settings from the API menu to access the configuration settings available for the selected API.
06 In the Endpoint Configuration section, select Private from the Endpoint Type dropdown list to change the endpoint type for the selected API to private. Choose Save changes to apply the changes.
07 Before your private API can be accessed, you have to create a resource policy and attach it to the API. The policy should grant access to the API from your VPC endpoints or from VPC endpoints available in other AWS accounts that you explicitly grant access. Navigate back to the API menu and select Resource Policy to access the resource policy attached to the selected API.
08 On the Resource Policy page, paste the following resource policy template into the policy document textbox. Make sure that you replace {{vpceID}}
(including the curly braces) with your own VPC endpoint ID. If you don't have a VPC endpoint already created, follow the steps outlined in this conformity rule to create one. The resource policy placeholders are enclosed in double curly braces (e.g. {{account-id}}
). Replace each highlighted placeholder with your own configuration information:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "execute-api:Invoke", "Resource": [ "arn:aws:execute-api:{{aws-region}}:{{account-id}}:{{api-id}}
/*" ] }, { "Effect": "Deny", "Principal": "*", "Action": "execute-api:Invoke", "Resource": [ "arn:aws:execute-api:{{aws-region}}:{{account-id}}:{{api-id}}
/*" ], "Condition" : { "StringNotEquals": { "aws:SourceVpce": "{{vpceID}}
" } } } ] }
09 Choose Save to attach the new resource policy to your API.
10 Repeat steps no. 4 – 9 to reconfigure each publicly accessible Amazon API Gateway API available within the current AWS region.
11 Change the AWS cloud region from the navigation bar and repeat the Remediation process for other regions.
Using AWS CLI
01 Run update-rest-api command (OSX/Linux/UNIX) using the ID of the Amazon API Gateway API that you want to reconfigure as the identifier parameter to change the API endpoint type to private:
aws apigateway update-rest-api --region us-east-1 --rest-api-id aabbccaabb --patch-operations op=replace,path=/endpointConfiguration/types/REGIONAL,value=PRIVATE
02 The output should return the update-rest-api command request metadata:
{ "id": "aabbccaabb", "name": "WebAPI", "description": "Project5 Web API", "createdDate": "2022-01-11T10:55:44+00:00", "apiKeySource": "HEADER", "endpointConfiguration": { "types": [ "PRIVATE" ] }, "tags": {}, "disableExecuteApiEndpoint": false }
03 Before your private API can be accessed, you have to create a resource policy and attach it to the API. The policy should grant access to the API from your VPC endpoints or from VPC endpoints available in other AWS accounts that you explicitly grant access. To attach the required resource policy to your Amazon API Gateway API, run update-rest-api command (OSX/Linux/UNIX) as shown in the example below. Make sure that you replace {{vpceID}}
(including the curly braces) with your own VPC endpoint ID. If you don't have a VPC endpoint already created, follow the steps outlined in this conformity rule to create one. The resource policy placeholders are enclosed in double curly braces (e.g. {{account-id}}
). Replace each highlighted placeholder with your own configuration information:
aws apigateway update-rest-api --region us-east-1 --rest-api-id aabbccaabb --patch-operations op=replace,path=/policy,value='{\"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn:aws:execute-api:{{aws-region}}
:{{account-id}}
:{{api-id}}
\/*\"},{\"Effect\":\"Deny\",\"Principal\":\"*\",\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn:aws:execute-api:{{aws-region}}
:{{account-id}}
:{{api-id}}
\/*\",\"Condition\":{\"StringNotEquals\":{\"aws:SourceVpce\":\"{{vpceID}}
\"}}}]}\"}'
04 The command output should return the metadata available for the reconfigured API:
{ "id": "aabbccaabb", "name": "WebAPI", "description": "Project5 Web API", "createdDate": "2022-01-11T10:55:44+00:00", "apiKeySource": "HEADER", "endpointConfiguration": { "types": [ "PRIVATE" ] }, "tags": {}, "disableExecuteApiEndpoint": false }
05 Repeat steps no. 1 – 4 to reconfigure each publicly accessible Amazon API Gateway API available in the selected AWS region.
06 Change the AWS cloud region by updating the --region command parameter value and perform the Remediation process for other regions.
References
- AWS Documentation
- Amazon API Gateway FAQs
- Creating a private API in Amazon API Gateway
- Change a Public or Private API Endpoint Type in API Gateway
- Create and Attach an API Gateway Resource Policy to an API
- API Gateway Resource Policy Examples
- AWS Command Line Interface (CLI) Documentation
- apigateway
- get-rest-apis
- update-rest-api
- CloudFormation Documentation
- Amazon API Gateway resource type reference
- Terraform Documentation
- AWS Provider