Amazon Web Services ブログ

Amazon API Gateway で API キーを使わずに認証とアクセス制御を行う

はじめに

Amazon API Gateway の API キーの利用を検討したものの、API キーの制約によってプロダクトの要件を満たせないことがあります。その際、それぞれ Amazon Cognito を利用した認証と AWS WAF を用いた IP ベースのレート制限を利用するという代替案をご紹介いたします。

背景

筆者は普段、プロトタイピングソリューションアーキテクトとして、お客様のプロダクトのプロトタイプ作りをお手伝いさせていただいております。お客様の中には、ユーザー認証やアクセス制御として Amazon API Gateway の API キーの利用を検討している場合があります。しかし、API キーでお客様の要件を満たせるかどうかは、慎重に検討が必要です。

  1. API キーには数の上限があります。Amazon API Gateway のクォータと重要な注意点 にも記載がある通り、1 アカウント、1 リージョンあたりの API キー数の上限は 500 です。そのため、多くのユーザーを抱える API では API キーによる認証は適さないと言えます。
  2. API キーのセキュリティについても検討が必要です。API キーは有効期限が設定できないので、有効期限を設定可能な認証方法に比べ、漏洩した際のリスクが大きいです。

このように、 API キーは容易に利用が可能な反面、いくつかの考慮事項があるため、選定は慎重に行う必要があります。次の考察で、認証とアクセス制限について、それぞれ代替案をご紹介したいと思います。

考察

では、ユースケース別に代替案をご紹介いたします。

一つ目は、認証として API キーを利用したいケースです。それぞれのユーザーに対し、ユニークな API キーを割り当てることを想定しています。この場合、背景にて説明した API キー数の上限とセキュリティについて検討が必要です。API キーを使用した使用量プランの作成と使用 のAPI キーと使用量プランのベストプラクティスにも記載がある通り、基本的に API キーは認証として利用すべきではありません。そのような場合は、Amazon Cognito による ID トークンを用いた認証をご検討ください。

Cognito のユーザープールは、最大ユーザー数 40,000,000 と API キーに比べると十分な数があります。また、ID トークンは 5 分 – 1 日 の間で有効期限を設定可能です。詳細は Amazon Cognito のクォータ をご参照ください。また、Amazon API Gateway と Amazon Cognito の統合方法については REST API と Amazon Cognito ユーザープールを統合する をご参照ください。

続いて、API キーのスロットリング機能を利用したいケースです。この場合はお客様の要件に対して deep dive が必要です。もし、単にユーザーからの過多なアクセスを制限したいという要件であれば、AWS WAF の IP ベースのレート制限を利用することが可能です。AWS WAF の IP ベースのレート制限では、各発信元 IP アドレスに対し、5分間あたりのリクエスト数を設定して制限をかけることができます。詳細な仕様については レートベースのルールステートメント をご参照ください。また、AWS WAF を利用すれば、セキュリティ侵害や一般的なウェブの脆弱性から API を保護することも可能になります。

実際にアクセス制限がかかる様子を次の検証にてご紹介いたします。

検証

では、AWS WAF を利用した IP ベースのレート制限の挙動を確認してみたいと思います。事前に、Amazon API Gateway と AWS Lambda を統合し、ステータスコード 200 を返すだけのエンドポイントを作成しました。作成方法は Lambda 統合で API Gateway REST API を構築する をご参照ください。また、AWS WAF は下図のように 5 分あたり 100 リクエストに制限を設定いたしました。設定方法は AWS WAF の開始方法 をご参照ください。

AWS WAFの設定

では続いて、設定した制限に対してアクセス過多な状態を作ります。今回は 5 分あたり 100 リクエストとリクエスト数が少ないので、簡易なスクリプトを作成し、アクセスが制限されている様子を確認します。スクリプトは以下のように、直列で curl コマンドを実行するものを用意しました。ステータスコードが 200 であれば . (ドット)、そうでない場合は E を表示するようにしました。

#!/bin/bash

while :
do
    status=`curl https://xxxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/test -o /dev/null -w '%{http_code}' -s`

    if [ $status = '200' ]; then
        echo -n '.'
    else
        echo -n 'E'
    fi
done

ではこちらのスクリプトを実行してみます。実行後しばらくすると、以下のような結果を出力していました。

スクリプトの実行結果

このように、一定時間実行し続けると、エラーが出るようになりました。

また、AWS WAF のコンソールにて、受け取ったリクエスト数とブロックしたリクエスト数をグラフで確認することが可能です。実際の画面がこちらです。

リクエストがブロックされている様子

緑が許可されたリクエスト数で、オレンジがブロックされたリクエスト数です。このように、最初は許可されていたリクエストが、一定数を超えたところからブロックされている様子がわかります。

結論

この記事では、Amazon API Gateway の API キーの利用を検討したものの、API キーの制約によってプロダクトの要件を満たせない場合、それぞれ Amazon Cognito を利用した認証と AWS WAF を用いた IP ベースのレート制限を利用するという代替案をご紹介いたしました。もちろん、要件次第では API キーを利用するという選択肢もあるので、お客様の要件と照らし合わせて最適なアーキテクチャを構成してください。

この記事はアマゾン ウェブ サービス ジャパンの鈴木 太一郎が執筆しました。