Key Management Serviceについて勘違いしていたこと

あるいは Kanazawa.rb meetup #74 - Kanazawarb に行ってきたよ。

最近 Google Cloud Key Management Service について調べていた。

というのも、Cloud Functions で小さいツールを業務的に扱うことがたぶん今後増えるので、サービスアカウントが増える、ということはこのアカウントのキー管理が増える、ということを予想していた。

結論から言うとこの二つのうち両方を勘違いしていたのだが、その過程で面白いことが分かったのでまとめておこうと思う。

Cloud KMSは自分の管理したい鍵を直接管理してくれるものではなかった

Cloud Key Management Service | Cloud KMS | Google Cloud

Cloud KMS は確かに鍵を管理してくれるのだが、今自分が管理したいと思っている、すでに存在している鍵を収める金庫のような役割を果たしてくれるわけではなかった。

Cloud KMS は決してクラウドから取り出すことのできない鍵を生成、管理してくれるものだったのだ。

「え? 取り出せない鍵に意味あるの?」

あるんです。

「鍵に対して名前が振ってあって、その名前に対して暗号化/複合したいデータを送りつけてやる」

という使い方をすれば「取り出せないけど使える鍵」を実現できる。そしてこの方式には明確なメリットがある。

  • 鍵を利用したいレベルの秘密情報の利用の痕跡をすべてクラウド側に残せる
  • 特定の名前の鍵を破棄すれば、その鍵を利用するデータの利用も無効化できる
    • (鍵にアクセスできるユーザーなどで管理できるかどうかは未確認)

そう。単なる金庫ではなく監査が行えるし、暗号化したデータの利用も制御可能になる。

この鍵はどう使うのがよいのか?

この鍵はあくまでクラウド側で管理しやすい形をしているもので、直接何かに使えるわけではない。まぁ、暗号化/複合はデータを送りつけてやれば可能だが、

暗号化/複合のたびに通信が発生するので、ありとあらゆる暗号利用シーンに使うのは現実的でないし、なんなら暗号化/複合できるデータの容量には制限がある1

ということで、

  • データを暗号化して保存する鍵を暗号化する
  • 何かの認証に利用する鍵を暗号化する

など、鍵を暗号化する鍵 ( Key Encryption Key ) として利用することを想定しているらしい。

そこで新たな疑問

  1. Cloud KMSへアクセスする権限の認証、認可に利用するキーの管理はどうなるのか?
  2. 暗号化したキーはどこに保存するのがよいのか?

これについては、まだ完全に解決していないが、

  • Cloud KMS へアクセスするマスターキーの管理は頑張ってね
  • Cloud Storage の読み書きの際には実は Cloud KMS の key name を利用したアクセスが可能

という辺りにヒントがありそう2。少なくとも大量の鍵を大量のまま頑張って管理するよりは頑張らずに管理することは可能そうだ。

Cloud FunctionsからCloud Storageへのアクセスは鍵不要だった

Function の動作しているサービスアカウントの Default Credentials で同一プロジェクトの Storage は読み書き可能だった。

サーバー間での本番環境アプリケーションの認証の設定 | 認証 | Google Cloud

環境変数が設定されていない場合、ADC では、サービスで実行されているアプリケーションに応じて、Compute Engine、Kubernetes Engine、App Engine、または Cloud Functions によって提供されているデフォルトのサービス アカウントを使用します。

※ もしかしたら beta から GA になったタイミングでこの仕様は変わっているかもしれない

しかしpkgcloudはそれを許さなかった

pkgcloud/google.md at master · pkgcloud/pkgcloud

Using the Google Cloud provider requires:

  1. A project id
  2. A JSON key file

ということでFunction実行時の鍵を減らすには

  • pkgcloud に pull-req を送って default credentials を利用できるようにする
  • pkgcloud の利用を諦めて独自に Google API SDK の wrapper を作って file system へのアクセスと透過的に切り替える何かを作る
  • local の file system での開発を諦める

以上から決断が必要そう、ということが分かった。

CI/CDなどからKMSを利用する方法を確立するのが次の課題

Function 実行時に必要な鍵は(将来的に)なくせることが分かった。もう一つの鍵は CI/CD サービスから deploy 時に利用するサービスアカウントの鍵である。

これについては CI/CD サービスが KMS を提供するクラウド3の外にあるCircleCI を今のところ使っているので、どうしても鍵を外部に保存する必要があり、その鍵自体を KMS で暗号化することが肝要になってくる。

そこで CI/CD サービスから KMS を利用して安全に暗号化/複合できるようにする手法を確立しておくことで、今後 deploy の必要な Function が増えても管理コストが極力増えないようにできるはずだ。

以上、あーなるほどね、すっきりした。

  1. 2018-10-21現在でGoogle KMSは64KiB, AWS KMSは4KB 

  2. Cloud StorageのドキュメントではなくSDKのコードを読んでいて気がついた。Google Cloudのドキュメントから情報を探すの難しすぎるよ。 

  3. 今回の私の場合は Google 

More