API Gateway as an Attack Surface
AWS API Gateway is the front door to most serverless applications — and as such, it's the primary attack surface. Every public API endpoint is potentially exposed to credential stuffing, brute force, unauthorized access attempts, and injection attacks. The good news is that API Gateway has extensive built-in security features; the challenge is knowing which ones to use and how to monitor them effectively.
This guide covers the security controls available in API Gateway, how to configure them, and the monitoring patterns that detect when someone is probing or abusing your API.
Authentication and Authorization Layers
API Gateway supports multiple authentication mechanisms, and choosing the right one for each endpoint is the foundation of API security.
Amazon Cognito User Pool Authorizers
For APIs serving authenticated users, Cognito User Pool authorizers validate JWT tokens and extract claims. This is the most common pattern for SaaS applications:
resource "aws_api_gateway_authorizer" "cognito" {
name = "cognito-authorizer"
rest_api_id = aws_api_gateway_rest_api.api.id
type = "COGNITO_USER_POOLS"
provider_arns = [aws_cognito_user_pool.pool.arn]
}
The authorizer validates that the token is signed by your Cognito User Pool, is not expired, and (if configured) has the required scopes. Never implement token validation in your Lambda functions when you can push it to the API Gateway layer.
Lambda Authorizers
Lambda authorizers let you write custom authorization logic in a Lambda function. They're useful for API key validation, JWT validation against third-party providers, or custom claim-based authorization. The authorizer returns an IAM policy document that API Gateway uses to evaluate the request.
IAM Authorization
For service-to-service APIs (Lambda calling Lambda, Step Functions calling an API), IAM authorization is the most secure option. The calling service signs the request with its IAM credentials using SigV4, and API Gateway validates the signature against the configured IAM resource policy. This requires no secrets to manage and provides full CloudTrail audit trails on both sides.
Resource Policies
API Gateway resource policies let you restrict which principals, IPs, or VPCs can access an API entirely — before authentication even runs. Use resource policies to whitelist known partner IPs for B2B APIs or to restrict an API to traffic from within your VPC.
Rate Limiting and Throttling
API throttling prevents both abuse and accidental DoS from misconfigured clients. API Gateway throttles at two levels:
- Stage-level throttling: The default limit across all endpoints in a stage
- Method-level throttling: Per-endpoint overrides for sensitive operations
Configure stage-level throttling as a baseline, then tighten limits on sensitive endpoints:
resource "aws_api_gateway_method_settings" "throttle" {
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = aws_api_gateway_stage.prod.stage_name
method_path = "*/*"
settings {
throttling_rate_limit = 1000 # requests per second
throttling_burst_limit = 2000 # concurrent requests
}
}
For login endpoints and other sensitive operations, set much lower limits — typically 10-50 requests per second per stage.
Usage Plans and API Keys
For external APIs or partner integrations, usage plans provide per-client throttling and quota enforcement. Each client gets an API key, and the usage plan defines the rate and quota limits. This lets you identify which clients are generating excess load and cut off abusive clients without affecting others.
AWS WAF Integration
AWS Web Application Firewall can be attached to an API Gateway stage to inspect and filter requests before they reach your endpoints. WAF provides managed rule groups for common attack patterns:
- AWS Managed Rules (Core rule set) — protects against OWASP Top 10
- Bot Control — identifies and manages bot traffic
- SQL injection and XSS rules
- Geographic restrictions
For most API Gateway deployments, enabling WAF with the AWS Core rule set and the Amazon IP reputation list is a high-value, low-configuration starting point. See our guide on AWS WAF monitoring for the full configuration and monitoring approach.
TLS and Certificate Management
API Gateway enforces TLS 1.2 as a minimum for all API calls. For custom domain names, you manage the certificate through AWS Certificate Manager (ACM). Best practices:
- Use TLS 1.3 minimum security policy where possible
- Enable mutual TLS (mTLS) for service-to-service APIs that need strong authentication
- Set up ACM certificate renewal notifications — expired certificates cause immediate API outages
Monitoring API Gateway with CloudWatch
API Gateway automatically publishes metrics to CloudWatch. The most security-relevant:
4XXError— Client errors, including 401 Unauthorized and 403 Forbidden. A spike in 4XX errors often indicates a brute force attempt or a misconfigured client.5XXError— Server errors. Could indicate an injection attack causing application errors.Count— Total request volume. Watch for unusual spikes.Latency— Unusually high latency can indicate application-layer DoS.
CloudWatch Alarms for Security Events
aws cloudwatch put-metric-alarm --alarm-name "API-High-4XX-Rate" --metric-name "4XXError" --namespace "AWS/ApiGateway" --dimensions Name=ApiName,Value=myapi Name=Stage,Value=prod --statistic Sum --period 300 --threshold 100 --comparison-operator GreaterThanThreshold --evaluation-periods 1 --alarm-actions arn:aws:sns:us-east-1:123456789012:SecurityAlerts
Access Logging
API Gateway access logging captures detailed information about every request: client IP, user agent, authentication status, response code, latency. Enable access logging for all production stages and send logs to CloudWatch Logs:
resource "aws_api_gateway_stage" "prod" {
access_log_settings {
destination_arn = aws_cloudwatch_log_group.api_logs.arn
format = jsonencode({
requestId = "$context.requestId"
ip = "$context.identity.sourceIp"
caller = "$context.identity.caller"
user = "$context.identity.user"
requestTime = "$context.requestTime"
httpMethod = "$context.httpMethod"
resourcePath = "$context.resourcePath"
status = "$context.status"
protocol = "$context.protocol"
responseLength = "$context.responseLength"
errorMessage = "$context.error.message"
})
}
}
Use CloudWatch Logs Insights to analyze access logs for patterns: repeated authentication failures, unusual user agents, scanning behavior (requests to many different endpoints in a short window).
Detecting API Abuse Patterns
The following CloudWatch Logs Insights queries help identify API abuse:
Authentication Failures by IP
fields ip, status
| filter status in ["401", "403"]
| stats count(*) as failures by ip
| sort failures desc
| limit 20
Endpoint Scanning Detection
fields ip, resourcePath
| filter status = "404"
| stats count_distinct(resourcePath) as uniquePaths by ip
| filter uniquePaths > 20
| sort uniquePaths desc
An IP hitting more than 20 unique 404 paths is almost certainly scanning your API for known endpoints. This pattern often precedes a targeted attack.
High-Frequency Users
fields ip, user
| stats count(*) as requests by ip, user
| filter requests > 1000
| sort requests desc
For CloudTrail analysis patterns, see our CloudTrail analysis guide.
API Gateway and Lambda Security
When API Gateway invokes a Lambda function, the Lambda should treat the event as untrusted input. The API Gateway authorizer validates authentication, but your Lambda must still validate authorization (does this user have permission to do this specific thing?) and sanitize input. Don't assume that because a request passed the authorizer, it's safe to pass directly to your backend. See our Lambda security guide for input validation patterns.
Private APIs and VPC Integration
For internal APIs that should never be publicly accessible, use API Gateway private endpoints backed by VPC endpoint connections. Private APIs are accessible only from within your VPC, eliminating the public attack surface entirely:
resource "aws_api_gateway_rest_api" "private" {
endpoint_configuration {
types = ["PRIVATE"]
vpc_endpoint_ids = [aws_vpc_endpoint.apigw.id]
}
}
Combine with a resource policy that denies access except from your VPC endpoint. See our VPC security monitoring guide for the network security context.
GuardDuty API Gateway Findings
GuardDuty monitors API Gateway usage through CloudTrail data events. Relevant findings:
- Calls from TOR exit nodes
- Anomalous API access patterns consistent with credential compromise
- Known malicious IP addresses making API calls
For API-heavy applications, ensure GuardDuty data events are enabled for API Gateway. See the GuardDuty setup guide for configuration.
FAQ
Should I use HTTP API or REST API?
HTTP API is newer, cheaper, and lower latency, but has fewer features. REST API supports more advanced features including resource policies, per-method throttling, WAF integration, and caching. For public-facing APIs with security requirements, REST API is generally the right choice. HTTP API is fine for simple backends where cost and simplicity matter more.
How do I rotate API keys without downtime?
Create a new API key, add it to the usage plan, and give clients a migration window. Remove the old key only after confirming all clients have switched. API Gateway usage plans show per-key request counts, so you can verify when a key is no longer being used.
What's the best way to handle CORS for API Gateway?
Configure CORS at the API Gateway level rather than in your Lambda functions. Be specific about allowed origins — avoid * for authenticated APIs. Restrict allowed methods and headers to what your application actually uses. And never trust the Origin header for authorization decisions — it's easily spoofed.
Protect your AWS accounts before it's too late
Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.
Written by Vigilare Engineering
Platform Team