Google版 S3である Google Cloud Storage (gcs) ですが、もう随分前になるもののIAM対応となり、アクセス・ユーザー管理が非常に楽になりました。
ここでのIAMは勿論 GCPのIAMです。名前は同じですが、AWS の IAMとは、全く異なるものです。 今のところgcsのIAMはAWSに比べて機能面で大きく劣ります。

IAMと、今までのACL

元々GCPにはIAMは存在せず、GCSはそれ単体で独自のACLを持っていました。今回の変更でこのACLは レガシーACL と呼ばれるようになりました。レガシーと後述します。
対して今後はIAMによるGCSのアクセス制限・許可を使うようになります。
では、レガシーは今後どうなるのかですが、恐らく無くなることはないと思います。が、Developsers Console(ブラウザから)のレガシーACL設定は、もうできなくなりました。

IAMで出来るようになること

まず最初に、非常に語弊があるIAMという名称。先にAWS識者に言うことは S3に対するIAMと違って、リソース縛り(/pub/* は全員許可 /user1* は IAM user user1だけが通るとか、が一切できません。
制御出来るのは バケット単位のみです。 Prefix/Key単位では制御不能です。Denyのルールとかも書けません。

で、何が出来るようになったかと言うと バケット単位で IAM権限として付与した場合は、レガシーACLに頼らず(レガシーよりも強く)そのバケットの全てのオブジェクトに対して制御が可能です。

は?何いってんの?そんなの当たり前じゃねーか?

とAWS識者は即反応しそうですが、この当たり前が、ほんのすこし前まで当たり前ではなかった。この記事は主にそれを書きます。

レガシーACL

S3のバケットACLやオブジェクトACLと同じで、バケット・オブジェクト1個1個単位でACLを設定します。このACLには、プロジェクトメンバだけではなく、Web公開する場合は allUsers に対する権限も含まれます。
大変なのは1個1個に指定しなければならないことです。極端な話、静的サイトをホスティングする場合、全部で100ファイルから成る場合は、その100個1つ1つに allUsers の閲覧権限が必要です。

そんなのやってられないですよね!そこで Default ACL と言うものをバケット単位で指定します。

Default ACL ?

バケット単位で指定する、DefaultでオブジェクトにつけるACLです。

例をあげるともしも、Default ACLを指定していなかったら。 バケットのACLがあれば、ファイルのアップロードは可能です。つまり、XさんがAバケットに書き込み権限が付与されていると gs://a/hoge/fuga.txt など、好きな場所にファイル(オブジェクト)を upload可能です。 しかし、 gs://a/hoge/fuga.txt というファイル(オブジェクト)自体には ACLが何も付きません。勿論ACLの後付は可能です、が ACLが何も付いていないオブジェクトは、例え作成者であるXであっても`削除や移動や編集(上書きUpload)が一切できないオブジェクトになります。 対して、 Default ACL に AllUser に対して ReadOnly を指定していた場合。上記と同じ手順で、gs://a/hoge/fuga.txt がWeb公開された状態に自動でなります。

つまりは、オブジェクトをUploadする時に、ACLを何も指定しなかったら Default ACLの内容で、オブジェクトACLが付くということです。

バケット・オブジェクト ACLの問題点

一見問題なさそうに見える Default ACLですが、実に大きな問題を持っています。それは

バケットACLに新たにユーザーを追加した場合でも、既存オブジェクトのACLは変わらない、という点です。 つまりこういうことです。

  1. X さんが gs://hoge/a.txt を upload この時、 Default ACL は Xの編集権限のみ
  2. upload により a.txt に Xの編集権限が付く(仮に)
  3. Y さんがプロジェクトに参加、 gs://home にレガシーACLとしてユーザーを追加した Default ACL にも Yの編集権限を追加
  4. Y さんが gs://hoge/b.txt を upload これは問題ない
  5. Y さんが gs://hoge/a.txt を削除 or 上書き これができない、 だって a.txt は Yがいない時に生成されたので、 オブジェクトACLにXの編集権限しかないから

これに対する対処方は2つ

  1. 既存のオブジェクトのACLを全部変更する 具体的にはYの編集権限もオブジェクト全部につける
  2. そもそもユーザー個単位で権限を付与しない Google Group (G SuiteでなくてもOK)単位で許可をする

1) は根性です。全てのファイルのACL書き換えですので、それなりに時間もかかるリスキーな作業です。
2) はGroupという管理単位を1つかまして、ユーザー追加・削除の影響を最小限にする方法です。Google Gruop単位でACL設定した場合、もしもメンバを追加したいとなっても、GCS側はとくに変更無しで、Google Groupに該当するユーザーを追加 or 削除すればよいのです

Web公開とallUsers

GCSのオブジェクトをWeb公開する場合、AWSのような便利なバケットポリシーは存在せず、オブジェクトACL単位で管轄します。この、公開する時につかうユーザー(= 無認証ユーザーのアクセス)を allUsers という名前で指定します。回りくどく書きましたが、

Web公開したい なら allUsersでRead権限付ける しかもファイル一個一個に
だけどそんな面倒なことやってられないので、 Default ACL で allUsers足しとけ

となります。

レガシー or IAM

レガシーとIAMを比較して、じゃあこれからどうすればいいの?をまとめます

ユーザー・グループには IAMで権限付与

Object ACLの問題が発生しないため、レガシーを捨ててIAMにすることを強くおすすめします。 デメリットは私は思いつきません。

allUsers には レガシーで

ここは私の感覚をもろに出しているので、そうじゃないと思う人もいるかもしれません。

結論から言うと、 allUsers としてIAMで読み取り専用で権限付与は可能です。 が、1つ大きく問題があります。 詳しくは書きませんが、GCSはブラウザ上でバケット内のオブジェクトの一覧を確認できるGCPのツールがあります。AWSでいうマネージメントコンソールからのS3一覧画面のようなものですが、GCSはGCPの認証とは別にGCS単体での管理画面を持ちます。この画面が、何とallUsersとしてIAMでバケット許可していると、だれでも見えてしまいます。 つまりどう言うことかというと、所謂Apacheとかが自動生成する そのディレクトリに含まれるファイル一覧無認証で閲覧可能 になります。

結局Webで全部公開するなら、見れてもいいじゃないか?

という考えも有ると思いますが、「公開してはダメなものも意図せず置いちゃった。。」というのが二昔前の情報漏えいの基本だったと記憶しています。なので、私はIAMとして allUsers を読み込み専用とするのはかなり危険だと思います。このバケットには絶対に公開してOKのものしか置かない・置けないという仕掛けが無い限りは。

おまけ Default ACLの設定

今のDevelopers Console上から、 Default ACLを設定することはできません。gsutil のみとなります。 gsutil で Default ACLを設定する手順をざっくり書きます。

gsutil defacl get gs://[バケット名] > default.json

vim default.json 
# 編集する 下記を追記
  {
    "entity": "allUsers",
    "role": "READER"
  }

gsutil defacl set default.json gs://[バケット名]

まとめ

  • 今後はGCSのアクセス管理は基本IAMでいい
  • allUsers を IAMで ReadOnlyとするのは結構危険

Default ACLをブラウザ上から設定できないのは不便だなとおもう。

元記事はこちら

Google Cloud Storage (gcs) IAM対応でACL設定がより簡単に