本日も乙

ただの自己満足な備忘録。

Cloud Storage(GCS)のバケットロックによるファイル保持で変更・削除から守る

昨年のアップデートになりますが、Cloud Storage(GCS) の Bucket Lock 機能がGAとしてリリースされました。

cloud.google.com

Bucket Lock 機能によって、特定のGCSバケットに格納されたファイル(オブジェクト)は指定した期間は変更および削除ができなくなります。ユースケースとしては、セキュリティコンプライアンスとして完全性が必要とされる(改ざんや削除が許されない)ログや重要ファイルの保管が挙げられます。

目次

保持ポリシー

GCSバケットに保持ポリシーを設定することで、 Bucket Lock が有効になります。保持ポリシーはGCSバケットの新規作成もしくは既存バケットに追加で設定することが可能です。バケットにオブジェクトを格納すると、保持ポリシーによって設定したオブジェクトを保護する期間(保持期間)はオブジェクトの上書きおよび削除ができなくなります。オブジェクトの保存時間が保持期間を経過したら上書きや削除ができるようになります。ただし、上書きした場合はオブジェクトの作成日も上書きされてリセットされるため、再度保持期間を経過するまで上書きや削除ができなくなります。

GCSにはオブジェクトのバージョン管理がサポートされていますが、保持ポリシーとの両方を有効化することができません。

また、オブジェクトのライフサイクル機能によって、オブジェクトの自動削除が設定されていた場合、保持ポリシーによる保持期間の方が優先され、保持期間が経過するまで削除されず残ります。

保持ポリシーはロックすることができます。ロックすることで、第三者 *1 によって保持ポリシーの削除や保持期間の短縮を防ぐことができます。 ただし、一度ロックしてしまうと解除することができませんので注意が必要です。また、保持期間は延長することができますが、短縮ができません。ロックしてしまうと、バケット内のファイルすべてが保持期間を経過しないとバケットの削除ができません。ロックする際は本当にロックして良いのか慎重に検討しましょう。

オブジェクトの保持

bucket Lock 機能と併用してオブジェクトにも保持機能(Hold; 保留)があります。オブジェクトに対して保留機能が有効になっている間は上書きや削除はできません。

オブジェクトの保留方法には以下の2つがあります。

  • イベントベースの保留 (Event-based)
  • 一時的な保留 (Temporary)

両者の違いについて、以下の図を使って説明します。

gcs-object-hold

あるGCSバケットに対して、1年間の保持期間とした保持ポリシーを設定したとします。オブジェクトA、オブジェクトBを同じタイミングで格納し、オブジェクトAにはイベントベースの保留、オブジェクトBには一時的な保留を設定したとします。

オブジェクトA、Bともに保持期間(1年間)を経過したとしても保留が解除されるまで削除することができません。保持期間経過後に保留解除した場合、一時的な保留の場合はすぐに削除が可能です。一方、イベントベースの保留の場合は、さらに保持期間(1年間)を経過した後にやっと削除可能になります。

それぞれのユースケースとして、ドキュメントから引用します。

Event-based holds can be used in conjunction with a retention policy to control retention based on the occurrence of some event, such as holding loan documents for a certain period after loan was paid. Temporary holds can be used for regulatory or legal investigation purposes, such as holding trading documents for legal investigation.

(翻訳) イベントベースの保留を保存方針と組み合わせて使用​​して、ローンが支払われた後の一定期間ローン文書を保留するなど、何らかのイベントの発生に基づいて保留を制御できます。一時保留は、法的調査のための取引文書の保管など、規制上または法的調査の目的で使用できます。

https://cloud.google.com/storage/docs/bucket-lock#object-holds

一時的な保留は、Bucket Lock 機能に関係なく一時的にファイルを変更・削除されたくない場合に設定するのが有用です。イベントベースの保留は、上記ではローン文書が挙げられていますが、特定のイベントが発生しある程度の期間までオブジェクトを残しておく必要がある場合に有用です。

デフォルトでのイベントベースの保留

個々のオブジェクトに保留を設定できますが、バケットレベルでデフォルトでイベントベースの保留を設定することが可能です。設定を有効化すると、新規オブジェクトに対して、イベントベースの保留が自動的に設定されます。

検証

実際にBucket Lock機能とオブジェクトの保留を試してみました。
検証用として、 test-bucket-lock-hogehoge というバケットを作成し、保持期間を1日に設定しました。

Bucket Lock

bucket-lock

適当なファイルを作成し、GCSバケットに配置します。

$ cat locktest.txt
file locked!!

$ gsutil cp locktest.txt gs://test-bucket-lock-hogehoge
Copying file://locktest.txt [Content-Type=text/plain]...
- [1 files][   14.0 B/   14.0 B]
Operation completed over 1 objects/14.0 B.

削除しようとすると、403エラーが返ってきて削除できないことが確認できました。

$ gsutil rm gs://test-bucket-lock-hogehoge/locktest.txt
Removing gs://test-bucket-lock-hogehoge/locktest.txt...
AccessDeniedException: 403 Object 'test-bucket-lock-hogehoge/locktest.txt' is subject to bucket's retention policy and cannot be deleted, overwritten or archived until 2019-01-05T01:40:31.631959852-08:00

ファイル変更も同様にできません。

# ファイルを編集
$ cat locktest.txt
file locked!!
change!!

$ gsutil cp locktest.txt gs://test-bucket-lock-hogehoge
Copying file://locktest.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Object 'test-bucket-lock-hogehoge/locktest.txt' is subject to bucket's retention policy and cannot be deleted, overwritten or archived until 2019-01-05T01:40:31.631959852-08:00

保持期限を経過していれば削除できます。

# 保持期限(2019/01/05) を過ぎている
$ date "+%Y-%m-%d %H:%M:%S"
2019-01-06 00:20:44

$ gsutil rm gs://test-bucket-lock-hogehoge/locktest.txt
Removing gs://test-bucket-lock-hogehoge/locktest.txt...
/ [1 objects]
Operation completed over 1 objects.

オブジェクトの保持

次にオブジェクトの保留の検証です。先ほどと同様に適当なファイルを2つ作成し、それぞれにイベントベースの保留と一時的な保留を設定します。

$ cat event-based-hold-test.txt
holdtest!!
$ cat temporary-hold-test.txt
holdtest!!

$ gsutil cp event-based-hold-test.txt gs://test-bucket-lock-hogehoge
$ gsutil cp temporary-hold-test.txt gs://test-bucket-lock-hogehoge

# イベントベースの保留を設定
$ gsutil retention event set gs://test-bucket-lock-hogehoge/event-based-hold-test.txt

# 一時的な保留を設定
$ gsutil retention temp set gs://test-bucket-lock-hogehoge/temporary-hold-test.txt

# 保留設定を確認
$ gsutil ls -L gs://test-bucket-lock-hogehoge/event-based-hold-test.txt
...(省略)
    Event-Based Hold:       Enabled
...(省略)

$ gsutil ls -L gs://test-bucket-lock-hogehoge/temporary-hold-test.txt
...(省略)
    Temporary Hold:         Enabled
    Retention Expiration:   Sun, 06 Jan 2019 15:15:27 GMT
...(省略)

マネジメントコンソールから見るとこのようになっています。

object-hold

Bucket Lock機能と同様にファイルを削除しようとしても403エラーが返ってくるのが確認できます。

$ gsutil rm gs://test-bucket-lock-hogehoge/event-based-hold-test.txt
Removing gs://test-bucket-lock-hogehoge/event-based-hold-test.txt...
AccessDeniedException: 403 Object 'test-bucket-lock-hogehoge/event-based-hold-test.txt' is under active Event-Based hold and cannot be deleted, overwritten or archived until hold is removed.

$ gsutil rm gs://test-bucket-lock-hogehoge/temporary-hold-test.txt
Removing gs://test-bucket-lock-hogehoge/temporary-hold-test.txt...
AccessDeniedException: 403 Object 'test-bucket-lock-hogehoge/temporary-hold-test.txt' is under active Temporary hold and cannot be deleted, overwritten or archived until hold is removed.

保留を解除します。解除後の保持期限がそれぞれ異なっている点に注目してください。 イベントベースの保留は解除された後に保持期限が設定されるため、一時的な保留よりも期限が後になっています。

$ gsutil retention event release gs://test-bucket-lock-hogehoge/event-based-hold-test.txt
$ gsutil retention temp release gs://test-bucket-lock-hogehoge/temporary-hold-test.txt

$ gsutil ls -L gs://test-bucket-lock-hogehoge/event-based-hold-test.txt | grep "Retention Expiration"
    Retention Expiration:   Sun, 06 Jan 2019 15:30:23 GMT

$ gsutil ls -L gs://test-bucket-lock-hogehoge/temporary-hold-test.txt | grep "Retention Expiration"
    Retention Expiration:   Sun, 06 Jan 2019 15:15:27 GMT

マネジメントコンソールから見るとこのようになっています。

object-hold

まとめ

本記事ではGCSのBucket Lock機能のまとめと検証を行いました。料金表を見るかぎり Bucket Lock 機能による料金は、操作APIに対する課金のみなので積極的に使っていきたいところです。

参考

*1:外部からの攻撃ではなく、別の作業者によるオペミスを想定しています