概要

S3バケットポリシーで、あるLamdba関数からのアクセスを拒否しようとした際に詰まったところをメモ。

設定したいこと

Lambda関数 function-a からの、S3バケット bucket-aへのReadアクションを拒否する。

ケースとしてあまりないと思うが、今回は、S3へのアクセスが何らかの理由で失敗したという想定をテストしたいためにこの方法を取ることとした。

間違ったバケットポリシーの設定

Lambda関数からのアクセスを拒否するということで、以下のように、Conditionに該当のLambda関数をSourceArnとして設定した Deny ルールを書けばいいと考えた。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": *,
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::bucket-a",
            "Condition": {
                "ArnLike": {
                    "AWS:SourceArn": "arn:aws:lambda:ap-northeast-1:111111111111:function:function-a"
                }
            }
        },
        {
            "Effect": "Deny",
            "Principal": *,
            "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl"
            ],
            "Resource": "arn:aws:s3:::bucket-a/*",
            "Condition": {
                "ArnLike": {
                    "AWS:SourceArn": "arn:aws:lambda:ap-northeast-1:111111111111:function:function-a"
                }
            }
        }
    ]
}

しかし、これでは動作しない。

正しいバケットポリシーの設定

以下を読んで理解。

Lambda 実行ロールに Amazon S3 バケットへのアクセスを許可するにはどうすればよいですか?

Lambda関数からS3などの他リソースへのアクセスは、Lambda関数から直接ではなく、アタッチされている「IAMロール」を通して行われる。

よって、S3バケットポリシーには、そのIAMロールからのアクセスを拒否するようにルールを書かなければならない。

IAMロール名を role-aとすると、以下のように記載する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/role-a"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::bucket-a",
        },
        {
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/role-a"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl"
            ],
            "Resource": "arn:aws:s3:::bucket-a/*",
        }
    ]
}

Principalに該当のIAMロールを入れて、Denyルールを記載する。

これで、やりたかったことが実現できた。

まとめ

Lambdaに限らずEC2やECSなど他のコンピューティングリソースについても、同様のことを気をつける必要がある。

試行錯誤している時はわからないけど、言われてみれば確かになと理解できる。

元記事はこちら

特定のLambdaからのアクションをS3バケットポリシーで拒否したい時