Cloud KMS を gcloud コマンドで試す

# はじめに

Cloud KMS を使って、gcloud コマンドから鍵管理がどのように行えるか試してみます。

# 環境

* macOS High Sierra Version 10.13.6
* Google Cloud SDK 235.0.0

# Cloud KMS とは

Cloud KMS とは、GCP 上で暗号鍵の作成・管理とその鍵を使用して暗号化・復号化できるサービスです。接続情報などを含むテキストの管理などに利用できます。
AWS であれば、AWS Key Management Service という同様のサービスが存在します。

以降では、Cloud KMS で利用する鍵リング・鍵・鍵バージョンについて触れます。



## 鍵リング

鍵リングとは、鍵をグループ化したもので、プロジェクト内に複数作成できます。また、鍵リング内には複数の鍵を含めることができます。
鍵リングには権限を付与することができ、利用するシステムごとに権限を管理することができます。

![鍵リング](https://cloud.google.com/kms/images/resources2.png)

## 鍵

鍵とは、暗号鍵のことでこの暗号鍵を用いて暗号化、権限のあるユーザーであれば復号できます。

## 鍵バージョン

鍵は世代管理することができ、バージョンは `1` から順に繰り上がっていきます。
バージョンごとに、有効・無効・破棄のスケジュール済み・破棄などの状態があり、明示的に移行するまで復号に利用できます。

## 注意事項

作成した鍵リングや鍵・鍵バージョンは、完全に削除することはできません。鍵バージョンを削除することによって課金の対象から外れ利用はできなくなりますが、鍵が削除されたという情報は残り続けます。
完全に削除するのであれば、プロジェクト自体の削除が必要になります。
以降の Cloud KMS を試す際に不要な鍵を残したくない場合は、テスト用のプロジェクトを作成することをおすすめします。

# Cloud KMS の API を有効化する

以下のリンクから Cloud KMS の API を有効にします。
[Cloud KMS API の有効化](https://console.cloud.google.com/flows/enableapi?apiid=cloudkms.googleapis.com)

# Cloud SDK をインストールする

以下のドキュメントを参考に Cloud SDK をインストールし、プロジェクトの設定をしてください。
[Google Cloud SDK documentation](https://cloud.google.com/sdk/docs/)

# 鍵リングを作成する

以下のコマンドで鍵リングを作成します。

サンプルでは、鍵リング名に `sample` という名前を指定しています。
`--location` には、`global`を指定しています。`global` であれば世界中のゾーンから利用可能です。
特定のリージョンにアクセスが集中している場合は、ロケーションをその地域に設定すると良いと思います。
指定可能なロケーションについては、以下のドキュメントを参照してください。
[Cloud KMS locations](https://cloud.google.com/kms/docs/locations)

```bash
$ gcloud kms keyrings create sample --location global
```

# 鍵を作成する

以下のコマンドで鍵を作成します。

サンプルでは、鍵名に `sample-key` という名前を指定しています。
`--location` には、鍵リング同様 `global`を指定しています。
`--purpose` には、鍵の用途を指定します。ここでは、`encryption` と指定しています。

```bash
$ gcloud kms keys create sample-key --location global \
  --keyring sample --purpose encryption
```

以下のコマンドから鍵の詳細が確認できます。

```bash
$ gcloud kms keys list --location global --keyring sample
NAME                                                                          PURPOSE          LABELS  PRIMARY_ID  PRIMARY_STATE
projects/[PROJECT_ID]/locations/global/keyRings/sample/cryptoKeys/sample-key  ENCRYPT_DECRYPT          1           ENABLED
```

# データの暗号化

暗号化するテキストファイルを作成します。

```bash
$ echo "Hello Cloud KMS" > plaintext.txt
```

以下のコマンドでテキストファイルを暗号化します。

`--keyring` と `--key` には、事前に作成した鍵リング名と鍵名を指定します。
`--ciphertext-file` には、暗号化された内容を含むファイル名を指定します。

```bash
$ gcloud kms encrypt --location global \
  --keyring sample --key sample-key \
  --plaintext-file plaintext.txt \
  --ciphertext-file plaintext.txt.encrypted
```

暗号化されたテキストには、base64 でエンコードされた値が含まれています。
構成管理するのであれば、以下のコマンドで base64 でデコードしたテキストを管理すると利用しやすいと思います。

```bash
cat plaintext.txt.encrypted | base64
```

# テキストの復号化

以下のコマンドで暗号化されたテキストファイルを復元します。

`--ciphertext-file` には、暗号化されたファイル名を指定します。
`--plaintext-file` には、復号化するファイル名を指定します。

```bash
$ gcloud kms decrypt --location global \
  --keyring sample --key sample-key \
  --ciphertext-file plaintext.txt.encrypted \
  --plaintext-file plaintext.txt.decrypted
```

`plaintext.txt.decrypted` ファイルを確認すると復号化できていることが分かります。

```bash
$ cat plaintext.txt.decrypted
Hello Cloud KMS
```

# お掃除

以下のコマンドで作成した鍵のバージョンを確認します。

```bash
$ gcloud kms keys versions list --location global \
  --keyring sample --key sample-key
NAME                                                                                            STATE
projects/[PROJECT_ID]/locations/global/keyRings/sample/cryptoKeys/sample-key/cryptoKeyVersions/1  ENABLED
```

バージョン番号が `1` だと分かったので、鍵のバージョン番号 `1` を指定し以下のコマンドで鍵を削除します。

```bash
$ gcloud kms keys versions destroy 1 \
  --location global --keyring sample --key sample-key
``` 

改めて鍵のバージョンを確認すると、状態が `DESTROY_SCHEDULED` に変更されていることが分かります。
状態が `DESTROY_SCHEDULED` に変更されてから 24 時間後に削除されます。

```bash
$ gcloud kms keys versions list --location global \
  --keyring sample --key sample-key
NAME                                                                                            STATE
projects/[PROJECT_ID]/locations/global/keyRings/sample/cryptoKeys/sample-key/cryptoKeyVersions/1  DESTROY_SCHEDULED
```

前述したとおり、鍵を削除することで利用できなくなり課金の対象にはなりませんが、鍵情報自体は残り続けることに注意してください。

# さいごに

gloud コマンドから Cloud KMS を利用してみました。
GCP 上で手軽に秘密情報が管理できるのは便利だと思います。
次回があれば、Cloud KMS を利用したアプリケーションの環境変数の利用について試してみたいと思います。

# 参考
[Cloud Key Management Service documentation](https://cloud.google.com/kms/docs/)
[Cloud KMS (Cloud Key Management Service) について調べたことのまとめ](https://qiita.com/ao_log/items/673e3f37d3e5069d0d03)