Back to Checks
aws

API Gateway REST API with a public endpoint has an authorizer configured

apigateway_restapi_public_with_authorizer
Service: apigatewaySeverity: medium
OfficialBuilt-inVerified
Categories:internet-exposedidentity-access
Resource Type:AwsApiGatewayRestApi

API Gateway REST APIs exposed to the Internet are evaluated for an attached authorizer that enforces caller identity (Lambda authorizer or Cognito user pool) on method invocations.

Focus is on whether public endpoints require authenticated requests rather than accepting anonymous calls.

Prowler logoProwlerprowler-provider-aws

Risk

Without an authorizer on a public API, anonymous callers can:

  • Read or alter data (confidentiality/integrity)
  • Trigger backend actions, impacting systems
  • Abuse traffic, degrading availability and inflating costs

Endpoint enumeration also enables broader discovery and lateral movement.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks apigateway_restapi_public_with_authorizer

Recommendation

Enforce authentication on all Internet-facing APIs by attaching an authorizer (Cognito user pool or Lambda) that validates tokens and scopes.

Apply defense in depth:

  • Restrictive resource policies and IP controls
  • WAF, throttling, quotas, rate limits
  • Least-privilege backend access and comprehensive logging

Remediation

CLI

aws apigateway create-authorizer --rest-api-id <rest_api_id> --name <example_resource_name> --type TOKEN --authorizer-uri arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account-id>:function:<example_resource_name>/invocations --identity-source 'method.request.header.Authorization'

Terraform

# Terraform: Minimal Lambda TOKEN authorizer for API Gateway REST API
resource "aws_api_gateway_authorizer" "<example_resource_name>" {
  name            = "<example_resource_name>"
  rest_api_id     = "<example_resource_id>"
  type            = "TOKEN"  # Critical: enables a Lambda authorizer on the REST API
  identity_source = "method.request.header.Authorization"  # Critical: header to read token
  authorizer_uri  = "arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account-id>:function/<example_resource_name>/invocations"  # Critical: Lambda authorizer function URI
}

NativeIaC

# CloudFormation: Create a minimal Lambda TOKEN authorizer for a public REST API
Resources:
  <example_resource_name>:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Name: <example_resource_name>
      RestApiId: <example_resource_id>
      Type: TOKEN  # Critical: adds an authorizer to the REST API
      IdentitySource: method.request.header.Authorization  # Critical: header to read token from
      AuthorizerUri: arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account-id>:function/<example_resource_name>/invocations  # Critical: Lambda authorizer function URI

Other

1In the AWS Console, open API Gateway and select your REST API
2In the left pane, click Authorizers > Create authorizer
3Choose Lambda (TOKEN) or Cognito User Pool
4For Lambda: select the function and set Identity source to method.request.header.Authorization; for Cognito: select the user pool
5Click Create authorizer to add it to the API

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_with_authorizer(Check):
    def execute(self):
        findings = []
        for rest_api in apigateway_client.rest_apis:
            if rest_api.public_endpoint:
                report = Check_Report_AWS(metadata=self.metadata(), resource=rest_api)
                report.resource_id = rest_api.name

                report.status = "PASS"
                report.status_extended = f"API Gateway REST API {rest_api.name} with ID {rest_api.id} has a public endpoint with an authorizer."

                if not rest_api.authorizer:
                    report.status = "FAIL"
                    report.status_extended = f"API Gateway REST API {rest_api.name} with ID {rest_api.id} has a public endpoint without an authorizer."

                findings.append(report)

        return findings