mcpField
I
implementing-api-gateway-security-controls

implementing-api-gateway-security-controls

github.com/mukul975セキュリティ35.2k211 回インストール8 週間前に更新
リポジトリ

implementing-api-gateway-security-controls について

API ゲートウェイのセキュリティ制御を設定するチーム向けの実装ガイドです。認証、通信制限、スキーマ検証、TLS、WAF、監視を扱い、バックエンド側の検証も必要としています。

主な機能

  1. 01認証と認可の一元化
  2. 02レート制限とクォータの設定
  3. 03OpenAPI に基づくリクエスト検証
  4. 04TLS と相互 TLS の設定
  5. 05WAF 連携とセキュリティイベント監視

活用シーン

  1. 01マイクロサービス API の統一入口の設定
  2. 02クライアントのリクエスト頻度とクォータの制限
  3. 03API 仕様に合わないリクエストの拒否
  4. 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 と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
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 があります。セキュリティチームは、各サービスを変更せずに、認証の一元化、レート制限、リクエスト検証を実装する必要があります。

アプローチ:

  1. Kong Gateway を単一のエントリーポイントとしてデプロイし、8 つのバックエンドマイクロサービスにトラフィックをルーティングします
  2. JWT 検証プラグインを設定し、会社の Keycloak IdP に対してトークンを検証します
  3. レート制限を適用します。JWT クレームで識別される一般ユーザーには 60 リクエスト/分、プレミアムユーザーには 300 リクエスト/分を設定します
  4. OAS 検証プラグインを有効にし、OpenAPI 仕様に一致しないリクエストを拒否します(マスアサインメントやインジェクションを阻止します)
  5. ゲートウェイの背後にあるサービス間通信に mTLS を設定します
  6. レスポンス変換プラグインを設定し、Server ヘッダーと X-Powered-By ヘッダーを削除して、セキュリティヘッダーを追加します
  7. SQL インジェクションおよび XSS 対策ルールのために AWS WAF と連携します
  8. セキュリティメトリクスのフィルターとアラートを設定し、アクセスログを 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)

コメント