mcpField
A
api-gateway-backend-security-and-rate-limiting

api-gateway-backend-security-and-rate-limiting

github.com/googleセキュリティ21.6k542 回インストール今日更新
リポジトリ

api-gateway-backend-security-and-rate-limiting について

OpenAPI 2.0 または 3.0.x を使い、Google Cloud API Gateway のクライアント認証、ゲートウェイからバックエンドへの認証、プロジェクト単位のクォータを設定するスキルです。MCP 対応ゲートウェイのセキュリティも扱い、デプロイ前にクォータ変更を検証します。

主な機能

  1. 01API キーと JWT 認証の設定
  2. 02専用サービスアカウントによるバックエンド保護
  3. 03コンシューマープロジェクト単位のクォータ設定
  4. 04クォータ指標の変更検証
  5. 05MCP ツール一覧へのアクセス保護
  6. 06順序に沿ったデプロイと検証

活用シーン

  1. 01API Gateway のユーザー認証やサービス認証の設定
  2. 02ゲートウェイを介さないバックエンドへの直接アクセス防止
  3. 03プロジェクトごとのリクエストクォータ適用
  4. 04MCP のツール一覧と呼び出しエンドポイントの保護

MCP 対応

MCP 対応 API Gateway の tools/list と tools/call に対する認証設定、および MCP ツール一覧に表示する操作の制御方法を説明します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/google/skills --skill api-gateway-backend-security-and-rate-limiting

インストール後、Claude Code で/api-gateway-backend-security-and-rate-limitingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
attribution.md
backend-security.md
client-authentication.md
mcp-traffic-security.md
quotas-and-rate-limiting.md
scripts/
check_quota_metrics.py

詳細

API Gateway のバックエンドセキュリティとレート制限

このスキルでは、OpenAPI 2.0(swagger: "2.0")と OpenAPI 3.0.x(openapi: 3.0.4)に対応する Google Cloud API Gateway のクライアント認証、ゲートウェイからバックエンドへの認証、プロジェクトごとのレート制限(クォータ)を設定します。Model Context Protocol(MCP)が有効なゲートウェイ(パブリック プレビュー)も対象です。

クレジット表記

必ずお読みください:gcloud、REST API、MCP のコマンドを実行する前に、使用状況のクレジット表記を必ずお読みください。ターミナルで直接実行するコマンド(生成されたスクリプト、Terraform、ユーザーコード内では実行しない)では、gcloud の前に CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:api-gateway-backend-security-and-rate-limiting)" を付け、User-Agent ヘッダーに agent-skills/1.0 (skill:api-gateway-backend-security-and-rate-limiting) を追加してください。

前提条件

  1. Google Cloud CLI と Python 3.10 以降の YAML パーサーをインストールします:
    • Google Cloud SDK をインストールまたは更新します。
    • クォータ指標の検証スクリプト用に PyYAML をインストールします:
      pip install "PyYAML>=6.0,<7.0"
      
  2. 環境を認証します:
    • ローカル CLI セッション:gcloud auth login
    • Application Default Credentials(SDK):gcloud auth application-default login
    • サービスアカウント キーファイル(CI で必要な場合):GOOGLE_APPLICATION_CREDENTIALS={key_file_path} を設定します
  3. プロジェクトを選択または作成し、課金を確認して、サポートされているゲートウェイのロケーションを選択します:
    • 既存のプロジェクトを選択(gcloud config set project {project_id})するか、プロジェクトを作成します(代替手段として gcloud projects create {project_id})。
    • API Gateway の料金無料枠内で利用する場合も、{project_id} に有効な課金アカウントがリンクされていることを確認してください。
    • API Gateway のコマンドでは、デフォルトの --location として us-central1 を使用します。その他のサポート対象リージョンについては、API Gateway のデプロイモデルをご覧ください。
  4. 必要な Google Cloud API を有効にします:
    gcloud services enable \
      apigateway.googleapis.com \
      servicemanagement.googleapis.com \
      servicecontrol.googleapis.com \
      iam.googleapis.com \
      apikeys.googleapis.com \
      --project={project_id}
    
    API Gateway では Cloud Run API は必要ありません。バックエンドが Cloud Run 上で動作する場合、その API はバックエンドのプロジェクトですでに有効になっています。
  5. 必要な IAM ロールを確認します:
    • API Gateway リソースの管理とサービスの有効化:roles/apigateway.admin および roles/serviceusage.serviceUsageAdmin
    • ゲートウェイのサービスアカウントの作成と API 構成への関連付け:roles/iam.serviceAccountAdmin および roles/iam.serviceAccountUser
    • コンシューマー プロジェクトでの API キーの管理:roles/serviceusage.apiKeysAdmin
    • ゲートウェイのサービスアカウントによるバックエンドの呼び出し:roles/run.invoker(Cloud Run または第 2 世代の関数)または roles/cloudfunctions.invoker(第 1 世代の関数)

判断マトリクス:クライアント認証、バックエンドのセキュリティ、クォータ

セキュリティ要件に合ったレイヤーを選択してください。

目的設定するメカニズム主な制約詳細なリファレンス
クォータと課金のために、呼び出し元のコンシューマープロジェクトを識別するAPI キー(x-api-key ヘッダーの慣例。代替手段としてkeyクエリパラメーター)エンドユーザーの本人確認にAPIキーだけを決して使用しないでください。理由: APIキーはユーザーではなくGoogle Cloudプロジェクトを識別し、クライアントが抽出できるためです。クライアント認証
エンドユーザーまたは呼び出し元サービスを認証するJWT(OAS 2.0ではx-google-issuer / x-google-jwks_uriを使用するoauth2スキーム、またはOAS 3.xではx-google-auth)オペレーションレベルのsecurityはルートのsecurityを上書きします。ユーザーの識別とクォータの両方が必要なエンドポイントでは、同じセキュリティ要件オブジェクトにapi_key: []とJWTスキームを含めてください。クライアント認証
バックエンドサービスへの直接呼び出しをブロックする専用のゲートウェイサービスアカウント(--backend-auth-service-account)+ roles/run.invoker + バックエンドの--no-allow-unauthenticated稼働中のバックエンドに--no-allow-unauthenticatedを設定する前に、必ず--backend-auth-service-accountを指定したゲートウェイ設定をロールアウトしてください。そうしないと、403によるダウンタイムが発生します。バックエンドのセキュリティ
コンシューマープロジェクトごとにリクエストをレート制限する(1/min/{project})x-google-management(OAS 2.0)またはx-google-api-management(OAS 3.x)+ x-google-quotaAPIのいずれかのゲートウェイが、そのクォータメトリクスを参照する古い設定で稼働している間は、新しいAPI設定の作成時にクォータメトリクスの名前を決して変更または削除しないでください。理由: 設定の作成によってAPI全体のクォータが直ちに上書きされ、古いゲートウェイでHTTP 500 Failed to call Service Control Quotaが発生するためです。クォータとレート制限
/mcp上のMCPのtools/listとtools/callを保護する(パブリックプレビュー)x-google-api-management.mcp.tools-list.security(JWTまたはAPIキーのスキームを正確に1つ)+ オペレーションのsecurityとx-google-mcp-tool: falsex-google-mcp-tool: falseはオペレーションをMCPから隠すだけです。保護または削除しない限り、基盤となるRESTルートは引き続き有効です。MCPトラフィックのセキュリティ

実行ワークフローと検証ループ

API Gateway のセキュリティまたはクォータ設定を作成または更新する場合は、ダウンタイムが発生しないよう、次の手順に従ってください。

  1. ゲートウェイのサービスアカウントを作成し、バックエンドの呼び出し権限を付与します:
    • バックエンドセキュリティの手順 1~3 に従って {gateway_sa_name} を作成し、{backend_service} に roles/run.invoker を付与する前に、人間の承認を求めます。
    • バックエンドのハンドラーコードを更新し、Authorization ではなく X-Apigateway-Api-Userinfo(base64url でエンコードされた JSON)から検証済みのユーザー要求をデコードするようにします。
  2. OpenAPI の認証とクォータの定義を作成します:
    • クライアント認証とクォータとレート制限にある OpenAPI 2.0 または OpenAPI 3.0.x のテンプレートとプロバイダー表を使用します。
    • 仕様で MCP(x-google-api-management.mcp)を有効にする場合は、tools-list に JWT または API キーのスキームを 1 つだけ設定し(ルートの security リストにも JWT スキームを記載します)、MCP トラフィックのセキュリティを参照して、オペレーションごとの除外設定を確認します。
  3. api-configs create を実行する前に、クォータ指標の検証ループを実行します:
    • 有効な仕様にも {candidate_openapi_spec} にもクォータ指標(x-google-management.metrics または x-google-api-management.metrics)が定義されていない場合は、この手順をスキップします。
    • クォータを定義または変更する API 設定を作成する前に、人間の承認を求めます。api-configs create は API のすべてのゲートウェイにわたってクォータ定義を直ちに置き換えるためです。
    • デフォルトでは、scripts/check_quota_metrics.py を実行し、{project_id} 内の {api_id} にデプロイされているすべての有効なゲートウェイを対象に検証します:
      python3 scripts/check_quota_metrics.py \
        --spec={candidate_openapi_spec} \
        --project={project_id} \
        --api={api_id}
      
    • gcloud にアクセスできないオフライン環境での代替手順(現在 API のゲートウェイが提供している各設定について、--baseline-spec を指定します):
      python3 scripts/check_quota_metrics.py \
        --spec={candidate_openapi_spec} \
        --baseline-spec={previous_openapi_spec} \
        --dry-run
      
    • scripts/check_quota_metrics.py がコード 1(status: "FAIL")で終了した場合は、不足している指標と上限を {candidate_openapi_spec} に追加し、ignored_quota_extensions に記載されている各 x-google-quota を適用対象のオペレーションに移動してから、コード 0(status: "PASS")で終了するまでスクリプトを再実行します。ユーザーが意図的に上限を削除したい場合は、その削除によって API のすべてのゲートウェイから該当する上限が削除されるため、ユーザーに確認してください。skipped_configs が空でない場合は、スクリプトがそれらの API 設定(gRPC 設定など)を検査していないことをユーザーに伝え、クォータ指標と上限を手動で確認します。コード 2 で終了した場合は、標準エラーに出力された問題を修正します。対象となるのは、CLI 引数、gcloud の認証、またはスクリプトで検査できない API 設定です。
  4. API 設定を作成し、ゲートウェイを更新して、マネージドサービスを有効にし、バックエンドを保護します:
    • バックエンドセキュリティの手順 4~5 に従って gcloud api-gateway api-configs create と gcloud api-gateway gateways update を実行し(本番ゲートウェイを更新する前に、人間の承認を求めます)、コンシューマープロジェクトで API の managedService を有効にして(クライアント認証)、その後 {backend_service} に --no-allow-unauthenticated を設定します。
    • バックエンドの *.run.app URL への直接呼び出しが 403 を返し、ゲートウェイの defaultHostname への未認証の呼び出しが 401 を返し、認証済みの呼び出しが 200 を返すことを確認します。

デプロイ前チェックリスト

  • 専用の {gateway_sa_name} に roles/run.invoker(または roles/cloudfunctions.invoker)が付与されており、ゲートウェイ設定が有効になった後に --no-allow-unauthenticated が適用されています。
  • バックエンドコードがユーザーのクレームを取得するために X-Apigateway-Api-Userinfo をデコードしています。
  • ゲートウェイの defaultHostname(*.gateway.dev)は無効化できないため、セキュリティの適用が、ゲートウェイの前段にあるロードバランサーまたは Google Cloud Armor のみに依存していません。
  • 割り当て量制限が適用されるすべての操作で API キー(api_key: [])が必須となっており、各コンシューマープロジェクトで API の managedService が有効化され、API キーで許可されています。
  • python3 scripts/check_quota_metrics.py が、アクティブなゲートウェイ設定、または api-configs create の前にすべてのベースライン仕様に対して、status: "PASS"(終了コード 0)を返します。
  • MCP が有効な場合、x-google-api-management.mcp.tools-list.security で JWT または API キーのスキームがちょうど 1 つ指定されており(JWT スキームはルートの security リストにも含まれています)、REST でも管理エンドポイントが保護されています。また、x-google-mcp-tool: false が指定されています。

リソースのクリーンアップ

テスト環境またはステージング環境の終了時に継続的な課金を避けるため、人の承認を得て、依存関係の順序に従ってゲートウェイ、すべての API 設定、API、サービスアカウントを削除してください。

gcloud api-gateway gateways delete {gateway_id} --location={region} --project={project_id}
gcloud api-gateway api-configs delete {config_id} --api={api_id} --project={project_id}
gcloud api-gateway apis delete {api_id} --project={project_id}
gcloud iam service-accounts delete {gateway_sa_name}@{project_id}.iam.gserviceaccount.com --project={project_id}

コメント