Techfirm Cloud Architect Blog

テックファーム株式会社クラウドインフラグループのブログ

S3上の機密情報ファイルへタグベース制御を行う

はじめに

各種リソースへのアクセスを個別に制御する場合、IAMポリシーでAction、またResource要素を個別に設定すると思います。
ですがAWSには、より厳密かつ柔軟にアクセスを制御するABAC(タグベースのアクセス制御)といった手法があります。
今回は、S3上のファイルに対してタグベースでアクセスを制御する例をご紹介します。

1.ロール毎にファイルへのアクセスを制御する

1つ目の例では、ロール毎にS3上のファイルへのアクセスを制御してみます。
今回の例では、開発者、運用者といったロールへスイッチロールする環境とし、開発者だけがS3上の特定ファイルへアクセスできるものとします。

1.1.制御のイメージ

今回の例は以下のような制御イメージです。

1.1.制御のイメージ

1.2.設定するIAMポリシー

1.1.制御のイメージの制御を行うには、以下のようなIAMポリシーを開発者用のIAMロールに設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:ListBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Deny",
            "Action": [
                "s3:DeleteObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:ExistingObjectTag/Role": ["developer"]
                }
            }
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:RequestObjectTag/Role": ["developer"]
                }
            }
        }
    ]
}

この実装ポイントは、"s3:ExistingObjectTag/Role": ["developer"]で開発者は、Roleタグにdeveloperという値が設定されたファイルを参照できるようにしています。

上記IAMポリシーは、以下のような予防的ガードレールを設けています。

  • DeleteObjectTaggingでユーザーにタグ削除を禁止します
  • "s3:RequestObjectTag/Role": ["developer"]で、Roleタグとdeveloperという値が設定されていないとアップロードできないようにします

1.3.補足

また、上記は開発者向けの設定を想定して記載しましたが、

  • 運用者の場合は、それぞれの値をoperatorに変えて運用者のみ参照できる
  • 管理者の場合は、Condition要素を設定しないで全てのファイルを参照できる

のような、ロール毎に制御するといった場面も考えられます。

2.オブジェクト所有者のみ参照を許可する

2つ目の例では、オブジェクトの所有者のみがS3上のファイルへアクセスできるように制御してみます。
今回の例では、特定のロールへスイッチロールする環境とし、S3上のファイル所有者だけがそのファイルへアクセスできるものとします。

2.1.制御のイメージ

今回の例は以下のような制御イメージです。

2.1.制御のイメージ

2.2.設定するIAMポリシー

2.1.制御のイメージの制御を行うには、以下のようなIAMポリシーをIAMロールに設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:ListBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Deny",
            "Action": [
                "s3:DeleteObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:ExistingObjectTag/Owner": "${aws:username}"
                }
            }
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "s3:RequestObjectTagKeys": ["Owner"]
                }
            }
        }
    ]
}

この実装ポイントは、"s3:ExistingObjectTag/Owner": "${aws:username}"でOwnerタグに自身の名前が設定されているファイルのみ参照できるようにしています。

また、上記IAMポリシーは、以下のような予防的ガードレールを設けています。

  • DeleteObjectTaggingでユーザーにタグ削除を禁止します
  • "s3:RequestObjectTagKeys": ["Owner"]を記載して、Ownerタグが設定されていないとアップロードできないようにします

2.3.補足

また今回のIAMポリシーは、要件に応じて以下のように変更することも可能です。

  • 複数タグキーの内、どれか1つ設定する場合は、以下のように設定できます
    • 全てのタグキーを強制するならForAllValuesを設定します
        ~省略~
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectTagging"
            ],
            "Resource": "arn:aws:s3:::sample-bucket/*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "s3:RequestObjectTagKeys": [
                        "Owner"
                        "Role"
                    ]
                }
        ~省略~
  • 今回の例では、ファイルアップロード時にアップロードした人以外の名前をOwnerタグに設定できてしまいます。登録できるユーザー情報を自分のみに制限する場合は、以下のように設定できます
        ~省略~
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectTagging"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:RequestObjectTag/Owner": "${aws:username}"
                }
            }
        ~省略~

おわりに

今回は、S3上のファイルへタグベースでアクセスを制御(ABAC)する例をご紹介しました。
ABACの実装には、タグ設定のルールや、IAMポリシーの設計等、検討する項目が多いですが、実装できるとセキュリティの向上や、作業ミスの防止などの効果が見込めると思います。
要件に応じて適切に制御していきたいですね。

また今回は省きましたが、発見的ガードレールとしてAWS Configを使い、指定のタグが設定されていないS3ファイルを検知するのも良いと思います。

参考

1.複数のキーまたは値による条件の作成 https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_multi-value-conditions.html

2.タグ付けとアクセスコントロールポリシー https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/tagging-and-policies.html