this-week-in-gorilla

Vaultに入門する

先日おうちk8sクラスタにVaultを構築したので、Vaultを完全理解するため入門する。

https://github.com/hashicorp-japan/vault-workshop-jp をベースにやっていく。

Vault CLIのインストール

公式ドキュメントに沿ってインストールする。

$ brew tap hashicorp/tap
$ brew install hashicorp/tap/vault
$ vault --version
Vault v1.14.0 (13a649f860186dffe3f3a4459814d87191efc321), built 2023-06-19T11:40:23Z

Hello Vault

Vaultサーバーにログインする。tokenは構築時にメモしたRoot Tokenを使う。 問題なければtokenなどが表示される。

$ export VAULT_ADDR=http://pi1:30820
$ vault login                       
Token (will be hidden): 
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                xxxxxxxxxxxxxxxxxx
token_accessor       xxxxxxxxxxxxxxxx
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

こちらによると、Root Tokenは最初の設定に使ったあとに破棄して新しいtokenを作ったほうが良いらしいが、一旦後回し。

現在有効になっているシークレットエンジンを確認する。

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_f62d42bd    per-token private secret storage
identity/     identity     identity_c3977962     identity store
sys/          system       system_4095113b       system endpoints used for control, policy and debugging

::: info シークレットエンジンとは

公式ドキュメントを読むと、エンジンは以下のことをするようだ
名前の通りって感じ

:::

これで準備は整ったので簡単なkvから触ってみる。
こちらに沿ってやってみる。

# KVのシークレットエンジンを有効化
$ vault secrets enable -path=kv -version=2 kv
Success! Enabled the kv secrets engine at: kv/

# バージョンニングを有効にする
$ vault kv enable-versioning kv
Success! Tuned the secrets engine at: kv/

# データを保存
$ vault kv put kv/iam name=kabu password=passwd
== Secret Path ==
kv/data/iam

======= Metadata =======
Key                Value
---                -----
created_time       2023-06-25T09:01:32.457141967Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

# 保存したデータを取得
$ vault kv get kv/iam
== Secret Path ==
kv/data/iam

======= Metadata =======
Key                Value
---                -----
created_time       2023-06-25T09:01:32.457141967Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

====== Data ======
Key         Value
---         -----
name        kabu
password    passwd

ポリシーを使ってアクセスを制御する

こちらに沿ってやっていく。

最初にトークンについて以下の説明があった。

ここまでRoot Tokenを利用して様々なシークレットを扱ってきましたが、実際の運用では強力な権限を持つRoot Tokenは保持をせずに必要な時のみ生成します。通常、最低限の権限のユーザを作成しVaultを利用していきます。また認証も直接トークンで行うのではなく信頼できる認証プロバイダに委託することがベターです。

基本的に認証プロバイダに委託してトークンをもらい、それを使うのが一般的らしい。

早速ポリシーについて確認する。

# ポリシー一覧
$ vault list sys/policy
Keys
----
default
root

# defaultのポリシーのcapabilitiesを確認
$ vault read sys/policy/default
Key      Value
---      -----
name     default
rules    # Allow tokens to look up their own properties
path "auth/token/lookup-self" {
    capabilities = ["read"]
}

# Allow tokens to renew themselves
path "auth/token/renew-self" {
    capabilities = ["update"]
}
...

各endpointにcapabilitiesがあって、それがどんな権限があるかを表している。

試しにdefaultのポリシーのtokenを発行してさっき作ったkvにアクセスできるかを確認する。

$ vault token create -policy=default
Key                  Value
---                  -----
token                xxxxxxxxxxx
token_accessor       xxxxxxxxxxx
token_duration       768h
token_renewable      true
token_policies       ["default"]
identity_policies    []
policies             ["default"]
$ export DEFAULT_TOKEN=xxxxxxxxxxxx
$ export ROOT_TOKEN=xxxxxxxxxx

$ VAULT_TOKEN=$DEFAULT_TOKEN vault kv get kv/iam
Error making API request.

URL: GET http://pi1:30820/v1/sys/internal/ui/mounts/kv/iam
Code: 403. Errors:

* preflight capability check returned 403, please ensure client's policies grant access to path "kv/iam/"

新しくポリシーを作って、tokenを作ってkvにアクセスできるようにしてみる。

$ nvim my-kv-policy.hcl
path "kv/*" {
  capabilities = ["read", "list"]
}

# ポリシーを作成
$ VAULT_TOKEN=$ROOT_TOKEN vault policy write my-kv-policy my-kv-policy.hcl 
Success! Uploaded policy: my-kv-policy

# 作成されたことを確認する
$ vault policy read my-kv-policy
path "kv/*" {
  capabilities = ["read", "list"]
}

# ポリシーに紐付けられたtokenを発行する
$ VAULT_TOKEN=$ROOT_TOKEN vault token create -policy=my-kv-policy
Key                  Value
---                  -----
token                hvs.CAESIAnw8Nr1R88ZrRXOSdLP6crtbQzJfTsjiwRy2471eJ1-Gh4KHGh2cy5wejI4M1dNWENEdnZtZE9jM1NaT0o3YkI
token_accessor       xj6liTAQe4g65uaAPNm8ZasN
token_duration       768h
token_renewable      true
token_policies       ["default" "my-kv-policy"]
identity_policies    []
policies             ["default" "my-kv-policy"]

# tokenwを使ってkvからデータ取れることを確認
$ VAULT_TOKEN=$MY_TOKEN vault kv get kv/iam
== Secret Path ==
kv/data/iam

======= Metadata =======
Key                Value
---                -----
created_time       2023-06-25T09:01:32.457141967Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

====== Data ======
Key         Value
---         -----
name        kabu

最後にこちらをみて、払い出したtokenを無効化しておく。

$ vault token revoke $DEFAULT_TOKEN
$ VAULT_TOKEN=$DEFAULT_TOKEN vault kv get kv/iam
Error making API request.

URL: GET http://pi1:30820/v1/sys/internal/ui/mounts/kv/iam
Code: 403. Errors:

$ vault token revoke $MY_TOKEN              
Success! Revoked token (if it existed)
$ VAULT_TOKEN=$MY_TOKEN vault kv get kv/iam 
Error making API request.

URL: GET http://pi1:30820/v1/sys/internal/ui/mounts/kv/iam
Code: 403. Errors:

* permission denied

さいごに

とりあえず簡単なKVとポリシーについては理解した。 次は認証プロバイダからtokenを払い出し、そのtokenを使ってシークレットにアクセスできるようにするのをやってみる予定。

最終的には、以下の要件を満たすような構成を作れれば良さそう。

参考資料