Contents
Apigee のセキュリティポリシー全体像と主要種類
この章では、Apigee が提供する代表的な ポリシー を俯瞰し、実務での選択基準を整理します。API の保護は「認証・認可」「レート制御」「脅威防御」の3層に分けて考えると管理が楽になるため、各ポリシーがどの層に属するかを明確に示します。
OAuthV2
アクセストークンの取得・検証・スコープチェックを行うポリシーです。OAuth 2.0 に準拠した認可サーバー(Apigee Edge の内蔵 Authorization Server でも外部 IdP でも)と連携し、無効トークンや期限切れトークンは 401 で即座に拒否します。
Verify API Key
シンプルな API キーの有無・状態(有効/無効)を確認します。OAuth を導入できないレガシークライアントや、内部サービス間の軽量認証に適しています。
Spike Arrest
短時間に集中したリクエストスパイクを抑えるレートリミッターです。「秒単位」または「分単位」の上限数を設定でき、バックエンドが過負荷になる前に 429 を返します。
Quota
日次・月次などの期間ベースでリクエスト総数を制限します。サブスクリプションモデルや無料枠提供時に「利用上限」を保証するために必須です。
ThreatProtection
SQL インジェクション、XSS、コマンドインジェクション等の OWASP Top 10 に対応した脅威を検出し、攻撃と判定されたリクエストは 403 で遮断します。基本的な Web アプリケーション防御が手軽に組み込めます。
要点まとめ
認証系は OAuthV2 と Verify API Key を用途に合わせて使い分ける。
レート制御は瞬間的なスパイクを Spike Arrest、期間累計を Quota で管理する。
脅威対策は ThreatProtection* をデフォルトで組み込むことで多くの攻撃を自動防御できる。
管理 UI で新規ポリシーを作成し XML 設定例を確認する手順
このセクションでは、Apigee の管理コンソールから ポリシーを作成 → XML 定義を取得 までの流れを具体的に示します。UI 操作はコードレビューと同等にトレーサビリティが確保できるため、チームでの共有や教育に有効です。
UI からポリシーを追加するフロー
まずは UI 上で実際にポリシーを配置し、必要項目を入力します。以下の手順は「PreFlow」への追加例ですが、任意の Flow に置き換えても同様です。
- 左メニュー → API プロキシ を選択し、対象プロキシ名をクリック。
- 上部タブの 「フローエディタ」 → 「PreFlow」(または任意の Flow)を開く。
- 右上の 「+ ポリシー追加」 ボタンでポリシーカタログを表示する。
- カタログから 「OAuthV2」 または 「Verify API Key」 を選び、「作成」 をクリック。
- ポリシー名(例:
OAuth-Validate)を入力し、「保存」 → 「デプロイ」 の順に進めると基本設定が完了する。
OAuthV2(トークン検証)の XML テンプレート
以下は UI で作成した OAuthV2 ポリシーの代表的な XML 定義です。Apigee が提供する公式スキーマ(apiproxy/policy/ ディレクトリ配下)に準拠していますので、手動編集時も同様の構造を保ちます。
|
1 2 3 4 5 6 7 8 9 |
<OAuthV2 name="OAuth-Validate"> <Operation>VerifyAccessToken</Operation> <AccessTokenPrefix>Bearer </AccessTokenPrefix> <TokensRequired>true</TokensRequired> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <!-- 必要に応じてスコープチェックを追加 --> <Scope>read write</Scope> </OAuthV2> |
Verify API Key(キー検証)の XML テンプレート
次に VerifyAPIKey ポリシーのサンプルです。APIKeyRef にはヘッダーやクエリパラメータなど、実際にキーが送られる場所を指定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<VerifyAPIKey name="APIKey-Check"> <APIKeyRef>request.header.api_key</APIKeyRef> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <FaultRules> <FaultRule name="InvalidKey"> <Step> <Name>Raise-InvalidKey-Fault</Name> <!-- 401 が返されたときにカスタムエラーメッセージを出す --> <Condition>(response.status = 401)</Condition> </Step> </FaultRule> </FaultRules> </VerifyAPIKey> |
注記
Apigee のポリシー XML は公式スキーマ(現在はv1系)に従います。2026 年版という表現は実在しないため、最新の公式ドキュメントをご参照ください。
Management API と curl でポリシー作成・更新を自動化する方法
手作業だけではスケールできません。ここでは サービスアカウント を利用した OAuth2 認証から、Management API へポリシーを作成/更新する一連のフローを示します。
サービスアカウントでアクセストークンを取得する手順
Apigee の Management API は Google Cloud IAM と統合されているため、サービスアカウントの JSON キー を使ってトークンを取得します。エンドポイントは公式ドキュメントに記載の通り https://oauth2.googleapis.com/token です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 環境変数に設定した JSON キーファイルへのパス KEY_FILE=$HOME/keys/apigee-sa.json # JWT を作成し、OAuth トークンを取得 ACCESS_TOKEN=$(curl -s -X POST \ "https://oauth2.googleapis.com/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \ --data-urlencode "assertion=$(cat $KEY_FILE | \ python3 -c 'import sys, json, jwt, time; \ data=json.load(sys.stdin); \ print(jwt.encode({\"iss\":data[\"client_email\"],\"scope\":\"https://www.googleapis.com/auth/apigee\",\"aud\":\"https://oauth2.googleapis.com/token\",\"exp\":int(time.time())+3600,\"iat\":int(time.time())}, data[\"private_key\"], algorithm=\"RS256\"))')") \ | jq -r .access_token) |
ポイント
gcloud auth print-access-tokenでも同等のアクセストークンが取得できますが、CI 環境では上記 JWT フローが汎用的です。
ポリシー作成リクエスト(正式エンドポイントと JSON 形式)
Apigee の Management API で ポリシーを作成 する正しいエンドポイントは次の通りです。
|
1 2 |
POST https://apigee.googleapis.com/v1/organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}/policies/{policyName} |
{policyName} は XML ファイル名(拡張子なし)と同一にします。ペイロードは XML か JSON のどちらでも受け付けますが、ここでは JSON を例示します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# 1️⃣ ポリシー定義 JSON(OAuthV2 の例) cat > oauth-policy.json <<'EOF' { "name": "OAuth-Validate", "type": "OAuthV2", "configuration": { "Operation": "VerifyAccessToken", "AccessTokenPrefix": "Bearer ", "TokensRequired": true, "Scope": "read write" } } EOF # 2️⃣ curl でポリシー作成 curl -X POST \ "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/${ENV}/apis/${API}/revisions/${REV}/policies/OAuth-Validate" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d @oauth-policy.json |
エラーレスポンスの基本解析
| HTTP ステータス | 主な原因 | 対処例 |
|---|---|---|
| 400 | JSON スキーマが公式仕様と不一致 | configuration のキー名・型を公式リファレンスで再確認 |
| 401 | アクセストークンが無効または期限切れ | トークン取得フローにリトライロジックを追加 |
| 409 | 同名ポリシーが既に存在 | PUT に切り替えて上書き、あるいは名前を変更 |
要点
Management API の PATCH/PUT は「フロー全体」や「ポリシー単体」の更新に使います。ポリシー作成は必ず POST + ポリシー名 の形式で行ってください。
プロキシフローへのポリシー添付と環境別リビジョンデプロイ手順
作成したポリシーを実際の API フローに組み込む段階です。UI と Management API 両方での手順を示すことで、スクリプト化や自動テストへの応用がしやすくなります。
UI でフローへポリシーを割り当てる方法
- API プロキシ → フローエディタ を開き、対象の Flow(例:
PreFlow)を選択。 - 左側「ステップ」領域に先ほど作成したポリシー名(例:
OAuth-Validate)をドラッグ&ドロップ。 - 必要なら Condition フィールドに Apigee の条件式を書きます(例:
request.header.client_id != null)。
Apigee では条件式は独自の Expression Language を使用し、SpEL という名称は誤解を招くためここでは「Apigee 条件式」と表記します。
Management API でフローへポリシーを割り当てる方法
以下は Conditional Flow(DefaultFlow)に OAuth-Validate を追加する PATCH リクエスト例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
curl -X PATCH \ "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/${ENV}/apis/${API}/revisions/${REV}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "flow": { "name":"DefaultFlow", "condition":"request.verb == \"GET\"", "steps":[{"name":"OAuth-Validate"}] } }' |
ポイント
flowオブジェクトは公式スキーマv1/flowに準拠しています。stepsは配列で、各要素のnameがポリシー名となります。
リビジョン作成・テスト環境デプロイ・本番デプロイ手順
| 手順 | 操作内容 | 例示コマンド |
|---|---|---|
| 1️⃣ | 新規リビジョンを生成(rev1 が自動付与される) |
curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/apis/${API}/revisions" |
| 2️⃣ | テスト環境へデプロイ | curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/test/apis/${API}/revisions/${REV}/deployments" |
| 3️⃣ | 本番環境へデプロイ(テストが成功したら実行) | curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/prod/apis/${API}/revisions/${REV}/deployments" |
| 4️⃣ | 必要に応じてロールバック | curl -X DELETE "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/test/apis/${API}/revisions/${REV}" |
注意点
デプロイ前は必ずテスト環境で Trace 機能や curl シナリオを実行し、ポリシーの期待通りの挙動を確認してください。
動作検証・カスタムロジック実装・CI/CD 自動化・トラブルシューティング
手動でのリクエストテスト手順と期待結果
| テストケース | コマンド例 | 期待されるステータス |
|---|---|---|
| OAuthV2 正常 | curl -i -H "Authorization: Bearer ${VALID_TOKEN}" https://api.example.com/v1/orders |
200 OK(有効トークン) |
| OAuthV2 無効 | 同上だが ${INVALID_TOKEN} を使用 |
401 Unauthorized |
| Spike Arrest 超過 | for i in {1..10}; do curl -s -o /dev/null -w "%{http_code}\n" https://api.example.com/v1/ping; done |
先頭 N 回は 200、上限超過分は 429 Too Many Requests |
| Quota 超過 | 大量リクエストを送信し日次上限を突破 | 403 Forbidden(Quota exceeded) |
カスタムスクリプト(JavaScript / Python)の配置とデバッグ方法
- スクリプトはプロキシの
resources/jsc/またはresources/python/ディレクトリに配置。 - ポリシー XML で参照例:
xml
<Javascript name="Custom-Logic">
<ResourceURL>jsc/custom.js</ResourceURL>
</Javascript>
- Trace 機能を有効化し、
console.log()の出力が Trace パネルに表示されることを確認。 - 永続的なログが必要な場合は
MessageLoggingポリシーと組み合わせ、Cloud Logging に転送する設定を追加。
CI/CD(Cloud Build / GitHub Actions)でポリシーデプロイを自動化
Cloud Build のサンプル (cloudbuild.yaml)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | # サービスアカウントで認証 gcloud auth activate-service-account --key-file=$$KEY_FILE # ポリシー JSON を取得(リポジトリの policies/ ディレクトリ) POLICY_PATH=policies/oauthv2.json # Management API へ POST(新規作成または上書きは PUT が安全) curl -X PUT "https://apigee.googleapis.com/v1/organizations/${_ORG}/environments/${_ENV}/apis/${_API}/revisions/${_REV}/policies/OAuth-Validate" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -d @${POLICY_PATH} # デプロイ curl -X POST "https://apigee.googleapis.com/v1/organizations/${_ORG}/environments/${_ENV}/apis/${_API}/revisions/${_REV}/deployments" |
GitHub Actions のサンプル (.github/workflows/apigee.yml)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
name: Deploy Apigee Policies on: push: paths: - 'policies/**' jobs: deploy: runs-on: ubuntu-latest env: ORG: ${{ secrets.APIGEE_ORG }} ENV: test API: my-api REV: rev1 steps: - uses: actions/checkout@v3 - name: Authenticate to GCP uses: google-github-actions/auth@v1 with: credentials_json: ${{ secrets.GCP_SA_KEY }} - name: Deploy policy via curl run: | ACCESS_TOKEN=$(gcloud auth print-access-token) curl -X PUT "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/${ENV}/apis/${API}/revisions/${REV}/policies/APIKey-Check" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d @policies/apikey.json |
よくあるエラーと対処法チェックリスト
| エラー | 主な原因 | 確認ポイント | 推奨対策 |
|---|---|---|---|
| ポリシー未適用 | リビジョンがデプロイされていない | GET /v1/organizations/{org}/environments/{env}/apis/{api}/revisions でデプロイ状態を確認 |
デプロイコマンドを再実行し、対象リビジョンが環境に紐付いているか検証 |
| スキーマエラー (400) | JSON/XML の構造が公式スキーマと不一致 | type と configuration キーの綴り・型を公式リファレンスで照合 |
公式ドキュメント(Apigee Policy Reference)の最新例に合わせる |
| レートリミット超過 (429) | Spike Arrest / Quota の上限が低すぎる | テスト時のリクエスト数と設定値を比較 | 上限を段階的に緩和、またはバックエンド側でキャッシュ導入 |
| 認証失敗 (401) | サービスアカウント権限不足、トークン期限切れ | IAM で Apigee Administrator または Apigee Runtime Admin ロールが付与されているか |
必要ロールを追加し、アクセストークン取得フローにリトライ処理を組み込む |
| ポリシー名重複 (409) | 同一名前のポリシーが既に存在 | GET /policies で一覧取得 |
名前をユニーク化するか、上書きしたい場合は PUT に切り替える |
まとめ
エラーログは必ず Apigee Trace と Cloud Logging の両方で確認し、原因特定に必要な情報を確保してください。
*CI/CD パイプラインではデプロイ前にテスト環境で自動化された curl シナリオを走らせることで、本番障害のリスクを大幅に低減できます。
本稿のまとめ
- ポリシーは認証・レート制御・脅威防御の3層 に分けて選定し、実装時は公式スキーマに沿った XML/JSON を使用する。
- UI と Management API の両方を把握 しておくと、手動作業と自動化のハイブリッドが可能になる。
- アクセストークン取得は
https://oauth2.googleapis.com/tokenを利用し、サービスアカウントの権限を正しく設定することが前提です。 - ポリシー追加・フロー割り当て・デプロイは順序通りに実行 し、必ずテスト環境で Trace と curl による検証を行う。
- CI/CD パイプライン(Cloud Build / GitHub Actions) を組み込めば、ポリシーのバージョン管理と安全な本番展開が実現できます。
これらのベストプラクティスに従えば、Apigee 上で堅牢かつスケーラブルな API ガバナンスを構築できるでしょう。