implementing-api-gateway-security-controls について
API ゲートウェイのセキュリティ制御を設定するチーム向けの実装ガイドです。認証、通信制限、スキーマ検証、TLS、WAF、監視を扱い、バックエンド側の検証も必要としています。
主な機能
- 01認証と認可の一元化
- 02レート制限とクォータの設定
- 03OpenAPI に基づくリクエスト検証
- 04TLS と相互 TLS の設定
- 05WAF 連携とセキュリティイベント監視
活用シーン
- 01マイクロサービス API の統一入口の設定
- 02クライアントのリクエスト頻度とクォータの制限
- 03API 仕様に合わないリクエストの拒否
- 04ゲートウェイのセキュリティイベント監視
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill implementing-api-gateway-security-controlsインストール後、Claude Code で/implementing-api-gateway-security-controlsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
API Gateway のセキュリティ制御の実装
使用する場面
- マイクロサービス API 向けに、認証・認可を一元管理するレイヤーを導入する場合
- すべての API エンドポイントに対して、レート制限、スロットリング、クォータ管理を実装する場合
- ゲートウェイレベルで OpenAPI 仕様に基づくリクエスト/レスポンス検証を設定する場合
- API トラフィック向けに、TLS 終端、相互 TLS、証明書管理を設定する場合
- API ゲートウェイに WAF ルールを統合して、インジェクション、XSS、既知の攻撃パターンをブロックする場合
唯一のセキュリティレイヤーとして使用しないでください。 API ゲートウェイは多層防御を提供しますが、バックエンドサービスでも認可と入力を検証する必要があります。
前提条件
- API ゲートウェイプラットフォームを選定し、デプロイしていること(Kong、AWS API Gateway、Azure APIM、Apigee)
- すべてのバックエンド API の OpenAPI/Swagger 仕様
- ゲートウェイドメイン用の TLS 証明書
- OAuth2/OIDC 用に設定された ID プロバイダー(IdP)(Okta、Auth0、Azure AD)
- 監視・ログ記録インフラストラクチャ(CloudWatch、Datadog、ELK)
- バックエンドサービスのエンドポイントが登録され、ゲートウェイから到達可能であること
ワークフロー
ステップ 1:Kong Gateway のセキュリティ設定
# kong.yml - Declarative Kong configuration with security plugins
_format_version: "3.0"
services:
- name: user-service
url: http://user-service:8080
routes:
- name: user-api
paths:
- /api/v1/users
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
strip_path: false
plugins:
# 1. Authentication: JWT validation
- name: jwt
config:
uri_param_names:
- jwt
header_names:
- Authorization
claims_to_verify:
- exp
maximum_expiration: 3600 # Max 1 hour token TTL
# 2. Rate Limiting
- name: rate-limiting
config:
minute: 60
hour: 1000
policy: redis
redis_host: redis
redis_port: 6379
fault_tolerant: true
hide_client_headers: false
limit_by: credential # Per-user, not per-IP
# 3. Request Size Limiting
- name: request-size-limiting
config:
allowed_payload_size: 1 # 1 MB max
size_unit: megabytes
# 4. IP Restriction (admin endpoints)
- name: ip-restriction
service: admin-service
config:
allow:
- 10.0.0.0/8
- 172.16.0.0/12
# 5. Bot Detection
- name: bot-detection
config:
deny:
- "sqlmap"
- "nikto"
- "nmap"
- "masscan"
# 6. CORS Configuration
- name: cors
config:
origins:
- "https://app.example.com"
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
headers:
- Authorization
- Content-Type
credentials: true
max_age: 3600
# 7. Response Transformer - Remove sensitive headers
- name: response-transformer
config:
remove:
headers:
- X-Powered-By
- Server
add:
headers:
- "X-Content-Type-Options: nosniff"
- "X-Frame-Options: DENY"
- "Strict-Transport-Security: max-age=31536000; includeSubDomains"
- "Content-Security-Policy: default-src 'none'"
ステップ 2:AWS API Gateway のセキュリティ設定
import boto3
import json
apigw = boto3.client('apigatewayv2')
# Create API with mutual TLS
api_response = apigw.create_api(
Name='secure-api',
ProtocolType='HTTP',
DisableExecuteApiEndpoint=True, # Force custom domain
)
api_id = api_response['ApiId']
# Configure authorizer (JWT with Cognito)
authorizer = apigw.create_authorizer(
ApiId=api_id,
AuthorizerType='JWT',
IdentitySource='$request.header.Authorization',
Name='cognito-jwt-authorizer',
JwtConfiguration={
'Audience': ['your-app-client-id'],
'Issuer': 'https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx'
}
)
# Create route with authorizer
apigw.create_route(
ApiId=api_id,
RouteKey='GET /api/v1/users',
AuthorizerId=authorizer['AuthorizerId'],
AuthorizationType='JWT',
)
# Configure throttling
apigw.create_stage(
ApiId=api_id,
StageName='prod',
DefaultRouteSettings={
'ThrottlingBurstLimit': 100,
'ThrottlingRateLimit': 50.0, # 50 requests per second
},
AccessLogSettings={
'DestinationArn': 'arn:aws:logs:us-east-1:123456789:log-group:api-access-logs',
'Format': json.dumps({
'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'
})
}
)
# WAF association
waf = boto3.client('wafv2')
web_acl = waf.create_web_acl(
Name='api-security-acl',
Scope='REGIONAL',
DefaultAction={'Allow': {}},
Rules=[
{
'Name': 'AWS-AWSManagedRulesSQLiRuleSet',
'Priority': 1,
'Statement': {
'ManagedRuleGroupStatement': {
'VendorName': 'AWS',
'Name': 'AWSManagedRulesSQLiRuleSet'
}
},
'OverrideAction': {'None': {}},
'VisibilityConfig': {
'SampledRequestsEnabled': True,
'CloudWatchMetricsEnabled': True,
'MetricName': 'SQLiRuleSet'
}
},
{
'Name': 'RateLimit',
'Priority': 2,
'Statement': {
'RateBasedStatement': {
'Limit': 2000,
'AggregateKeyType': 'IP'
}
},
'Action': {'Block': {}},
'VisibilityConfig': {
'SampledRequestsEnabled': True,
'CloudWatchMetricsEnabled': True,
'MetricName': 'RateLimitRule'
}
},
],
VisibilityConfig={
'SampledRequestsEnabled': True,
'CloudWatchMetricsEnabled': True,
'MetricName': 'ApiSecurityACL'
}
)
ステップ 3:OpenAPI スキーマによるリクエスト検証
# Kong OAS Validation Plugin configuration
plugins:
- name: oas-validation
config:
api_spec: |
openapi: "3.0.3"
info:
title: Secure API
version: "1.0"
paths:
/api/v1/users:
post:
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, email]
properties:
name:
type: string
maxLength: 100
pattern: "^[a-zA-Z ]+$"
email:
type: string
format: email
maxLength: 255
additionalProperties: false # Block mass assignment
responses:
'201':
description: User created
validate_request_body: true
validate_request_header_params: true
validate_request_query_params: true
validate_request_uri_params: true
verbose_response: false # Do not expose schema details in errors
ステップ 4:相互 TLS の設定
# Generate CA and client certificates for mTLS
# 1. Create CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -out ca.crt -days 365 \
-subj "/CN=API Gateway CA/O=Example Corp"
# 2. Create client certificate
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
-subj "/CN=api-client/O=Example Corp"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt -days 365
# Kong mTLS configuration
# Upload CA certificate to Kong
curl -X POST http://kong-admin:8001/ca_certificates \
-F "[email protected]"
# Enable mTLS plugin
curl -X POST http://kong-admin:8001/services/user-service/plugins \
--data "name=mtls-auth" \
--data "config.ca_certificates[]=$(cat ca_cert_id)" \
--data "config.revocation_check_mode=SKIP" \
--data "config.authenticated_group_by=CN"
ステップ 5:ログ記録と監視の設定
# CloudWatch monitoring for API security events
import boto3
cloudwatch = boto3.client('cloudwatch')
logs = boto3.client('logs')
# Create metric filters for security events
security_filters = [
{
'name': 'UnauthorizedAccess',
'pattern': '{ $.status = 401 || $.status = 403 }',
'metric': 'UnauthorizedAccessCount'
},
{
'name': 'RateLimitHits',
'pattern': '{ $.status = 429 }',
'metric': 'RateLimitHitCount'
},
{
'name': 'ServerErrors',
'pattern': '{ $.status >= 500 }',
'metric': 'ServerErrorCount'
},
{
'name': 'LargeResponses',
'pattern': '{ $.responseLength > 1000000 }',
'metric': 'LargeResponseCount'
},
]
for sf in security_filters:
logs.put_metric_filter(
logGroupName='api-access-logs',
filterName=sf['name'],
filterPattern=sf['pattern'],
metricTransformations=[{
'metricName': sf['metric'],
'metricNamespace': 'APISecurityMetrics',
'metricValue': '1',
'defaultValue': 0
}]
)
# Create alarm for unusual 401/403 spike
cloudwatch.put_metric_alarm(
AlarmName='API-UnauthorizedAccessSpike',
MetricName='UnauthorizedAccessCount',
Namespace='APISecurityMetrics',
Statistic='Sum',
Period=300, # 5 minutes
EvaluationPeriods=1,
Threshold=100,
ComparisonOperator='GreaterThanThreshold',
AlarmActions=['arn:aws:sns:us-east-1:123456789:security-alerts'],
AlarmDescription='More than 100 unauthorized access attempts in 5 minutes'
)
主要な概念
| 用語 | 定義 |
|---|---|
| API Gateway | すべての API トラフィックの一元的な入口です。バックエンドサービスにルーティングする前に、認証、認可、レート制限、リクエスト検証を適用します |
| レート制限 | 不正利用を防ぎ、公平なリソース割り当てを確保するため、一定の時間内にクライアントごとに送信できる API リクエスト数を制御することです |
| リクエスト検証 | バックエンドサービスに転送する前に、受信した API リクエストが想定されるスキーマ(データ型、必須フィールド、値の範囲)に準拠していることを確認することです |
| 相互 TLS(mTLS) | クライアントとサーバーの双方が証明書を提示する双方向 TLS 認証です。API 間通信における強力な ID 検証を提供します |
| WAF 統合 | 一般的な攻撃パターン(SQLi、XSS、パストラバーサル)をブロックするため、API ゲートウェイで適用される Web アプリケーションファイアウォールのルールです |
| OAuth2/OIDC | ゲートウェイがアクセスを許可する前に、ID プロバイダーに対して JWT トークンを検証する、トークンベースの認証プロトコルです |
ツールとシステム
- Kong Gateway:セキュリティ、レート制限、認証向けの豊富なプラグインエコシステムを備えたオープンソースの API ゲートウェイ
- AWS API Gateway:スロットリング、WAF 統合、Lambda オーソライザーを標準で備えたマネージド API ゲートウェイサービス
- Azure API Management:ポリシーベースのセキュリティ、開発者ポータル、Azure AD 統合を備えたエンタープライズ向け API ゲートウェイ
- Apigee(Google Cloud):脅威対策、クォータ管理、API 分析機能を備えた API 管理プラットフォーム
- Envoy Proxy:豊富なフィルターチェーンを備え、サービスメッシュアーキテクチャで API ゲートウェイとして使用される高性能プロキシ
一般的なシナリオ
シナリオ:Kong Gateway によるマイクロサービス API の保護
コンテキスト:ある企業が、モノリシック API からマイクロサービスへ移行しています。各マイクロサービスには独自の REST API があります。セキュリティチームは、各サービスを変更せずに、認証の一元化、レート制限、リクエスト検証を実装する必要があります。
アプローチ:
- Kong Gateway を単一のエントリーポイントとしてデプロイし、8 つのバックエンドマイクロサービスにトラフィックをルーティングします
- JWT 検証プラグインを設定し、会社の Keycloak IdP に対してトークンを検証します
- レート制限を適用します。JWT クレームで識別される一般ユーザーには 60 リクエスト/分、プレミアムユーザーには 300 リクエスト/分を設定します
- OAS 検証プラグインを有効にし、OpenAPI 仕様に一致しないリクエストを拒否します(マスアサインメントやインジェクションを阻止します)
- ゲートウェイの背後にあるサービス間通信に mTLS を設定します
- レスポンス変換プラグインを設定し、Server ヘッダーと X-Powered-By ヘッダーを削除して、セキュリティヘッダーを追加します
- SQL インジェクションおよび XSS 対策ルールのために AWS WAF と連携します
- セキュリティメトリクスのフィルターとアラートを設定し、アクセスログを CloudWatch に送信します
注意点:
- バックエンドサービスでも権限の検証が必要なのに、認可をゲートウェイだけに頼ること
- 認証済みユーザーごとのレート制限を設定しないこと(IP 単位のみでは、攻撃者が IP ローテーションで回避できます)
- 内部サービスのアーキテクチャが明らかになるような詳細なエラーレスポンスをゲートウェイが返すこと
- デプロイ後にセキュリティツールでゲートウェイ設定をテストしないこと
- ゲートウェイとバックエンドサービス間の相互 TLS が設定されておらず、バックエンドへの直接アクセスが可能になること
出力形式
## API Gateway Security Configuration Report
**Gateway**: Kong 3.5 (Kubernetes deployment)
**Backend Services**: 8 microservices
**Date**: 2024-12-15
### Security Controls Implemented
| Control | Plugin/Feature | Configuration |
|---------|---------------|---------------|
| Authentication | JWT Plugin | Cognito IdP, 1-hour max TTL |
| Rate Limiting | Rate Limiting Plugin | 60 req/min (user), Redis-backed |
| Request Validation | OAS Validation | Strict mode, no additional properties |
| TLS | Kong TLS | TLS 1.3 only, HSTS enabled |
| mTLS | mTLS Auth Plugin | Client cert required for admin APIs |
| WAF | AWS WAF | SQLi, XSS, rate-based rules |
| Headers | Response Transformer | Server header removed, security headers added |
| Logging | HTTP Log Plugin | CloudWatch, security metric filters |
### Verification Results
- JWT validation: Expired/invalid tokens correctly rejected (tested 50 payloads)
- Rate limiting: Enforced at 60 req/min, 429 returned with Retry-After header
- Request validation: Malformed requests rejected with 400 (tested 30 invalid payloads)
- mTLS: Requests without client certificate rejected with 401
- WAF: SQL injection payloads blocked (tested top 100 SQLi patterns)
コメント
Markdown 対応