4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lambda 関数 URL で Condition 句による IP アドレス制限が可能になったか検証する

4
Last updated at Posted at 2026-09-25

はじめに

2026/8/25 のアップデートで AWS Lambda 関数が IAM のリソースベースポリシーの全機能をサポートするようになりました。

Lambda function URLs (関数 URL) では、リクエストの認証タイプに AWS_IAM を選択すると、IAM エンティティのポリシーと Lambda のリソースベースポリシーに基づいてアクセスを制御できます。しかし、これまでリソースベースポリシーの設定に使う AddPermission API では指定できる条件キーが限られており、aws:SourceIp などの IAM グローバル条件コンテキストキーを使用した IP アドレス制限はできませんでした。仮に IP アドレス制限を実装したい場合は、Lambda 関数内で Event データの sourceIp を参照して独自に実装する必要がありました。

この点は、2022 年に Lambda function URLs がリリースされた際に検証し、以下の記事にまとめています。

2024 年のアップデートで CloudFront が Lambda 関数 URL オリジンへの Origin Access Control (OAC) をサポートしたため、CloudFront を前面に置き AWS WAF の IP セットを差し込む構成でも IP アドレス制限を実現できるようになっています。

今回のアップデートで新たに PutResourcePolicy API が追加され、完全な JSON ポリシードキュメントを設定できるようになりました。これにより、あらゆる種類の IAM 条件キーが利用可能になるとのことです。

本記事では、これまで関数 URL のリソースベースポリシー単体ではできなかった Condition 句による IP アドレス制限が、今回のアップデートで実際に可能になったかを検証します。

何が変わったのか

今回のアップデートで大きく変わったのは、条件キーの種類だけではなく、リソースベースポリシーの設定方式そのものです。IP アドレス制限などの条件キーが使えるようになったのも、この設定方式が変わったことによるものです。

これまで、Lambda 関数のリソースベースポリシーは AddPermission API で個別に Allow ステートメントを 1 つずつ追加する方式のみでした。この方式では、指定できる条件キーが aws:SourceArn、aws:SourceAccount、aws:PrincipalOrgID の 3 つに限られており、Deny ステートメントも記述できませんでした。

Individual permissions – Use the console or AddPermission API action to add single Allow statements. Individual permissions support only a limited set of condition keys (aws:SourceArn, aws:SourceAccount, and aws:PrincipalOrgID).

今回追加された PutResourcePolicy API では、完全な JSON ポリシードキュメントをリソースポリシーとして設定できるようになりました。S3 バケットポリシーや IAM ポリシーと同じように、複数のステートメント、複数の Principal、Allow と Deny の組み合わせ、そしてすべての IAM グローバル条件キーを 1 つのポリシー内で自由に定義できます。

Full JSON policy – Use the Lambda console, AWS CLI, or the PutResourcePolicy API action to add a complete JSON policy document. With a full JSON policy, you can use the complete range of IAM global condition keys, add multiple statements with multiple principals, and create explicit Deny statements.

両者の違いを整理すると以下のようになります。

観点 これまで(AddPermission API) 今回(PutResourcePolicy API)
ポリシー形式 特定のステートメントを追加 完全な JSON ポリシードキュメント
利用可能な条件キー aws:SourceArn, aws:SourceAccount, aws:PrincipalOrgID のみ すべての IAM グローバル条件キー
Deny ステートメント 利用不可 利用可能
Principal の指定 ステートメントごとに 1 つ 1 ステートメントに複数指定可能
ポリシーサイズ上限 — 20 KB

個別のステートメントを 1 つずつ追加する方式から、ポリシー文書全体をまとめて設定する方式が使えるようになったことで、IP アドレス制限をはじめとする細やかなアクセス制御も実現できるようになりました。なお、既存の AddPermission API で作成したポリシーは引き続き動作します。

検証の前提

  • 関数 URL の認証タイプは AWS_IAM に設定しています
  • AWS CLI を使用します

put-resource-policy は今回のアップデートで追加された新しいコマンドのため、実行には AWS CLI v2.36.28 以上が必要です。コマンドが Invalid choice: 'put-resource-policy' のようなエラーになる場合は、AWS CLI を更新してください。

やってみる

Allow + IpAddress では IP アドレス制限にならない

一見すると、Allow ステートメントに IpAddress 条件を付けて「特定の IP アドレスからのみ許可する」と書けば IP アドレス制限ができそうに思えます。しかし、この書き方では IP アドレス制限として機能しません。

これは IAM のポリシー評価ロジックによるものです。同一アカウント内では、アイデンティティベースポリシーとリソースベースポリシーの許可は和集合 (union) として評価されます。

If an action is allowed by an identity-based policy, a resource-based policy, or both, then AWS allows the action. An explicit deny in either of these policies overrides the allow.

つまりリソースベースポリシーの Allow に IpAddress 条件を付けても、他の経路からのアクセスを塞ぐ効果はありません。

一方、明示的な Deny はすべての Allow を上書きします。そのため、IP アドレスによるアクセス制限を行うには、NotIpAddress 条件を指定した Deny ステートメントで 許可したい IP アドレス以外からのリクエストを拒否する 方法を使います。この Deny ステートメントも、今回のアップデートで PutResourcePolicy API が追加されたことによって指定できるようになったものです。

PutResourcePolicy で IP アドレス制限付きポリシーを設定する

以下のような policy.json を作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowInvokeFromSpecificIP",
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "lambda:InvokeFunctionUrl",
            "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-function",
            "Condition": {
                "StringEquals": {
                    "lambda:FunctionUrlAuthType": "AWS_IAM"
                },
                "NotIpAddress": {
                    "aws:SourceIp": "xxx.xxx.xxx.xxx/32"
                }
            }
        }
    ]
}

put-resource-policy コマンドでポリシーをアタッチします。

aws lambda put-resource-policy \
  --resource-arn arn:aws:lambda:ap-northeast-1:123456789012:function:my-function \
  --policy file://policy.json

put-resource-policy は既存のリソースベースポリシーを上書きします。既存のポリシーがある場合は事前に get-resource-policy でバックアップを取得してください。

許可した IP アドレスからのリクエスト

aws:SourceIp に指定した IP アドレスからリクエストを送信します。AWS_IAM 認証のリクエストには SigV4 署名が必要なため、curl の --aws-sigv4 オプションで署名を付与しています。

$ curl -i https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/ \
  -H "X-Amz-Security-Token: ${AWS_SESSION_TOKEN}" \
  --aws-sigv4 "aws:amz:ap-northeast-1:lambda" \
  --user "${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}"

HTTP/1.1 200 OK
Date: Fri, 25 Sep 2026 04:48:45 GMT
Content-Type: application/json
Content-Length: 3021
Connection: keep-alive
x-amzn-RequestId: 
X-Amzn-Trace-Id: 

"Hello from Lambda!"

指定した IP アドレスからは NotIpAddress 条件に一致しないため Deny が発動せず、正常に 200 レスポンスが返りました。

許可されていない IP アドレスからのリクエスト

異なる IP アドレスの環境からリクエストを送信します。

$ curl -i https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/ \
  -H "X-Amz-Security-Token: ${AWS_SESSION_TOKEN}" \
  --aws-sigv4 "aws:amz:ap-northeast-1:lambda" \
  --user "${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}"

HTTP/1.1 403 Forbidden
Date: Fri, 25 Sep 2026 04:44:30 GMT
Content-Type: application/json
Content-Length: 144
Connection: keep-alive
x-amzn-RequestId: 
x-amzn-ErrorType: AccessDeniedException

{"Message":"Forbidden. For troubleshooting Function URL authorization issues, see: https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html"}

指定した IP アドレス以外からのリクエストは NotIpAddress 条件に一致して明示的な Deny が発動し、403 Forbidden で拒否されました。想定どおり IP アドレスによるアクセス制限ができています。

コンソールからの設定

今回のアップデートにより、Lambda コンソールのアクセス権限タブに JSON エディタが追加されています。コンソールの 編集 ボタンから直接 JSON ポリシーを編集できるため、CLI を使わずに JSON ベースのポリシーを設定することも可能です。

image.png

注意点

  • ポリシーの最大サイズは 20 KB です
  • PutResourcePolicy API は既存のリソースベースポリシーを完全に上書きします。AddPermission API で追加したポリシーも上書きされるため、既存のポリシーを事前に GetResourcePolicy API で取得しておくことを推奨します
  • PutResourcePolicy API を実行するには lambda:PutResourcePolicy、lambda:AddPermission、lambda:RemovePermission の 3 つの IAM 権限が必要です

Required permissions
To use the PutResourcePolicy, GetResourcePolicy, and DeleteResourcePolicy API actions, you need the following IAM permissions:
PutResourcePolicy: lambda:PutResourcePolicy, lambda:AddPermission, and lambda:RemovePermission

  • 2025 年 10 月以降に作成した関数 URL では、呼び出しに lambda:InvokeFunctionUrl と lambda:InvokeFunction の両方の権限が必要になりました。Allow ステートメントでアクセスを許可する場合は両方のアクションを指定する必要があります。

Note
Starting in October 2025, new function URLs will require both lambda:InvokeFunctionUrl and lambda:InvokeFunction permissions.

まとめ

これまで Lambda 関数 URL のリソースベースポリシー単体では実現できなかった aws:SourceIp 条件キーによる IP アドレス制限が、PutResourcePolicy API を使うことで実際に設定できることを確認できました。

IP 制限に限らず、Deny ステートメントや複数 Principal の指定など、IAM ポリシーで表現できる制御を関数 URL のアクセス制御にそのまま持ち込めるようになりました。シンプルに IP アドレスでアクセスを絞りたいだけであれば、CloudFront や AWS WAF を用意しなくてもリソースベースポリシーだけで完結できるようになったのは選択肢が増えて嬉しいポイントかなと思います。

以上です。
参考になれば幸いです。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?