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は変わらない
、という点です。 つまりこういうことです。
- X さんが gs://hoge/a.txt を upload この時、 Default ACL は Xの編集権限のみ
- upload により a.txt に Xの編集権限が付く(仮に)
- Y さんがプロジェクトに参加、 gs://home にレガシーACLとしてユーザーを追加した Default ACL にも Yの編集権限を追加
- Y さんが gs://hoge/b.txt を upload これは問題ない
- Y さんが gs://hoge/a.txt を削除 or 上書き これができない、 だって a.txt は Yがいない時に生成されたので、 オブジェクトACLにXの編集権限しかないから
これに対する対処方は2つ
- 既存のオブジェクトのACLを全部変更する 具体的にはYの編集権限もオブジェクト全部につける
- そもそもユーザー個単位で権限を付与しない 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をブラウザ上から設定できないのは不便だなとおもう。