[アップデート]S3アクセスポイントがクロスアカウントで作成できるようになりました #reinvent

別のアカウントにある S3 バケットに対してアクセスポイント(クロスアカウントアクセスポイント)を作成出来るようになりました
2022.12.01

お疲れさまです。とーちです。

別のアカウントにある S3 バケットに対してアクセスポイント(クロスアカウントアクセスポイント)を作成出来るようになりました。

この記事ではこのアップデートの内容についてお伝えします。

そもそも S3 アクセスポイントとは?というところについては、弊社の以下ブログで分かりやすくまとめられておりますのでこちらをご参照ください。

とりあえずまとめ

  • 別アカウントの S3 バケットに対してクロスアカウントアクセスポイントを作れるようになった
  • 2022/12 現時点では AWS CLI からのみ設定が可能

アップデートの概要

絵で示したほうが分かりやすいかと思いますので、とりあえず絵を描いてみました。

クロスアカウントアクセスポイントを作成するには、対象となる別アカウントの S3 バケット名とその S3 バケットが存在するアカウント ID が必要になります。

また、S3 バケットのバケットポリシーにて別アカウントのアクセスポイントからのアクセスを許可してあげる必要があります。

クロスアカウントアクセスポイントを使用する際のバケットポリシーの記載方法は S3 ユーザーガイドの以下のページが参考になりますので、ご参照ください。

Configuring IAM policies for using access points - Amazon Simple Storage Service

試してみた

それではさっそく クロスアカウントアクセスポイント を試してみようと思います。
前提となる環境は以下の通りです。

  • S3 バケットが存在するアカウント ID:111111111111
  • S3 バケット名:test-2022-12-01-11-30-02
  • アクセスポイントを作成するアカウント ID:222222222222

上記の環境でアカウント ID「222222222222」の IAM ユーザ「Jane」 でアクセスポイント経由で S3 にアクセスしてみようと思います S3 バケットは以下のような設定で作成しました。

  • ブロックパブリックアクセス設定:パブリックアクセスをすべてブロック
  • デフォルト暗号化:SSE-S3 で有効
  • オブジェクト所有者:ACL 無効

S3 のバケットポリシーは S 3ユーザーガイドを参考に以下の設定をしています。このポリシーはアカウント ID「222222222222」にアクセスポイント経由での GetObject と ListBucket を許可するという設定になります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test-2022-12-01-11-30-02",
                "arn:aws:s3:::test-2022-12-01-11-30-02/*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:DataAccessPointAccount": "222222222222"
                }
            }
        }
    ]
}

クロスアカウントアクセスポイントの作成

クロスアカウントアクセスポイントは 2022/12 現時点では AWS CLI からのみ作成可能となっています。
クロスアカウントアクセスポイントは S3 バケットが存在する AWS アカウントとは別のアカウントに作成します。今回でいうとアカウント ID「222222222222」に作成することになりますので、AWS CLI はアカウント ID「222222222222」の権限を持ったもので実行しましょう。

以下のコマンドで作成していきます。なお、AWS CLI は 2022/12/1 時点の最新バージョンである 2.9.3 にする必要があります。

# AWS CLIバージョン確認
> aws --version
aws-cli/2.9.3 Python/3.9.11 Darwin/22.1.0 exe/x86_64 prompt/off

# クロスアカウントアクセスポイントの作成
# アカウント ID「222222222222」の権限をもつプロファイルで実行
> aws s3control create-access-point --name example-ap --account-id 222222222222 --bucket test-2022-12-01-11-30-02 --bucket-account-id 111111111111 --profile acct-222222222222
{
    "AccessPointArn": "arn:aws:s3:ap-northeast-1:222222222222:accesspoint/example-ap",
    "Alias": "example-ap-**********************-s3alias"
}

# 作成したアクセスポイントの確認
# こちらも同じくアカウント ID「222222222222」のプロファイルで実行
> aws s3control list-access-points --account-id 222222222222 --profile acct-222222222222
{
    "AccessPointList": [
        {
            "Name": "example-ap",
            "NetworkOrigin": "Internet",
            "Bucket": "test-2022-12-01-11-30-02",
            "AccessPointArn": "arn:aws:s3:ap-northeast-1:222222222222:accesspoint/example-ap",
            "Alias": "example-ap-**********************-s3alias",
            "BucketAccountId": "111111111111"
        }
    ]
}

続いて、アクセスポイントポリシーを設定していきます。アクセスポイントポリシーの編集は AWS マネージメントコンソールからでも出来るのでこちらで行っていきます。
S3 コンソール画面左のナビゲーションペインから「アクセスポイント」を選ぶと、先程 AWS CLI で作成したアクセスポイント名が表示されるのでそれを選択します。

アクセスポイントの詳細画面で、「アクセス許可」のタブを選択しアクセスポイントポリシーを編集します。

今回は以下のようなポリシーにしてみました。バケットポリシーでは S3 バケット内の全てのオブジェクトに Get 出来るようにしましたが、アクセスポイントポリシーで IAM ユーザ「Jane」 の場合は、指定したディレクトリ内のみ Get 出来るよう制限します。
なお、このポリシーでは IAM ユーザ「Jane」 に対しての制限しかかけていないので、アカウント ID「222222222222」内のその他の IAM ユーザーや IAM ロールがこのアクセスポイントに対して権限を持っていれば、S3 バケット内の全てのオブジェクトを Get できるので注意です。
個人的にアクセスポイントポリシーを使った場合の許可・拒否については複雑で難しいと思うので、ポリシーの評価論理なども参考にしつつ、実際に設定してアクセス確認をするのがいいと思います。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:user/Jane"
            },
            "Action": "s3:GetObject",
            "NotResource": "arn:aws:s3:ap-northeast-1:222222222222:accesspoint/example-ap/object/Jane/*"
        }
    ]
}

クロスアカウントアクセスポイント経由でのアクセス

設定が出来たので、実際にアクセスしてみます。AWS CLI からアクセスしてみました。

# Bobディレクトリへのアクセス
# アカウント ID「222222222222」の IAM ユーザ「Jane」のプロファイルで実行
> aws s3api get-object --bucket arn:aws:s3:ap-northeast-1:222222222222:accesspoint/example-ap --key Bob/s3crossaccountAccess.jpeg  s3crossaccountAccess.jpeg --profile Jane

An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

# Janeディレクトリへのアクセス
# こちらも同じく IAM ユーザ「Jane」のプロファイルで実行
> aws s3api get-object --bucket arn:aws:s3:ap-northeast-1:222222222222:accesspoint/example-ap --key Jane/s3crossaccountAccess.jpeg  s3crossaccountAccess.jpeg --profile Jane
{
    "AcceptRanges": "bytes",
    "LastModified": "2022-12-01T05:54:22+00:00",
    "ContentLength": 30463,
    "ETag": "\"***********************\"",
    "ContentType": "image/jpeg",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}

上記の通り、別アカウントの S3 アクセスポイントからアクセスしファイルを取得することに成功しました。またアクセスポイントポリシーにより指定したディレクトリ以外へのアクセスが拒否されています。

使いどころ

例えば組織毎にアカウントが分かれていて、特定の S3 バケットに別の組織(アカウント)からアクセスさせたい場合、今までは必ず同一アカウント上にアクセスポイントを作る必要があったので、アクセスポイントポリシーの管理を S3 バケットの所有アカウントで行う必要がありました。
このアップデートにより、バケットポリシーは S3 バケットの所有者が管理、アクセスポイントポリシーは別の組織が管理といった形で権限の管理を分割することが出来るようになったので、そういったケースで有効に使えるのではと思います。

さいごに

S3 クロスアカウントアクセスポイントに関するアップデートの紹介でした。 このアップデートによりクロスアカウントでアクセスポイントを使う場合の権限管理がしやすくなったのではないかと思います。

以上、とーちでした。

参考

Creating an access point - Amazon Simple Storage Service
Amazon S3 Access Points can now be used to securely delegate access permissions for shared datasets to other AWS accounts
S3 アクセスポイントのうれしい点を自分なりの理解で解説してみる #reinvent | DevelopersIO
ポリシーの評価論理 - AWS Identity and Access Management