[アップデート] Amazon S3 でバケットの所属アカウントに応じた制御が行える IAM 条件キーが追加されました!

AWS アカウント単位での S3 アクションのコントロールを、 IAM ポリシーと VPC エンドポイントポリシーの条件キーで実現できるようになりました。

コンバンハ、千葉(幸)です。

Amazon S3 で使用できる新たな IAM 条件キーs3:ResourceAccountが追加されました!

特定のアカウントが持つ S3 に対してのみアクションが実行できる、そんな制御を行いやすくなりました。

もう一つ IAM 条件キー増えてませんか?

冒頭のブログでは、s3:TLSVersionについても記載があります。これはクライアントが S3 へのアクセスに使用する TLS の最小バージョンを制御できるものです。

なのですが……現時点で使い方が分からず。

s3:TLSVersionについては以下 S3 のドキュメントに記載があります。

記載はあるのですが、その条件キーを使用できるアクションやリソースが見当たりません。

IAM の Service Authorization Reference では記載自体が見つかりません。

IAM のポリシージェネレーターでも確認ができませんでした。

すべての S3 アクション、リソースを選択した状態で条件の設定を押下し……

条件の追加から使用可能な「サービスレベルの条件キー」を確認しましたが、s3:TLSVersionは見当たらず。

IAM_Management_Console-8814716

s3:TLSVersion以外の条件キーはすべて選択肢に出てきたので、現時点では使用できないのかな?と推測しました。

もしかしたら他の方法で確認・使用ができるかもしれませんが、本エントリでは言及の対象外とします。(ご存知の方がいたら教えてください。)

改めて s3:ResourceAccount とは

s3:ResourceAccountは IAM ポリシーもしくは VPC エンドポイントポリシーで使用できる条件キーです。

conditionkey

いずれかに設定することで、「対象 S3 バケットが所属するアカウント番号による制御」が実現できるようになります。

おさらいとなりますが S3 バケットの ARN は以下のような形式となっており、アカウント番号を含みません。

arn:aws:s3:::バケット名

よって、これまでは「このバケットには〇〇できる」「このバケットへの××は禁止する」といった個別の制御だけが可能でした。アカウントという切り口では制御できなかったわけです。

S3 API 実行時のオプションとしてアカウント番号を指定できる仕組みはありましたが、 IAM ポリシーや VPC エンドポイントポリシーとしての制御はできませんでした。

今回のアップデートにより、個々のバケットレベルでの制御でなくアカウント単位でのコントロールができるようになります。

「このアカウントのバケットにはアクセス禁止」「このアカウントにだけ許可」という制御ができますし、許可アカウントにバケットが増えても実行側のポリシーを変更する必要がない、という嬉しみ溢れる運用も可能になりました。

conditionkeys3

もちろんクロスアカウントの場合には S3 バケットポリシーで IAM ユーザーやロールがプリンシパルとして許可されている必要があります。 そこは変わりありません。

やってみた

今回は以下のような構成で条件キーの挙動を試してみます。

conditionkeys4

  • 実行元は 000000000000、実行先は999999999999
  • 実行ユーザー chiba-cli には以下のポリシーを設定
    • AdministratorAccess
    • 特定の条件で Deny するポリシー
  • 実行先 S3 バケット s3-dest-chiba では実行元アカウントを許可
  • 確認のため同一アカウントに S3 バケット chiba-no-bucket-policy あり

このケースでは、クロスアカウントでの実行に関して「他のポリシー設定でアクションが許可されつつも Deny ポリシーにより拒否される」という挙動を期待しています。

対向アカウントの S3 バケットには以下バケットポリシーを設定しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::000000000000:root"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::s3-dest-chiba",
                "arn:aws:s3:::s3-dest-chiba/*"
            ]
        }
    ]
}

同一アカウントの S3 バケットには何もポリシーを設定していません。

拒否ポリシーなしでの実行

先に成功するパターンを試しておきます。 Deny ポリシーを外し、AdministratorAccess だけが設定された状態の chiba-cli ユーザーでアクションを行います。

クロスアカウントでの実行は問題なく成功します。

% aws s3 cp test.txt s3://s3-dest-chiba
upload: ./test.txt to s3://s3-dest-chiba/test.txt

同一アカウントの実行ももちろん成功します。

% aws s3 cp test.txt s3://chiba-no-bucket-policy
upload: ./test.txt to s3://chiba-no-bucket-policy/test.txt

拒否ポリシーを設定しての実行

chiba-cli ユーザーに以下のポリシーを追加でアタッチします。

Deny-External-S3Bucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "s3:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        }
    ]
}

グローバル条件キーaws:PrincipalAccountを使用し、実行先の S3 バケットが自身と同一アカウントでなければ拒否、というポリシーとしています。

IAM_Management_Console-8819248

クロスアカウントでの PutObject は拒否されました。 Deny ポリシーが期待通りに機能しています。

% aws s3 cp test.txt s3://s3-dest-chiba
upload failed: ./test.txt to s3://s3-dest-chiba/test.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

同一アカウントでの PutObject は引き続き成功します。条件キーが意図せず Deny しているということも無さそうです。

% aws s3 cp test.txt s3://chiba-no-bucket-policy
upload: ./test.txt to s3://chiba-no-bucket-policy/test.txt

条件キーを使用した制御が確認できました!

終わりに

新しく増えた S3 の IAM条件キーs3:ResourceAccountの確認でした。

将来的に対向アカウントで S3 バケットが増える見込み、といった環境において、「ひとまずアカウントレベルで実行可能な権限を与えておく」という方式が取れるのは嬉しいですね。

S3 バケットが増える度に IAM ポリシーと VPC エンドポイントポリシーの Resource 部を一行ずつ追加していたかつての私に教えてあげたいです。(もちろんセキュリティ的にそれが望まれる環境もあります。)

s3:TLSVersionについては……追加の情報を待ちたいと思います。

以上、千葉(幸)がお送りしました。