Vault で特定の lease のみを renew できるように権限を絞る
GCP Secret Engine を使ってサービスアカウントの鍵を管理することを考える。以下のような policy を用意し、それを使って認可することになるだろう。(Terraform で管理されている前提)
code:hcl
data "vault_policy_document" "nantoka" {
rule {
path = "gcp/key/nantoka"
capabilities = "read"
}
}
resource "vault_policy" "nantoka" {
name = "nantoka"
policy = data.vault_policy_document.nantoka.hcl
}
これだけで GCP のクレデンシャルを読むだけなら十分だが、TTL を伸ばしたり縮めたりするために vault lease renew したくなる場合もあるだろう。その場合は sys/leases/renew に書き込める権限を与えればよい。cf. https://www.vaultproject.io/api-docs/system/leases#renew-lease
code:hcl
data "vault_policy_document" "nantoka" {
rule {
path = "gcp/key/nantoka"
capabilities = "read"
}
rule {
path = "sys/leases/renew"
capabilities = "create", "update"
}
}
resource "vault_policy" "nantoka" {
name = "nantoka"
policy = data.vault_policy_document.nantoka.hcl
}
ただしこのままではあらゆる lease を renew できてしまう。nantoka として認証される悪意を持ったユーザが何らかの方法で別ユーザ X の lease ID を盗んだ場合、その lease を必要以上に伸ばして X のクレデンシャルを長く使い続ける、といったことが可能になってしまう。そもそも X のクレデンシャルが盗まれてる時点でアウトだが、被害を最小限にするためにも lease renew する権限は可能な限り小さくしておきたい。
そこで parameter constraints が使える cf. https://www.vaultproject.io/docs/concepts/policies#parameter-constraints
code:hcl
data "vault_policy_document" "nantoka" {
rule {
path = "gcp/key/nantoka"
capabilities = "read"
}
rule {
path = "sys/leases/renew"
capabilities = "create", "update"
allowed_parameter {
key = "lease_id"
value = "gcp/key/nantoka/*"
}
allowed_parameter {
key = "increment"
value = []
}
}
}
sys/leases/renew のパラメータ lease_id を特定の prefix で縛ることで、lease renew できる範囲を狭くしている。
allowed_parameters はホワイトリスト方式なのできちんと increment も設定しないといけない。また、ドキュメントをちゃんと読めば「何でもいい」場合には vaule = ["*"] のようにしてはいけないことがわかる。空配列が正しい。これでだいぶハマった...
https://github.com/hashicorp/vault/blob/c14bd9a2b1d2c20f15b9f93f5c2d487507bb8a2f/vault/acl.go#L723-L725
ここで与えられたパラメータが glob 風パターンとマッチしているかを判定している
https://github.com/hashicorp/vault/blob/c14bd9a2b1d2c20f15b9f93f5c2d487507bb8a2f/sdk/helper/strutil/strutil.go#L362-L379
この実装を見る限り、パターンが * の場合、* としかマッチしなさそう
#Vault