Back to Checks
API Gateway REST API endpoint is private
apigateway_restapi_public
Service: apigatewaySeverity: medium
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsApiGatewayRestApi
Amazon API Gateway REST APIs are evaluated for endpoint exposure: internet-accessible endpoints versus private VPC-only access via interface VPC endpoints (AWS PrivateLink).
Risk
Internet exposure increases attack surface:
- Confidentiality: misconfigured or anonymous methods can leak data
- Integrity: unauthorized calls can change backend state
- Availability/cost: bots or DDoS can exhaust capacity and spike spend
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks apigateway_restapi_publicRecommendation
Prefer private REST APIs reachable via interface VPC endpoints (PRIVATE).
If public access is required, apply least privilege and defense in depth:
- Restrict with resource policies (
aws:SourceVpc/aws:SourceVpce) - Enforce strong auth (IAM, Cognito, or authorizers)
- Add AWS WAF, throttling, usage plans, and comprehensive logging
Remediation
CLI
aws apigateway update-rest-api --rest-api-id <REST_API_ID> --patch-operations op=replace,path=/endpointConfiguration/types/0,value=PRIVATETerraform
resource "aws_api_gateway_rest_api" "<example_resource_name>" {
name = "<example_resource_name>"
endpoint_configuration {
types = ["PRIVATE"] # Critical: makes the REST API private
}
}NativeIaC
Resources:
<example_resource_name>:
Type: AWS::ApiGateway::RestApi
Properties:
Name: <example_resource_name>
EndpointConfiguration:
Types:
- PRIVATE # Critical: sets the REST API endpoint to Private, removing public accessOther
1Open the AWS console and go to API Gateway
2Under REST APIs, select your API
3In the left menu, click Settings
4Set Endpoint Type to Private
5Click Save changes
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.apigateway.apigateway_client import (
apigateway_client,
)
class apigateway_restapi_public(Check):
def execute(self):
findings = []
for rest_api in apigateway_client.rest_apis:
report = Check_Report_AWS(metadata=self.metadata(), resource=rest_api)
report.resource_id = rest_api.name
if rest_api.public_endpoint:
report.status = "FAIL"
report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} is internet accessible."
else:
report.status = "PASS"
report.status_extended = (
f"API Gateway {rest_api.name} ID {rest_api.id} is private."
)
findings.append(report)
return findingsReferences
- https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html
- https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-examples.html#apigateway-resource-policies-source-vpc-example
- https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html
- https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies.html