S3のアクセスコントロールリスト(ACL)の基礎を学ぼう

S3アクセス制御に古くから使われているアクセスコントロールリスト(ACL)の概念を説明します
2021.08.30

S3のアクセスコントロールリスト(ACL)とは

ACLを一言でいうと

「被付与者」に「バケット・オブジェクト」への「アクセス」を許可するもの

です。

「被付与者」や「アクセス」には色々な種類があります。 以降で説明していきます。

被付与者(Grantee)

被付与者(Grantee) は バケット・オブジェクトへアクセスするユーザー を指します。

img

被付与者の実態は 「AWSアカウント」もしくは「事前定義済み S3グループ」 です。

img

AWSアカウント(正規ユーザーID)

S3の ACLにおいては 正規ユーザーID を使ってAWSアカウントを表します。

正規ユーザー ID は、 AWS アカウント に関連付けられています。 この ID は、 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be のような長い文字列です。

– 引用: アクセスコントロールリスト (ACL) の概要 - Amazon Simple Storage Service

自身のAWSアカウントの正規ユーザーIDはマネジメントコンソールやCLIで調べることができます。

※ 小ネタですが、匿名ユーザー(AWSに認証されていないユーザー)に 対応する正規ユーザーIDもあります。 65a011a29cdf8ec533ec3d1ccaae921c です。

事前定義済みS3グループ

Amazon S3が事前に定義しているグループです。 3種類あります。

img

All Users グループ は、そのまま、 「世界中の誰でも」 を表します。

Authenticated Usersグループ「任意のAWSアカウント」 を表します。 Authenticated とは付いていますが、「世界中の誰でも」とさほど変わらないです。 注意しましょう。

Log Delivery グループS3サーバーアクセスログ を配信するグループを指します。 S3サーバアクセスログを設定する際には、 このグループへアクセス許可を与える必要があります。

アクセス許可

アクセス許可の種類は 5種類 あります。 それぞれ S3バケット、オブジェクトで意味が違ってきます。

img

ドキュメントの表を引用すると以下のとおりです。

アクセス許可 バケット上で付与された場合 オブジェクト上で付与された場合
READ 被付与者がバケット内のオブジェクトをリストすることを許可します。 被付与者がオブジェクトデータとそのメタデータを読み込むことを許可します
WRITE 被付与者がバケット内に新しいオブジェクトを作成できるようにします。既存のオブジェクトのバケット所有者およびオブジェクト所有者については、これらのオブジェクトの削除と上書きも許可します。 該当しません
READ_ACP 被付与者がバケット ACL を読み込むことを許可します 被付与者がオブジェクト ACL を読み込むことを許可します
WRITE_ACP 被付与者が該当するバケットの ACL を書き込むことを許可します 被付与者が該当するオブジェクトの ACL を書き込むことを許可します
FULL_CONTROL バケット上の READ、WRITE、READ_ACP、WRITE_ACP アクセス許可を被付与者に許可します オブジェクト上の READ、READ_ACP、WRITE_ACP アクセス許可を被付与者に許可します

– 引用: アクセスコントロールリスト (ACL) の概要 #付与できるアクセス許可 - Amazon Simple Storage Service

【改めて】S3のアクセスコントロールリスト(ACL)とは

改めて ACLを説明します。

冒頭で 『「被付与者」に「バケット・オブジェクト」への「アクセス」を許可するもの』 と言いましたが、もう少し正確に言うと以下のようになります。

  • ACLは「被付与者」と「アクセス許可」の組み合わせです
  • ACLはバケットもしくはオブジェクトにアタッチします

▼ イメージ

img

実際に見てみる(S3バケット)

S3バケットのマネジメントコンソールの [アクセス許可] からACL設定を見ることができます。

img

上の画像ではバケット所有者(自身のAWSアカウント)にのみアクセス許可が付いています。 デフォルト設定でバケットを作成した際はこのような形になります。

AWS CLIで詳細を見てみます。 aws s3api get-bucket-acl を実行してみます。

$ aws s3api get-bucket-acl --bucket ${bucketName} --output yaml
Grants:
- Grantee:
    DisplayName: xxxx
    ID: b488699999999example99999999999999999999999999999999999999999999
    Type: CanonicalUser
  Permission: FULL_CONTROL
Owner:
  DisplayName: xxxx
  ID: b488699999999example99999999999999999999999999999999999999999999

ハイライト部分が「被付与者情報」および「アクセス許可」を表しています。 b488... の正規ユーザーIDに紐づくAWSアカウントに対して、 FULL_CONTROL のアクセス許可を与えています。

実際に見てみる(S3オブジェクト)

S3オブジェクトのマネジメントコンソールの [アクセス許可] からACL設定を見ることができます。

img

上の画像ではオブジェクト所有者(自身のAWSアカウント)にのみアクセス許可が付いています。 同じくデフォルトでS3オブジェクトをアップロードすると、このような形になります。

AWS CLIで詳細を見てみます。 aws s3api get-object-acl を実行してみます。

$ aws s3api get-object-acl --bucket ${bucketName} --key test.txt --output yaml
Grants:
- Grantee:
    DisplayName: xxxx
    ID: b488699999999example99999999999999999999999999999999999999999999
    Type: CanonicalUser
  Permission: FULL_CONTROL
Owner:
  DisplayName: xxxx
  ID: b488699999999example99999999999999999999999999999999999999999999

ハイライト部分が「被付与者情報」および「アクセス許可」を表しています。 b488... の正規ユーザーIDに紐づくAWSアカウントに対して、 FULL_CONTROL のアクセス許可を与えています。 先程のバケットと同じですね。

既定ACL

既定ACLと呼ばれる 事前定義済みのACLセット をサポートしています。
AWS CLI等でリクエストする際に利用できます。

既定ACL 追加されるアクセス許可
private 所有者に FULL_CONTROL のみ(デフォルト)
public-read privateの許可 + 「AllUsers に READ」
public-read-write privateの許可 + 「AllUsers に READ/WRITE」
aws-exec-read privateの許可 + 「EC2に AMIバンドル(in S3)の READ」
authenticated-read privateの許可 + 「AuthenticatedUsers に READ」
(オブジェクトのみ) bucket-owner-read オブジェクト所有者に FULL_CONTROL + バケット所有者にREAD
(オブジェクトのみ) bucket-owner-full-control オブジェクト所有者/バケット所有者に FULL_CONTROL
(バケットのみ) log-delivery-write LogDelivery に WRITE および READ_ACP

まとめ

ACLの全体像を再掲します。

img

ACLの解説をしました。が、S3のアクセス制御は ACLは触らずに バケットポリシーを使うべき だと思います。

ACLは AWSアカウント単位でしか被付与者を設定できませんが、バケットポリシーでは IAMユーザーやロール、他柔軟な制御が可能です。 また、オブジェクト単位で ACLを管理するのは骨が折れます。やるべきではありません。

そして S3の パブリックアクセスブロック 機能はぜひ活用しましょう。 BlockPublicAcls を有効にすることで パブリックACLを含むリクエストが拒否されます。 IgnorePublicAcls を有効にすることで、バケット及びオブジェクトの パブリックACLを無視してくれます。 『意図せず Authenticated Users や All Usersに対してアクセス許可を与えしまう』 といった事故を未然に防ぐことができます。

参考