SCP でパブリックな Lambda 関数 URL の設定を抑制してみた

先日のアップデートで追加された Lambda 関数 URL について、パブリックな設定を禁止するための SCP を試してみました
2022.04.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、大前です。

先日、Lambda 関数に HTTPS エンドポイントを追加できるようになるアップデートがありました。

Lambda の使いやすさが向上した一方で、適切に利用しないと Lambda をパブリックアクセス可能な状態にできてしまう機能でもあります。

公式ドキュメントに、SCP でパブリックな Lambda 関数 URL の設定を防ぐためのポリシー例が載っていますので、こちらを試して見たいと思います。

参考 : Lambda関数のURLのセキュリティと認証モデル-AWSLambda

やってみた

SCP の作成とアタッチ

上記の公式ドキュメントでは以下のポリシーが例示されているので、まずはこのポリシーを利用してみます。このポリシーは、Lambda 関数 URL を認証タイプ「AWS_IAM」以外で作成・更新する事を Deny します。認証タイプが何であれ Lambda 関数 URL を利用させたくない、という場合には "Condition" 句を削除してもらえれば OK です。

あくまで Lambda 関数 URL の設定・更新に関するポリシーであるため、既に認証タイプ「NONE」で作成されてしまった Lambda 関数 URL の利用を抑制するものではない 事にご注意ください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action":[
                "lambda:CreateFunctionUrlConfig",
                "lambda:UpdateFunctionUrlConfig"
            ],
            "Resource": "arn:aws:lambda:*:123456789012:function:*",
            "Condition": {
                "StringNotEquals": {
                    "lambda:FunctionUrlAuthType": "AWS_IAM"
                }
            }
        }
    ]
}


deny-public-lambda-httpendpoint という SCP を作成し、Root にアタッチしました。Root 配下の全アカウントに適用させたいので、"Resource" には arn:aws:lambda:*:*:function:* を指定しています。

Lambda 関数 URL が設定できない事を確認

Root に上記 SCP をアタッチしたら、適当な子アカウントにログインし、Lambda 関数を作成します。


「設定」から関数 URL の設定画面を開き、"認証タイプ" に NONE を指定して保存してみます。


エラーが出ました。意図した通りに SCP が機能しているようです。


"認証タイプ" を AWS_IAM にする事で、関数 URL は設定可能です。


"認証タイプ" が AWS_IAM で設定された Lambda 関数 URL の "認証タイプ" を NONE に変更しようとすると、こちらも問題なく弾かれることが確認できます。

特定の OU だけ例外にしたい場合

どうしてもパブリック Lambda 関数 URL の利用が必要になる場合があったり、検証用途で特定の OU 配下だけパブリックな Lambda 関数 URL の利用を許可したいケースもあるかもしれません。その場合、以下のような形で aws:PrincipalOrgPaths に関する Condition を追加し、パブリック Lambda 関数 URL の利用を許可したい OU を指定すれば OK です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action":[
                "lambda:CreateFunctionUrlConfig",
                "lambda:UpdateFunctionUrlConfig"
            ],
            "Resource": "arn:aws:lambda:*:*:function:*",
            "Condition": {
                "StringNotEquals": {
                    "lambda:FunctionUrlAuthType": "AWS_IAM"
                },
                "ForAnyValue:StringNotLike": {
                    "aws:PrincipalOrgPaths": [
                        "<組織ID>/<ルートID>/<OU ID>/*"
                    ]
                }
            }
        }
    ]
}


組織 ID などは Organizations のコンソール画面で確認できます。


例外として指定した OU ではパブリックな Lambda 関数 URL が設定できる一方で、その他のアカウントでは引き続きパブリックな Lambda 関数 URL の設定を禁止できていることが確認できます。

(おまけ) Lambda 関数の作成と同時に関数 URL を設定したらどうなるか

コンソールでは、Lambda 関数 URL は Lambda 関数自体の作成時に設定することもできるようです。SCP でパブリックな Lambda 関数 URLの設定が禁止されている状態で、Lambda 関数の作成と同時に Lambda 関数 URL の設定をやってみます。


Lambda 関数自体は作成されましたが、「Lambda 関数は作成されましたが、関数 URL の作成時にエラーが発生しました」 といった旨のエラーメッセージが表示されました。コンソールで Lambda 関数作成と同時にパブリックな関数 URL を設定しようとすると、関数 URL だけ設定に失敗するような動きになるようですね。


おわりに

パブリックな Lambda 関数 URL を抑制するための SCP を試してみました。便利な機能である一方で、意図せずパブリックに Lambda を公開してしまう可能性も孕んでいるため、SCP などで制限をかけられると安心かと思います。

以上、AWS 事業本部の大前でした。

参考