Skip to content

Latest commit

 

History

History
239 lines (184 loc) · 8.83 KB

policy.md

File metadata and controls

239 lines (184 loc) · 8.83 KB

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

ここではVaultがサポートするいくつかの認証プロバイダーとの連携と、ポリシーによるアクセスコントロールを試してみます。これらの機能を使うことでクライアントとなるユーザ、ツールやアプリに対してどのリソースに対して、どの権限を与えるかというアイデンティティベースのセキュリティを設定することが出来ます。

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

ここではその一部の方法とポリシーの設定を扱います。

初めてのポリシー

まず、プリセットされるポリシー一覧を確認してみましょう。ポリシーを管理するエンドポイントはsys/policysys/policiesです。sysのエンドポイントにはその他にも様々な機能が用意されています。

$ export VAULT_ADDR="http://127.0.0.1:8200"
$ vault secrets enable -path=kv -version=2 kv
$ vault secrets enable -path=database database
$ vault list sys/policy

Keys
----
default
root
$ 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"]
}

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

pathと指定されているのが各エンドポイントでcapablitiesが各エンドポイントに対する権限を現しています。試しにdefaultの権限を持つトークンを発行してみましょう。defaultにはこの前に作成したdatabaseへの権限はないのでdatabaseのパスへの如何なる操作もできないはずです。

$ vault token create -policy=default
Key                  Value
---                  -----
token                s.acBPCz3lfDryfVr01RgwyTqK
token_accessor       DnUd62Wcfwbg6eDX5Mhha0jf
token_duration       768h
token_renewable      true
token_policies       ["default"]
identity_policies    []
policies             ["default"]

defaultの権限を持ったトークンを生成しました。このトークンをコピーします。Tokenを環境変数にセットしておきましょう。

$ export DEFAULT_TOKEN=s.acBPCz3lfDryfVr01RgwyTqK
$ export ROOT_TOKEN=s.51du1iIeam79Q5fBRBALVhRB

databaseエンドポイントにアクセスしましょう。権限がないためpermission deniedが発生します。

$ VAULT_TOKEN=$DEFAULT_TOKEN vault list database/roles
Error listing database/roles/: Error making API request.

URL: GET http://127.0.0.1:8200/v1/database/roles?list=true
Code: 403. Errors:

* 1 error occurred:
	* permission denied

ポリシーを作る

ポリシーはVaultのコンフィグレーションと同様HCLで記述します。

$ cd /path/to/vault-workshop
$ cat > my-first-policy.hcl <<EOF
path "database/*" {
  capabilities = [ "read", "list"]
}
EOF

作ったらvault policy writeのコマンドでポリシーを作成します。ポリシーの作成はRoot Tokenで実施します。

$ VAULT_TOKEN=$ROOT_TOKEN vault policy write my-policy my-first-policy.hcl
Success! Uploaded policy: my-policy

$ vault policy list           
default
my-policy
root

$ vault policy read my-policy
path "database/*" {
  capabilities = [ "read", "list"]
}

新しいポリシーができました。このポリシーと紐づけられたトークンはdatabaseエンドポイントへのread, listの権限を与えられます。ではトークンを発行してみます。

$ VAULT_TOKEN=$ROOT_TOKEN vault token create -policy=my-policy 
Key                  Value
---                  -----
token                s.bA9M42W41G7tF90REMDCtMeO
token_accessor       LfQCnqPOJHGqO8TplfSjTNFs
token_duration       768h
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

Vaultにこのトークンを使って以下のコマンドを実行してください。

$ export MY_TOKEN=s.bA9M42W41G7tF90REMDCtMeO
$ VAULT_TOKEN=$MY_TOKEN vault list database/roles       
Keys
----
role-handson
role-handson-2
role-handson-3

$ VAULT_TOKEN=$MY_TOKEN vault read database/roles/role-handson
Key                      Value
---                      -----
creation_statements      [CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';]
db_name                  my-mysql-database
default_ttl              1h
max_ttl                  24h
renew_statements         []
revocation_statements    []
rollbakc_statements      []

$ VAULT_TOKEN=$MY_TOKEN vault kv list kv/
Error making API request.

URL: GET http://127.0.0.1:8200/v1/sys/internal/ui/mounts/kv
Code: 403. Errors:

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

Databaseのエンドポイントのread, list出来てきますがkvエンドポイントには権限がないことがわかります。

次にDatabaseエンドポイントにwriteの処理をしてみましょう。

$ VAULT_TOKEN=$MY_TOKEN vault write database/roles/role-handson-4 \
    db_name=mysql-handson-db \
    creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON handson.product TO '{{name}}'@'%';" \
    default_ttl="30s" \
    max_ttl="30s"

エラーが出るはずです。

Error writing data to database/roles/role-handson-4: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/database/roles/role-handson-4
Code: 403. Errors:

* 1 error occurred:
	* permission denied

ポリシーに設定した通り、databaseに対するread, listの処理が成功しましたがwriteの処理、kvに対する処理はエラーが発生したことがわかります。deny by defaultというルールのもと、指定したもの以外は全てdenyとなります。

もう少し細かいポリシーに変更してみましょう。

ドキュメントを見ながらdatabase/roles以下の直下のすべてのリソースに対してcreate,read,listの権限があるが、database/roles/role-handsonだけには一切アクセスできないコンフィグファイルを作ってみてください。

正解はこちらです。

$ VAULT_TOKEN=$ROOT_TOKEN vault policy write my-policy my-first-policy.hcl
$ VAULT_TOKEN=$ROOT_TOKEN vault token create -policy=my-policy -ttl=20m
$ export MY_TOKEN=<TOKEN_ABOVE>
$ VAULT_TOKEN=$MY_TOKEN vault list database/roles
Keys
----
role-handson
role-handson-2
role-handson-3

$ VAULT_TOKEN=$MY_TOKEN vault read database/roles/role-handson
Error reading database/roles/role-handson: Error making API request.

URL: GET http://127.0.0.1:8200/v1/database/roles/role-handson
Code: 403. Errors:

* 1 error occurred:
	* permission denied

$ VAULT_TOKEN=$MY_TOKEN vault read database/roles/role-handson-2
Key                      Value
---                      -----
creation_statements      [CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON handson.product TO '{{name}}'@'%';]
db_name                  mysql-handson-db
default_ttl              1h
max_ttl                  24h
renew_statements         []
revocation_statements    []
rollback_statements      []

以上のようになればOKです。

ここまではトークン発行の権限を持つユーザから直接トークンをCLIを使って発行してきました。通常クライアントからVaultを利用する際は信頼する認証プロバイダとVaultを連携させプロバイダで認証をし適切なトークンを発行するといったワークフローを簡単に実現できます。以降の章ではその方法をいくつか紹介していきます。

参考リンク