はじめに
WAFでLambdaからのアクセス制御を行ったことはありますか?
WAFでのアクセス制御といえば、IPアドレスやAWSが提供するマネージドルールを使用することが多いかと思います。
しかし、LambdaのIPアドレスは固定ではなく動的であり、そのIPレンジは非常に広範囲です。
そのため、 Lambdaからのアクセス制限をIPベースで行うことはほぼ不可能 です。
そこで、 今回は カスタムヘッダーを利用して、特定のLambdaからのアクセスだけに制限 してみました!
実際にどんな場面で使用したか
つい最近まで、CognitoはVPCエンドポイントに対応しておりませんでした。
そのため、プライベートな環境からインターネットを経由せずCognitoにアクセスするためには、CognitoのProxyのような役割を果たすLambdaを作成し、API Gatewayから呼び出すことで、Cognitoへのアクセスを行っていました。
そのため、CognitoのWAFで、前段のLambdaからのアクセスだけに絞りたかったのです。
現在はCognitoのVPCエンドポイントがサポート開始されておりますので、上記のような迂回構成は不要になるかと思います。
アップデート情報:Amazon Cognito ユーザープールが AWS PrivateLink とのプライベート接続のサポートを開始(2025/11/7)
https://aws.amazon.com/jp/about-aws/whats-new/2025/11/amazon-cognito-user-pools-private-connectivity-aws-privatelink/
実装
早速、実装に入っていきたいと思います!
①Parameter Store
Lambdaのカスタムヘッダーの値は、WAFで許可/拒否の判定に使用するため、言ってしまえば 「鍵」 のようなものになります。
そのため、カスタムヘッダーの値はLambdaのコードに直接記載するのではなく、Parameter Storeで保管するようにします。
カスタムヘッダーの値の取り扱いには十分注意してください。
必要に応じて、SecretManagerを使用してください。
Parameter Storeに/test/lambdaを作成し、[test123]という値を保存します。
②Lambda
次に、LambdaのコードでParameter Storeから文字列(test123)を取得して、カスタムヘッダー(x-lambda-auth)に埋め込みます。
get_parameterという関数を作成して、Parameter Storeから値を取り出しています。
ssm = boto3.client("ssm")
def get_parameter(name: str) -> str:
resp = ssm.get_parameter(Name=name, WithDecryption=True)
return resp["Parameter"]["Value"]
def lambda_handler(event, context):
token = None
try:
token = get_parameter("/test/lambda")
except Exception as e:
print(f"warn: failed to load token from parameter store: {e}")
headers = {
"User-Agent": "waf-checker/1.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
}
if token:
headers["x-lambda-auth"] = token
LambdaのIAMロールにParameter Storeの"ssm:GetParameter"の権限を付与しておきます。
{
"Statement": [
{
"Action": [
"ssm:GetParameter"
],
"Effect": "Allow",
"Resource": <Parameter StoreのARN>
}
],
"Version": "2012-10-17"
}
③WAF
WAFでは、「AllowLambdaHeader」というルールを作成し、x-lambda-authヘッダーが[test123]と完全に一致した場合にALLOWするように設定します。
ここで、忘れてはいけないのは デフォルトアクションをBLOCKにする ことです。
私がコンソールから作成した際には、デフォルトでデフォルトアクションがALLOWになっていました。
本来はヘッダーが一致すればALLOW、一致しなければBLOCKとなるはずが、デフォルトアクションをALLOWにすると、WAFルールが意味をなさず全てのアクセスが通過してしまいます。
アクセス確認
Lambdaを実行して、WAFで許可されるのか確認してみます。
WAFのログを確認すると、「AllowLambdaHeader」のルールでALLOWされていることが分かります!

試しに、以下のようにヘッダーに誤った値("xxxxxxxxx")を入れて実行してみると、

セキュリティ上の注意
セキュリティを強化する上では、以下のことに注意してください。
- カスタムヘッダーの値は秘密情報として扱い、コードに直接書かず Parameter Store や Secrets Manager を利用する
- WAF のデフォルトアクションは BLOCK に設定する
- カスタムヘッダーの値がログに出力される可能性があるため、ログの取り扱いにも注意する
また、本記事の内容を実装する際は、必ず最新の公式ドキュメントを確認し、セキュリティリスクを十分に理解した上で対応してください。
まとめ
今回は、WAFでLambdaのアクセス制御を行いました。
特に、カスタムヘッダーを利用したWAFルールは、Lambdaに限らず活用機会があると思いますので、参考にしていただけたら嬉しいです!
We Are Hiring!




