HashiCorp Vaultのポリシーを使いこなす

はじめに

前回、Root以外のユーザーを追加しましたが、その際にdefaultというポリシーが適用されていました。HashiCorp Vaultではポリシーにって各ユーザーのアクセス制限を行います。

今回はこのPolicyについて調査し、実際にやってみました。

やってみた

ポリシーファイルの書き方

ポリシーはサーバ起動時のConfigと同様に、 HCLまたはJSONで記載する必要があります。今回はHCLを使います。

ポリシーファイルの記載方法は以下のように、path毎にブロックを記載します。

path "secret/a" {
  ...
}
path "secret/b" {
  ...
}

ブロックの中に記載する要素は4つあります。

  • capabilities
  • required_parameters
  • allowed_parameters
  • denied_parameters

capabilitiesには許可する操作を指定します。create、read、update、delete、listの5つです。またdenyを指定すると全操作を明示的に拒否します。特殊な指定としてはsudoというものがあり、Rootポリシーじゃないとアクセスできないものへのアクセスを許可できるようです。

required_parametersには指定する必要のあるパラメータ、allowed_parametersは指定可能なパラメータ、denied_parametersは指定不可なパラメータです。

準備

以前の記事でもやっていたとおりに、サーバ側でVault Serverを起動しておきます。

クライアント側では、Vault Serverのアドレスを環境変数に設定します。

$ export VAULT_ADDR='https://EC2のパブリックIPアドレス:8200'

initializeします。

$ vault operator init -tls-skip-verify

Unsealして使えるようにします。

$ vault operator unseal -tls-skip-verify
$ vault operator unseal -tls-skip-verify
$ vault operator unseal -tls-skip-verify

RootのTokenを使ってloginします。

$ vault login -tls-skip-verify 6bcc76e3-98d8-3d5d-a8e1-a15ad3cc9ac8

ポリシーファイルの作成

以下のようなポリシーファイルを作成しました。

path "secret/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "secret/denyall" {
  capabilities = ["deny"]
}

path "secret/required" {
  capabilities = ["create"]
  required_parameters = ["foo", "bar"]
}
  
path "secret/allowed" {
  capabilities = ["create"]
  allowed_parameters = {
    "foo" = ["smokey"]
  }
}

path "secret/denied" {
  capabilities = ["create"]
  denied_parameters = {
    "foo" = ["smokey", "monkey"]
  }
}

ポリシーの作成

ポリシーファイルからポリシーを作成します。@は「ロカールディスクから読み込むよ」という指定です。

$ vault write -tls-skip-verify sys/policy/mypolicy policy=@policy.hcl
Success! Data written to: sys/policy/mypolicy

ポリシーを適用したTokenの作成

作成したポリシーmypolicyを適用したトークンを作成します。

$ vault token create -tls-skip-verify -policy=mypolicy
Key                Value
---                -----
token              c3bc86cf-ca2e-7817-07d4-42279fe0af3c
token_accessor     0caacc81-ef62-f842-58df-54bc41e36932
token_duration     768h
token_renewable    true
token_policies     [default mypolicy]

作成したTokenでログインします。

$ vault login -tls-skip-verify c3bc86cf-ca2e-7817-07d4-42279fe0af3c

path "secret/*"の確認

path "secret/*"には全てのcapabilitiesを指定していますので、create、read、update、delete、listが全部出来ます。

create

$ vault write -tls-skip-verify secret/sasakidaisuke value=smokeymonkey
Success! Data written to: secret/sasakidaisuke

$ vault list -tls-skip-verify secret/
Keys
----
sasakidaisuke

read

$ vault read -tls-skip-verify secret/sasakidaisuke
Key                 Value
---                 -----
refresh_interval    768h
value               smokeymonkey

update

$ vault write -tls-skip-verify secret/sasakidaisuke value=bucho
Success! Data written to: secret/sasakidaisuke

$ vault read -tls-skip-verify secret/sasakidaisuke
Key                 Value
---                 -----
refresh_interval    768h
value               bucho

delete

$ vault delete -tls-skip-verify secret/sasakidaisuke
Success! Data deleted (if it existed) at: secret/sasakidaisuke

$ vault list -tls-skip-verify secret/
No value found at secret/

path "secret/denyall"の確認

path "secret/denyall"の内容は以下の通りです。

path "secret/denyall" {
  capabilities = ["deny"]
}

capabilitiesでdenyを指定していますので、何も出来ません。

$ vault write -tls-skip-verify secret/denyall value=deny
Error writing data to secret/denyall: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/denyall
Code: 403. Errors:

* permission denied

しかしsecret/denyall以下については問題なく使えてしまいます。

$ vault write -tls-skip-verify secret/denyall/foo value=deny
Success! Data written to: secret/denyall/foo

$ vault read -tls-skip-verify secret/denyall/foo
Key                 Value
---                 -----
refresh_interval    768h
value               deny

path "secret/denyall"以下全てに対してdenyさせたい場合は、以下のようにポリシーファイルを書き換えます。

path "secret/denyall*" {
  capabilities = ["deny"]
}

そしてポリシーをアップデートします。

$ vault write -tls-skip-verify sys/policy/mypolicy policy=@policy.hcl
Success! Data written to: sys/policy/mypolicy

こうすると、path "secret/denyall"以下全てに対して操作ができなくなります。

$ vault write -tls-skip-verify secret/denyall/foo value=deny
Error writing data to secret/denyall/foo: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/denyall/foo
Code: 403. Errors:

* permission denied

path "secret/required"の確認

path "secret/required"の内容は以下の通りです。

path "secret/required" {
  capabilities = ["create"]
  required_parameters = ["foo", "bar"]
}

fooとbarというパラメータがrequiredされていますので、普通にvalueを入れようとしてもエラーになります。

$ vault write -tls-skip-verify secret/required value=daisuke
Error writing data to secret/required: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/required
Code: 403. Errors:

* permission denied

もちろんfooだけを指定してもエラーになります。

$ vault write -tls-skip-verify secret/required value=daisuke foo=hoge
Error writing data to secret/required: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/required
Code: 403. Errors:

* permission denied

fooとbarという2つのパラメータを両方共指定すれば、valueをwriteすることが出来ます。

$ vault write -tls-skip-verify secret/required value=daisuke foo=hoge bar=fuga
Success! Data written to: secret/required

ちなみにcreateしか許可されていないので、keyをreadすることは出来ません。

$ vault read -tls-skip-verify secret/required
Error reading secret/required: Error making API request.

URL: GET https://EC2のグローバルIPアドレス:8200/v1/secret/required
Code: 403. Errors:

* permission denied

path "secret/allowed"の確認

path "secret/allowed"の内容は以下の通りです。

path "secret/allowed" {
  capabilities = ["create"]
  allowed_parameters = {
    "foo" = ["smokey"]
  }
}

fooというパラメータにsmokeyを入れることだけが許可されていますので、foo以外のパラメータは使えません。

$ vault write -tls-skip-verify secret/allowed bar=hoge
Error writing data to secret/allowed: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/allowed
Code: 403. Errors:

* permission denied

fooにsmokey以外を入れることも許可されません。

$ vault write -tls-skip-verify secret/allowed foo=hoge
Error writing data to secret/allowed: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/allowed
Code: 403. Errors:

* permission denied

fooにsmokeyを入れればサクセスとなります。

$ vault write -tls-skip-verify secret/allowed foo=smokey
Success! Data written to: secret/allowed

path "secret/denied"の確認

path "secret/denied"の内容は以下の通りです。

path "secret/denied" {
  capabilities = ["create"]
  denied_parameters = {
    "foo" = ["smokey", "monkey"]
  }
}

fooにsmokeyとmonkeyを入れることは許可されていません。

$ vault write -tls-skip-verify secret/denied foo=smokey
Error writing data to secret/denied: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/denied
Code: 403. Errors:

* permission denied

$ vault write -tls-skip-verify secret/denied foo=monkey
Error writing data to secret/denied: Error making API request.

URL: PUT https://EC2のグローバルIPアドレス:8200/v1/secret/denied
Code: 403. Errors:

* permission denied

smokeyとmonkey以外は入れることが出来ます。

$ vault write -tls-skip-verify secret/denied foo=daisuke
Success! Data written to: secret/denied

さいごに

ポリシーを使うことで細かいアクセス制限が出来ます。認証情報を登録する管理者と参照だけするユーザー等、細かい設定も可能だと思います。

合わせて読みたい