[アップデート] AWS WAF のカスタムヘッダーやレスポンスボディでラベル値を動的に展開できる「動的ラベル補間」が追加されました
いわさです。
AWS WAF にはルールの評価時にリクエストへ「ラベル」を付与し、後続のルールでそのラベルを参照して処理を分岐させる仕組みがあります。
カスタムヘッダーやカスタムレスポンスの機能で、ラベルの値に応じてオリジンにヘッダーを送信したり、ブロック時レスポンスのカスタマイズが出来ます。
ただ従来は、ラベル値ごとに個別のルールを作成し、静的な文字列を設定する必要がありました。
また、カスタムレスポンスボディも固定テキストしか設定できず、ブロックページにリクエスト固有の情報を含めることが出来ませんでした。
これが先日の AWS WAF のアップデートで「動的ラベル補間(Dynamic Label Interpolation)」が追加されました。
ヘッダーやレスポンスボディの値フィールドに ${namespace:} と書くだけで、実際に付与されたラベル値に自動展開されるようになります。
今回こちらを確認してみたので紹介します。
アップデート前
例えば顧客の Tier(Enterprise / standard / trial)をオリジンにヘッダーで伝えたい場合、従来は Tier ごとラベル判定して静的ヘッダー値をオリジンへ転送するルールを用意する必要がありました。


また、ブロック時にはカスタムレスポンスを設定できるのですが、固定テキストのみでブロックページにリクエスト固有の情報(IP やリクエスト ID)を含めることが出来ませんでした。

アップデート後
東京リージョンで ALB に WAF WebACL をアタッチして動的ラベル補間を確認してみました。
カスタムリクエストヘッダーの補間
動的ラベル補間では、カスタムヘッダーの値フィールドに ${namespace:} 構文を書くことで、ラベルの名前空間に一致する値が自動的に展開されます。
ステートメントも従来の「ラベル」単体マッチではなく「名前空間」マッチを使うことで、名前空間内のどのラベルが付与されていてもルールがヒットするようになります。
先ほどの Tier 転送の例だと、名前空間マッチと補間構文 ${...app:tier:} を使うことで、どの Tier が来ても自動的に展開されるルールを 1 つ書くだけで済みます。

結果として、先ほどの検証例の場合だと 3 つあった転送ルールが 1 つに集約できます。

実際に x-api-key: pk_enterprise_12345 ヘッダーを付けてリクエストを送り、WAF のサンプルリクエスト API で確認してみます。
% aws wafv2 get-sampled-requests \
--web-acl-arn "arn:aws:wafv2:ap-northeast-1:123456789012:regional/webacl/waf-dynamic-label-demo/7049afdf-73df-4e9b-943d-8e4033eb164c" \
--rule-metric-name "forward-tier" \
--scope REGIONAL \
--time-window StartTime=2026-05-13T07:00:00Z,EndTime=2026-05-13T09:00:00Z \
--max-items 5 \
--region ap-northeast-1
{
"SampledRequests": [
{
"Request": {
"ClientIP": "203.0.113.1",
"Country": "JP",
"URI": "/",
"Method": "GET",
"HTTPVersion": "HTTP/1.1",
"Headers": [
{
"Name": "x-api-key",
"Value": "pk_enterprise_12345"
}
]
},
"Action": "COUNT",
"RequestHeadersInserted": [
{
"Name": "x-amzn-waf-x-customer-tier",
"Value": "enterprise"
}
]
}
]
}
RequestHeadersInserted で、カスタムラベル app:tier:enterprise の末尾値 enterprise がヘッダーに展開されていることが確認できます。
なお、公式ドキュメントによると、カスタムラベルの補間では完全修飾名前空間(awswaf:ACCOUNT_ID:webacl:WEBACL_NAME:app:tier:)を使う必要があるみたいです。
The label match statement works with the short namespace, but interpolation references must always use the fully-qualified namespace.
カスタムレスポンスボディの補間
カスタムレスポンスボディに ${awswaf:ip:} や ${awswaf:request_id:} のような合成ラベルを埋め込めるようになりました。

cURL でアクセスしてみます。
% curl -s http://waf-demo-alb-918047397.ap-northeast-1.elb.amazonaws.com/block-page
Your request was blocked.
IP: 203.0.113.1
Request ID: 1436823463:1-6a0430f6-44150fa11ef6d6db11ffa59b
If you believe this is an error, contact support with the Request ID above.
${awswaf:ip:} がクライアント IP に、${awswaf:request_id:} が WAF リクエスト ID に解決されていることが確認できます。
カスタムレスポンスヘッダーの補間
302 リダイレクトの Location ヘッダーにも補間構文を使えます。
% curl -s -D - http://waf-demo-alb-918047397.ap-northeast-1.elb.amazonaws.com/verify
HTTP/1.1 302 Moved Temporarily
Server: awselb/2.0
Date: Wed, 13 May 2026 08:06:21 GMT
Content-Length: 0
Connection: keep-alive
location: /verify?ip=203.0.113.1&rid=1436823463:1-6a0430fd-58c8d69e26ff5b84431e5e4e
Location ヘッダーにも動的に値が埋め込まれていることが確認できます。良いですね!
補間の解決ルール
公式ドキュメントによると、解決ルールは以下のとおりとのことです。
- 名前空間に一致するラベルが 1 つ → その末尾の値に解決(例:
enterprise) - 複数 → カンマ区切りのリストに解決(例:
non_browser_user_agent,automated_browser) - なし → 空文字に解決
なお、1 つの値フィールドに含められるプレースホルダーは最大 10 個までみたいです。
合成ラベルの種類
今回の検証では ${awswaf:ip:} と ${awswaf:request_id:} を確認しましたが、以下の 4 種類が用意されているとのことです。
| 合成ラベル | 説明 |
|---|---|
${awswaf:request_id:} |
WAF リクエスト ID |
${awswaf:ip:} |
クライアント IP アドレス |
${awswaf:ja3:} |
JA3 TLS フィンガープリント |
${awswaf:ja4:} |
JA4 TLS フィンガープリント |
JA3/JA4 は HTTPS 接続時に値が取得できるものだと思います。
今回は HTTP で検証したので確認できていません。
さいごに
本日は AWS WAF に動的ラベル補間が追加されたので確認してみました。
カスタムレスポンスボディ、カスタムレスポンスヘッダー、カスタムリクエストヘッダーの 3 箇所すべてで補間が動作することを確認できました。
ラベル値ごとに個別のルールを書いていた部分を 1 つのルールに集約できるのは、ルール管理の手間が減って良いですね。
あとはブロックページにリクエスト ID を埋め込めるようになったので、ユーザーから「ブロックされた」と問い合わせがあった際にリクエスト ID を教えてもらってトラブルシューティングしやすくするとか、そんな活用もできるかもしれない。
カスタムラベルの補間で完全修飾名前空間が必要な点は少し面倒ですが、ラベルマッチステートメントの Key はショートネームで動くので設定自体はシンプルに保てそうです。









