S3バケットのバケットポリシーで設定すべき項目

# はじめに
S3のバケットポリシーについて、一般的に設定しておくべきことを記載していきます。

# 概要
基本的に以下を必要に応じて設定しておくべきです。

| # | バケットポリシー概要 | 利用ケース |
| --- | --- | --- |
| 1 | HTTPS通信以外の拒否 | 基本的に入れておいてよい。HTTP通信を利用するケースは少ないが、明示的に指定しておくことで非暗号化通信の場合リクエストを拒否できる。 |
| 2 | 暗号化を指定しない場合のオブジェクトのアップロードの拒否 | 基本的に入れておいてよいが、KMSかSSE-S3かなどアップロード元の対応状況に依存するため注意。|
| ３ | 暗号化を指定しない場合のオブジェクトのアップロードの拒否 | 基本的に入れておいてよいが、KMSかSSE-S3かなどアップロード元の対応状況に依存するため注意。 |
| ４ | 特定のVPCエンドポイント以外からの通信拒否 | VPCからの通信のみであれば入れておくことを推奨 |
| ５ | 各種AWSサービスが要求するポリシー | 忘れがちだが、各種AWSサービスからのログ出力等でポリシーが必要となる。各種ガイドを確認の上設定すること。 |
| ６ | クロスアカウントアクセスの許可ポリシー | クロスアカウントアクセスの場合は、必須となる。 |

# HTTPS通信以外の拒否
基本的にS3への通信は暗号化されますが、HTTPでの通信も可能ではあります。そのため、HTTPS通信以外を拒否することで、通信の暗号化を必須とすることができます。

```
{
  "Id": "HTTPS Only",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "HTTPS only",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::＜バケット名＞",
        "arn:aws:s3:::＜バケット名＞/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      },
      "Principal": "*"
    }
  ]
}
```

https://dev.classmethod.jp/articles/s3-request-https-only/

# 暗号化を指定しない場合の通信拒否
オブジェクトの暗号化を必須とするポリシーです。このポリシーにより、暗号化しないオブジェクトのアップロードを拒否できます。以下にSSE-S3方式と、SSE−KMSの場合のバケットポリシーを記載します。

## SSE-S3以外拒否
```
{
  "Version": "2012-10-17",
  "Id": "Encrypted Only",
  "Statement": [
    {
      "Sid": "Encrypted Only",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::＜バケット名＞/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    }
  ]
}
```
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingServerSideEncryption.html

## SSE-KMS以外拒否
```
{
  "Version": "2012-10-17",
  "Id": "Encrypted Only",
  "Statement": [
    {
      "Sid": "Encrypted Only",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::＜バケット名＞/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption-aws-kms-key-id": "<KMSキーのARN>"
        }
      }
    }
  ]
}
```

# 特定のVPCエンドポイント以外からの通信拒否
VPCからの通信のみの場合はこのポリシーを入れておきましよう。

```
{
   "Version": "2012-10-17",
   "Id": "VPCE only",
   "Statement": [
     {
       "Sid": "Access-to-specific-VPCE-only",
       "Principal": "*",
       "Action": "s3:*",
       "Effect": "Deny",
       "Resource": ["arn:aws:s3:::＜バケット名＞",
                    "arn:aws:s3:::＜バケット名＞/*"],
       "Condition": {
         "StringNotEquals": {
           "aws:SourceVpce": "＜VPCエンドポイントID＞"
         }
       }
     }
   ]
}
```

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/example-bucket-policies-vpc-endpoint.html

# 各種AWSサービスが要求するポリシー
忘れがちですが、AWSのログ等各種サービスからのアップロードはAWSが指定するバケットポリシーを指定することが必要です。ガイドをみて適切に設定しましょう

https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html


# クロスアカウントアクセスのバケットポリシー
該当のバケットにクロスアカウントでのアクセスを行いたい場合、IAMポリシーだけでなく、バケットポリシーが必須となります。

```
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "CrossAccount",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::＜アクセス元のアカウントID＞:root"
         },
         "Action": [
            "s3:＜必要な操作＞"
         ],
         "Resource": [
            "arn:aws:s3:::＜バケット名＞"
         ]
      }
   ]
}
```

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example2.html

# まとめ
バケットポリシーは、適切に設定することで、不適切なアクセスを予防することができます。
また、そもそもせってしない場合利用できないケースもありますので、上記を参考に適切なポリシーを設定しましょう。