実施したかったこと
以下のように Amplify の前段に CloudFront を配置し、AWS WAF の IP 制限を実装しようとしていました。
Amplify の Basic 認証機能を設定しますが、CloudFront からアクセスする際はカスタムヘッダー (Authorization) を付与して Basic 認証を通過します。

悪意のある第三者 (攻撃者) は、CloudFront (cloudfront.example.com) にアクセスしようとすると IP 制限によりブロックされ、(図の青い線)
IP 制限をバイパスするためにオリジンである Amplify (amplify.example.com) にアクセスしようとすると Basic 認証によってブロックされる (図の赤い線) … という形でアプリケーション保護を提供できます。
こちらの構成は以下の通り AWS のガイダンスにも記載されているような内容なのですが、本構成でエラーが発生したため対策と併せて共有します。
AWS Amplify がホストするウェブアプリケーションの AWS WAF を有効にする
エラー内容
CloudFront のドメイン (cloudfront.example.com) にアクセスすると 403 Forbidden となりました。
WAF のログを確認したところ、なぜかアクセス元がユーザーの拠点IPではなく 130.176.135.77 等の CloudFront の IP (※1) になっており、WAF の IP 制限ルールでブロックされていました。

※1 これが CloudFront の IP であることは、AWSマネージドプレフィックスリストから確認しています
原因
CloudFront のオリジンリクエストポリシーで「AllViewer」を使用して全ての HTTP ヘッダー・Cookie・クエリ文字列をオリジン (Amplify) に転送するようにしていたのですが、

実は多段 CloudFront の構成で Host ヘッダーを転送してしまうとアクセスのループが発生してしまうようです。
Amplify も内部的には CloudFront を利用しているので、このケースに当てはまります。図にすると以下のようなものになると推測しています。

今回のケースでは、IP 制限によりループが途中でブロックされています。
対処方法
Host ヘッダーを転送しないよう、AWS マネージドのオリジンリクエストポリシー「AllViewerExceptHostHeader」を利用するか、

もしくは以下のように Host ヘッダーのみ転送しないオリジンリクエストポリシーを作成し、対象のディストリビューションに適用することで本事象は解消しました。

投稿者プロフィール
- 2015年8月入社。弊社はインフラ屋ですが、アプリも作ってみたいです。