11
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

gcloudコマンドで試すGCP Secret Manager

Secret Managerは、GCP上でパスワードやAPIキーなどの秘密情報を安全に管理するためのサービスです。2020年3月にGAしました。

似たカテゴリのサービスであるCloud Key Management Service(KMS)は、秘密情報そのものではなく、それらを暗号化・複合するための鍵を管理します。

以前はKMSと独自の暗号化・複合ソリューション、その他BerglasHashiCorp Vaultを利用していたケースの一部もSercert Manager単独で賄えるはずです。

概念

SecretとVersionという単位を理解する必要があります。

Secretは各プロジェクトのグローバルに作成されます。Secretに対しては削除、Versionの追加、ラベルの付与などの操作が可能です。

SecretはVersionを持ちます。個々のVersionは秘密情報や有効、無効、削除済みのステータスを持ちます。

たとえば、「Service AのパスワードをSecret Managerで管理し、アプリケーションから利用したい」とします。これを実現するには、service-a-passwordという名前でSecretを作成し、パスワードを指定してVersionを作成します。このパスワードをアプリケーションから利用する際は、service-a-password SecretのVersion 1を指定してSecret Managerから取得します。

パスワードをローテーションする際は、service-a-password SecretにVersionを追加します。

GCPのコンソールから確認するとつぎのようになります。

service-a-password.png

コマンド概要

gcloudコマンドではSecretと、locationsとversionsに対する操作が可能です。[]は適当に読み替えてください。

# GCPプロジェクト内ではじめて利用する場合はAPIを有効化します
$ gcloud services enable --project [PROJECT_ID] secretmanager.googleapis.com

$ gcloud secrets
ERROR: (gcloud.secrets) Command name argument expected.

Available groups for gcloud secrets:

      locations               Manage locations of users' secrets.
      versions                Manage secret versions.

Available commands for gcloud secrets:

      add-iam-policy-binding     Add IAM policy binding to a secret.
      create                     Create a new secret.
      delete                     Delete a secret.
      describe                   Describe a secret's metadata.
      get-iam-policy             Get the IAM policy for the secret.
      list                       List all secret names.
      remove-iam-policy-binding  Remove IAM policy binding for a secret.
      set-iam-policy             Set the IAM policy binding for a secret.
      update                     Update a secret's metadata.
...

$ gcloud secrets locations
ERROR: (gcloud.secrets.locations) Command name argument expected.

Available commands for gcloud secrets locations:

      describe                Describe a location.
      list                    List all available locations.
...

$ gcloud secrets versions
ERROR: (gcloud.secrets.versions) Command name argument expected.

Available commands for gcloud secrets versions:

      access                  Access a secret version's data.
      add                     Create a new version of an existing secret.
      describe                Describe metadata about the secret version.
      destroy                 Destroy a secret version's metadata and secret
                              data.
      disable                 Disable the version of the provided secret.
      enable                  Enable the version of the provided secret.
      list                    List all versions for a secret.
...

listは利用可能なロケーションのリストです。

$ gcloud secrets locations list
NAME                  LOCATION
asia-east1            Taiwan
asia-southeast1       Singapore
australia-southeast1  Sydney
europe-north1         Finland
europe-west1          Belgium
europe-west4          Netherlands
us-central1           Iowa
us-east1              South Carolina
us-east4              Northern Virginia
us-west1              Oregon
us-west2              Los Angeles

gcloudコマンドからSecretを作成するときは、--locationsオプションで指定します。指定しない場合はGCPがよしなに選択します。後から変更できません。

準備

gcloudコマンドで挙動を確認するにあたり、つぎのコマンドで権限を付与します。

$ gcloud projects add-iam-policy-binding [PROJECT_ID] --member="serviceAccount:[SERVICE_ACCOUNT]" --role="roles/secretmanager.admin"

利用できるロールはつぎの3つです。

  • roles/secretmanager.admin
  • roles/secretmanager.secretAccessor
  • roles/secretmanager.viewer

今回はSecret自体を作成する必要があるため、roles/secretmanager.adminを付与しています。

Secret・Versionの作成・変更

testという名前のSecretを作成し、秘密情報を保存する方法を見ていきます。

$ gcloud secrets create test
Created secret [test].

$ gcloud secrets list
NAME  CREATED              REPLICATION_POLICY  LOCATIONS
test  2020-07-14T12:44:01  automatic

# Secret自体を消そうとすると、含むVersionも一緒に消します。
$ gcloud secrets delete test
You are about to destroy the secret [test] and its [0] version(s).
This action cannot be reversed.

Do you want to continue (Y/n)?  n

ERROR: (gcloud.beta.secrets.delete) Aborted by user.

$ gcloud beta secrets describe test
createTime: '2020-07-14T12:44:01.379968Z'
name: projects/xxxxxxxxxxxx/secrets/test
replication:
  automatic: {}

# Secret自体にできる操作はラベル関連です
$ gcloud secrets update test -h
Usage: gcloud secrets update SECRET [optional flags]
  optional flags may be  --clear-labels | --help | --remove-labels |
                         --update-labels

For detailed information on this command and its flags, run:
  gcloud secrets update --help

# testtestという秘密情報でVersionを追加します
$ echo "test test" > secret.txt
$ gcloud secrets versions add test --data-file ./secret.txt
Created version [1] of the secret [test].

$ gcloud secrets versions list test
NAME  STATE    CREATED              DESTROYED
1     enabled  2020-07-14T13:16:36  -

# describeはデータを確認するものではありません
$ gcloud secrets versions describe 1 --secret test
createTime: '2020-07-14T13:16:36.616572Z'
name: projects/xxxxxxxxxxxx/secrets/test/versions/1
state: ENABLED

# Versionのデータを読むのは'access'です
$ gcloud secrets versions access 1 --secret test
test test

# Version毎に無効にできます
$ gcloud secrets versions disable 1 --secret test
Disabled version [1] of the secret [test].

$ gcloud secrets versions list test
NAME  STATE     CREATED              DESTROYED
1     disabled  2020-07-14T13:16:36  -

# 無効にしたVersionにアクセスするとエラーになります
$ gcloud secrets versions access 1 --secret test
ERROR: (gcloud.secrets.versions.access) FAILED_PRECONDITION: Secret Version [projects/xxxxxxxxxxxx/secrets/test/versions/1] is in DISABLED state.

# Versionを削除する前にdisableすることが推奨されています
$ gcloud secrets versions destroy 1 --secret test
You are about to destroy version [1] of the secret [test]. This action
 cannot be reversed.

Do you want to continue (Y/n)?  Y

Destroyed version [1] of the secret [test].

# 削除したVersionにアクセスしてもエラーになりますが、状態は区別されています
$ gcloud secrets versions access 1 --secret test
ERROR: (gcloud.secrets.versions.access) FAILED_PRECONDITION: Secret Version [projects/xxxxxxxxxxxx/secrets/test/versions/1] is in DESTROYED state.

$ gcloud secrets versions list test
NAME  STATE      CREATED              DESTROYED
1     destroyed  2020-07-14T13:16:36  2020-07-14T13:27:25

# Versionを増やします
$ gcloud secrets versions add test --data-file ./secret.txt
Created version [2] of the secret [test].

$ gcloud secrets versions list test
NAME  STATE      CREATED              DESTROYED
2     enabled    2020-07-14T13:28:46  -
1     destroyed  2020-07-14T13:16:36  2020-07-14T13:27:25

Secretの権限管理

test Secretにアクセスできるサービスを設定します。system-aというService AccountをもつサービスがこのSecretを利用するとしましょう。

# system-a Service Accountを用意します
$ gcloud iam service-accounts create system-a
Created service account [system-a].

# gcloud secretsコマンドで、system-aにSecret Manager関連のポリシーをバインディングできます
# roles/secretmanager.secretAccessor はデータアクセス専用です
$ gcloud secrets add-iam-policy-binding test --member=serviceAccount:system-a@yyyyyyyyyyyyy.iam.gserviceaccount.com --role=roles/secretmanager.secretAccessor
Updated IAM policy for secret [test].
bindings:
- members:
  - serviceAccount:system-a@yyyyyyyyyyyyy.iam.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwWqZxB39ss=
version: 1

# gcloud secretsコマンドでroles/appengine.appAdminを付与しようとするとエラーになります
$ gcloud secrets add-iam-policy-binding test --member=serviceAccount:system-a@yyyyyyyyyyyyy.iam.gserviceaccount.com --role=roles/appengine.appAdmin
ERROR: Policy modification failed. For a binding with condition, run "gcloud alpha iam policies lint-condition" to identify issues in condition.
ERROR: (gcloud.secrets.add-iam-policy-binding) INVALID_ARGUMENT: Role roles/appengine.appAdmin is not supported for this resource.

$ gcloud secrets get-iam-policy test
bindings:
- members:
  - serviceAccount:system-a@yyyyyyyyyyyyy.iam.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwWqZxB39ss=
version: 1 

Secretの利用

system-aというService Accountからアクセスしてみましょう。

今回はgcloudコマンドからアクセスしますが、コンピューティング系のサービスのService Accountを設定し、GCPクライアントライブラリからアクセスするのも要領は同じです。

# system-aのService Accountのクレデンシャルをローカルに…
$ gcloud auth activate-service-account --key-file system-a-service-account.json
Activated service account credentials for: [system-a@yyyyyyyyyyyyy.iam.gserviceaccount.com]

# test Secretのversion 2にアクセス
$ gcloud secrets versions access 2 --secret test
test test

# SecretのVersionにアクセスする以外の操作はエラーになります
$ gcloud secrets versions list test
ERROR: (gcloud.secrets.versions.list) PERMISSION_DENIED: Permission 'secretmanager.versions.list' denied for resource 'projects/yyyyyyyyyyyy/secrets/test' (or it may not exist).

$ gcloud secrets locations list
ERROR: (gcloud.secrets.locations.list) User [system-a@yyyyyyyyyyyy.iam.gserviceaccount.com] does not have permission to access project [yyyyyyyyyyyy] (or it may not exist): Permission 'secretmanager.locations.list' denied for resource 'projects/yyyyyyyyyyyy' (or it may not exist).

その他

BerglasはSecret Managerにも対応しているようです。

Secret管理用のCLIとしても、アプリケーション用のインテグレーション(ライブラリや環境変数管理)としても利用できそうなので随時追記します。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
11
Help us understand the problem. What are the problem?