HashiCorp VaultのKVシークレットエンジンを使ったkey/value形式のデータの読み書きを試した。
触り始めて間もないので解釈や表現がおかしいところはあるかも。(あったら教えてください)
HashiCorp VaultにおいてシークレットエンジンにはAWSやAzure、SSHなど様々なデータ構造の定義があり、本エントリではその中の一つであるkey/value形式のデータを扱うKVシークレットエンジンを使ったデータの読み書きについての簡単にまとめ。
ほんとはイケてないんだけど、作業はすべてrootで実施(root tokenでログイン済み状態)
RESTについては、使用するトークン(例では環境変数 VAULT_TOKEN
にセットしてる)は、同様にroot tokenで、X-Vault-Token
ヘッダで指定する。X-Vault-Token
でなく、一般的な"Authorization: Bearer $VAULT_TOKEN"
でも認証可能。
KVシークレットエンジンの有効化
「KVシークレットエンジンの有効化」というと始めはピンとこなかったけど、「KV形式のデータを扱うための箱を作る」が近いイメージだと思う。
C言語風にいうとKV構造体変数を保持する領域を確保する、みたいな。
my-kv-secret
という名前(パス)のKVシークレットエンジンを有効にするには以下のコマンド。
/ $ vault secrets enable -path=my-kv-secret -version=2 kv Success! Enabled the kv secrets engine at: my-kv-secret/
-path
オプションを省略すると、kv
というパスのKVシークレットエンジンが作成される。
-version
オプションを省略するとKVシークレットエンジンversion1で作成される。version2で作成する場合は-version=2
を付加。
普通のLinuxコマンドと違って、オプションを末尾に付与できないので注意。
バージョンの違いについてはドキュメント参照
KVシークレットエンジンの無効化
有効化の逆なので、要は削除。
/ $ vault secrets disable my-kv-secret Success! Disabled the secrets engine (if it existed) at: my-kv-secret/
KVシークレットエンジンの一覧
/ $ vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_fa65f299 per-token private secret storage identity/ identity identity_0917a11b identity store my-kv-secret/ kv kv_838b2e62 n/a sys/ system system_8a5e2f0e system endpoints used for control, policy and debugging
-detailed
を付与すると詳細が表示される。
読み書きと一覧
最初わかりづらかったんだけど、「一つのKVシークレットエンジンにkey/value形式のデータを保存」ではなく「一つのKVシークレットエンジン内にあるキー毎にkey/value形式のデータを保存」というデータ構造になってる。
という表現もやっぱりわかりづらいんで、百聞は一見に如かずで実行例。
write
CLI
my-kv-secret
シークレットエンジンに、server1
とserver2
いうキーで、ユーザー名・パスワード・IPアドレスを保存。
/ $ vault kv put my-kv-secret/server1 username=zaki password=curry_tabetai host=192.168.10.89 Success! Data written to: my-kv-secret/server1 / $ vault kv put my-kv-secret/server2 username=zaki password=curry_tabeta host=192.168.10.13 Success! Data written to: my-kv-secret/server2
ちなみにこの書式はKVシークレットエンジンversion1のもので、version2では非推奨。
version2では-mount
オプションでシークレットエンジン名を指定する書式が推奨される。
/ $ vault kv put -mount=my-kv-secret server3 username=zaki password=asuha_curry host=192.168.10.10 Success! Data written to: my-kv-secret/server3
JSONファイル
JSON形式のファイルを使ったwriteも可能。
/ $ cat /var/tmp/sample.json { "username": "zaki", "password": "json-data", "host": "192.168.18.6" } / $ vault kv put -mount=my-kv-secret server4 @/var/tmp/sample.json Success! Data written to: my-kv-secret/server4
REST
POSTするデータはdata
以下に作成するのがポイント (ここ見落として30分くらい溶かした笑)
$ curl -s -H "X-Vault-Token: $VAULT_TOKEN" \ -X POST \ -d '{ "data": { "username":"zaki", "password":"curl-post", "host":"192.168.18.21" } }' \ http://192.168.0.75:8200/v1/my-kv-secret/data/server5 {"request_id":"45c406a2-9d38-b46c-fd48-32c887366fd8","lease_id":"","renewable":false,"lease_duration":0,"data":{"created_time":"2024-02-20T13:42:48.263373535Z","custom_metadata":null,"deletion_time":"","destroyed":false,"version":1},"wrap_info":null,"warnings":null,"auth":null}
JSONファイルを使う場合も同様
$ cat tmp/post.json { "data": { "username":"zaki", "password":"curl-json-post", "host":"192.168.18.26" } } $ curl -s -H "X-Vault-Token: $VAULT_TOKEN" \ -X POST \ -d @tmp/post.json \ http://192.168.0.75:8200/v1/my-kv-secret/data/server6 {"request_id":"3a52eeff-2be4-9b01-94cf-d6316d64f208","lease_id":"","renewable":false,"lease_duration":0,"data":{"created_time":"2024-02-20T13:45:11.476087387Z","custom_metadata":null,"deletion_time":"","destroyed":false,"version":1},"wrap_info":null,"warnings":null,"auth":null}
エンドポイントはシークレットエンジンのバージョンで異なるので注意。
前述の例はversion2の場合。
version1の場合は/v1/<secret-engine-name>/<key-name>
となり、/data
が無くなる。
(先頭の/v1
はAPIバージョンであってシークレットエンジンのバージョンではない)
ここまで全部ユーザー名・パスワード・ホストと、データ構造をそろえているけど、これはたまたまそうしてるだけで、別にそろってる必要はなく柔軟に書き込み可能。
list
/ $ vault kv list my-kv-secret Keys ---- server1 server2 server3 server4 server5 server6
writeで作った6件分のキーがリストされていることがわかる。
RESTの場合は以下の通り。
$ curl -s -H "X-Vault-Token: $VAULT_TOKEN" -X LIST http://192.168.0.75:8200/v1/my-kv-secret/metadata | python -m json.tool { "request_id": "fb371bc4-b31b-7cb1-a870-e3fedc8411ef", "lease_id": "", "renewable": false, "lease_duration": 0, "data": { "keys": [ "server1", "server2", "server3", "server4", "server5", "server6" ] }, "wrap_info": null, "warnings": null, "auth": null }
ちなみにAPIリファレンスにこれ乗って無さそうなんだけど。。(/metadata
のあとのパス記載が全てrequired
になってる)
read
CLI
put
で作成したデータは当然get
で参照できる。
/ $ vault kv get my-kv-secret/server1 ====== Secret Path ====== my-kv-secret/data/server1 ======= Metadata ======= Key Value --- ----- created_time 2024-02-20T13:30:15.916047056Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ====== Data ====== Key Value --- ----- host 192.168.10.89 password curry_tabetai username zaki
KVシークレットエンジンversion2を使っていると、この通りメタデータも含まれる。(version1の場合はデータのみ)
書式についてもputと同様、-mount
の使用が推奨されている。
/ $ vault kv get -mount=my-kv-secret server2 ====== Secret Path ====== my-kv-secret/data/server2 ======= Metadata ======= Key Value --- ----- created_time 2024-02-20T13:30:15.990461672Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ====== Data ====== Key Value --- ----- host 192.168.10.13 password curry_tabeta username zaki
また、-format
を使えばjsonやyaml形式でも出力できる。
/ $ vault kv get -format=json -mount=my-kv-secret server3 { "request_id": "804b3606-ee34-7734-1ff3-efa9011ce5d2", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "data": { "host": "192.168.10.10", "password": "asuha_curry", "username": "zaki" }, "metadata": { "created_time": "2024-02-20T13:30:16.03813777Z", "custom_metadata": null, "deletion_time": "", "destroyed": false, "version": 1 } }, "warnings": null }
REST
$ curl -s -H "X-Vault-Token: $VAULT_TOKEN" http://192.168.0.75:8200/v1/my-kv-secret/data/server4 | python -m json.tool { "request_id": "b6370992-2cc7-9e63-97ff-ea7daf9d0e9b", "lease_id": "", "renewable": false, "lease_duration": 0, "data": { "data": { "host": "192.168.18.6", "password": "json-data", "username": "zaki" }, "metadata": { "created_time": "2024-02-20T13:30:16.101513188Z", "custom_metadata": null, "deletion_time": "", "destroyed": false, "version": 1 } }, "wrap_info": null, "warnings": null, "auth": null }
環境
- HashiCorp Vault on Kubernetes
- CHART: vault-0.27.0
- APP VERSION: 1.15.2
更新と削除はまた別途…
=> 書いたよ (2024.07.31)
ところでSecrets EngineだったりSecrets EnginesだったりSecrets enginesだったり公式ドキュメントの表記揺れが結構あるように見える。。どれが正解なの。。