Hashicorp Vault 操作メモ

# 概要

hashicorp vault の各種操作に必要なコマンドを、探しやすいように1ページにまとめたもの。
個人で触れている箇所のメモです。全機能の網羅ではありません。
※順次更新していきます。

最低限の操作イメージが掴めている人向けです。初めての方は[チュートリアル](https://developer.hashicorp.com/vault/tutorials)を！

# 初期操作

## インストール

パッケージマネージャー対応できるなら、こちらのほうが更新が楽
https://www.vaultproject.io/downloads

```shell
# centos の例
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install vault
vault --version
# 起動設定（クライアントとしてvaultコマンドを利用するのみならば不要）
sudo systemctl enable vault
sudo systemctl start vault
```

auto complete 設定

```shell
# 下記コマンドで、~/.bashrcにauto complete設定が追加される
vault -autocomplete-install
```

## config（初期）

パッケージマネージャでインストールした場合、設定は`/etc/vault.d/vault.hcl`で行う
listener の設定値で、http,https の起動を変えられる

```hcl
# https で起動する場合
listener "tcp" {
  address       = "0.0.0.0:8200"
  tls_cert_file = "/opt/vault/tls/tls.crt"
  tls_key_file  = "/opt/vault/tls/tls.key"
}

# http で起動、localhost接続のみ許可する場合
listener "tcp" {
  address = "127.0.0.1:8200"
  tls_disable = 1
}

# http で起動、他ホストからの接続を許可する場合
listener "tcp" {
  address = "0.0.0.0:8200"
  tls_disable = 1
}
```

設定値の説明はこちら
https://developer.hashicorp.com/vault/docs/configuration

## 接続オプション指定

vaultの稼働環境に応じて、環境変数を指定
vault コマンドは、ここで指定したサーバーに対する操作となる

```shell
# 証明書チェックを無視  ※デフォルト設定で起動した場合は、これが必要
export VAULT_SKIP_VERIFY=true
# httpで起動した場合
export VAULT_ADDR=http://127.0.0.1:8200
# httpsで起動した場合 ※デフォルト
export VAULT_ADDR=https://127.0.0.1:8200
# 他サーバーで稼働中のvaultに接続する場合
export VAULT_ADDR=https://192.168.11.78:8200
```

利用環境に応じて、`/etc/profile`, `~/.bash_profile` などに記述すればよい。

その他、利用可能な環境変数はこちら
[vault 環境変数](https://www.vaultproject.io/docs/commands)

## init

初めて利用する場合はinitializeが必要

```shell
# 初期化  ※出力された root token , unseal key は大切に保管
vault operator init

# unseal key を4つ、 unseal 操作を2回に指定
vault operator init -key-shares=4 -key-threshold=2

# auto-unseal 利用時は、オプションが異なる
vault operator init -recovery-shares 5 -recovery-threshold 2
```

## unseal

vaultサービス起動直後はseal 状態のため、指定回数 unsealが必要

```shell
# 状態確認  Sealed true となっていると一切の操作ができない
vault status
# unseal を指定回数実行
vault operator unseal {unseal key}

# Sealed false となったことを確認
vault status
```

本番環境ならば、別途auto-unseal を利用するとよい
https://developer.hashicorp.com/vault/tutorials/auto-unseal

## 既存の環境を初期化

初期化して`vault operator init`からやり直したい場合は、サービス停止状態でデータを削除し、起動しなおす。

```shell
sudo systemctl stop vault
sudo rm -rf /opt/vault/data/*
sudo systemctl start vault
```

## 手動インストール

直接バイナリを落として、起動させることも可能
https://www.vaultproject.io/downloads より対象OSの BINARY DOWNLOAD よりバージョン選択して、

```shell
# vault コマンドを準備
wget https://releases.hashicorp.com/vault/1.12.2/vault_1.12.2_linux_amd64.zip
sudo unzip vault_1.12.2_linux_amd64.zip -d /usr/local/bin/
sudo chmod +x /usr/local/bin/vault

# 設定ファイルを指定して起動
vault server -config /etc/vault.d/vault.hcl

# 設定毎にファイルを分けて読み込む
vault server \
    -config /etc/vault/main.hcl \
    -config /etc/vault/storage.hcl \
    -config /etc/vault/tcp-listeners.hcl

# /etc/vault ディレクトリ以下の.hclファイルを読み込む
vault server -config /etc/vault
```

## devモードで起動

devモードで起動することで、http起動、unseal不要、login不要 (~/.vault-tokenに書き込まれる)で、即利用できる。
検証内容が明確ならば、手元の環境を汚さず即試せる。
ただしデータは全てメモリ上に保存されるため、vault停止時にすべて消える。

```shell
# dev モードで起動
vault server -dev

# Root Token Id 指定、listen アドレス指定し、バックグラウンドで起動
vault server -dev -dev-root-token-id "root" -dev-listen-address "0.0.0.0:8200" &
# 動作チェック
export VAULT_ADDR=http://127.0.0.1:8200
vault status
vault secrets list

# 利用が終わったら閉じる
pgrep -f vault | xargs kill
```

## History無効化(推奨)

vault から始まるコマンドが、historyに残らないように
unseal、認証、データ登録時など、機密情報を含むコマンド履歴が残ることを防止

```shell
# vault から始まるコマンドはhistoryに残さない
export HISTIGNORE="&:vault*"
```

# 基本操作

このあたりは押さえておいたほうがいいという操作のメモ書き

## login

```shell
# vault login のデフォルトはToken認証
vault login
Token (will be hidden): {認証用のTokenを入力}

# vault login -method で、あらかじめ定義済みのAuthMethodを利用可能
vault login -method=userpass

# auth 設定でデフォルト以外のパスを指定した場合は、パスを指定
vault login -method aws -path aws/dev

# 認証に成功すると、一定のPolicyが付与された期限付きTokenが発行される（Token 認証以外）
# 以降の操作は、このTokenを利用して行う。
vault token lookup

# vault login で発行されたTokenは、~/.vault-token に書き込まれる
cat ~/.vault-token

# Token認証で、あらかじめTokenが分かっている場合は、~/.vault-token に直接に書き込むことで、login操作をしなくとも利用可能
echo "{任意のToken}" > ~/.vault-token

# 既にTokenが分かっている場合は、環境変数指定でも可能
export VAULT_TOKEN="{任意のtoken}"
vault token lookup

# VAULT_TOKEN 変数に書き込むことで、単一コマンドのみ、指定Tokenを利用することも可能
# ※単一行のみ環境変数が有効となる
VAULT_TOKEN="{任意のtoken}" vault token lookup

# 優先順位は VAULT_TOKEN 環境変数 > ~/.vault-token
```

## 利用中のToken情報チェック

TokenId、期限、割り当てられているPolicy などの確認

```shell
vault token lookup
vault token lookup {他のtoken}
VAULT_TOKEN=xxxx vault token lookup

```

## json/yaml 出力

API利用時に限らず、出力項目が多い場合は、json/yamlのほうが見やすいかも

```shell
vault kv list -format=json kv
vault kv list -format=yaml kv
```

## curlコマンド出力

`-output-curl-string`オプションで、vault コマンドの操作を curl で置き換えた内容を出力
vaultの利用はほぼAPIとなるため、操作の確認のために頻繁に利用する

```shell
vault kv get -output-curl-string kv/myapp/system1
```

## 接続先のvaultチェック

本番環境、検証環境など、どのサーバーに対して操作しているかのチェック
該当する操作が見当たらないため、適当な手段をピックアップ

```shell
# 環境変数でVAULT_ADDRをチェック（指定がなければ https://127.0.0.1:8200）
env | grep VAULT

# curl 出力で、どのサーバー宛ての操作を行っているか確認
vault status -output-curl-string

# エラーメッセージを使って確認
VAULT_TOKEN="test" vault token lookup

# login状態ならば、接続先ホスト情報を返す
vault read -format json /sys/host-info | jq -r .data.host
```

# secret

## secret設定の管理（共通）

```shell
# 現在のsecret一覧
vault secrets list
vault secrets list -detailed

# secret 作成
# path 未指定だとデフォルトで path=kv/ となる
vault secrets enable kv
# pathを指定して作成
vault secrets enable -path=kv/myapp kv
# description 追加
vault secrets tune -description="kv for myapp" kv/myapp

# 既存のsecretのpath を変更
vault secrets move kv/ kv-v1/
# パスが重なる場合は2段階で移動
vault secrets move kv/ kv1/
vault secrets move kv1/ kv/myapp

# secret 削除 (pathで指定)
vault secrets disable kv/myapp
```

## kv

id,pass 、API Key などの機密情報を格納する、シンプルなKey-Valueストアとして利用

### secret利用

```shell
# pathを指定してkv secret 作成
vault secrets enable -path=kv/myapp -description="kv for myapp" kv

# 値を登録
vault kv put kv/myapp/it password="foo"
# 一覧
vault kv list kv/myapp/
# 値の確認
vault kv get kv/myapp/it
# 値の変更
vault kv put kv/myapp/it password="bar"
# 値の削除
vault kv delete kv/myapp/it

# 複数項目を登録
vault kv put kv/myapp/system1  hostname="system1"  ipaddress="192.168.0.1"  login_user="operator" login_password="password"

# json 出力
vault kv get -format=json kv/myapp/system1 | jq -r .data

# 一部の項目だけ取得
vault kv get -field=ipaddress kv/myapp/system1

# 修正時はまるごと変更 ※部分的な変更はできない
vault kv put kv/myapp/system1  hostname="system1"  ipaddress="192.168.0.1"  login_user="operator" login_password="P@ssw0rd"

# jsonから登録
vault kv put kv/myapp/system2 -<<EOF
{
  "hostname": "system2",
  "ipaddress": "192.168.0.2",
  "login_user": "user01",
  "login_password": "P@ssw0rd"
}
EOF

# ファイルから登録
tee myapp_system3.json <<EOF
{
  "hostname": "system3",
  "ipaddress": "192.168.0.3",
  "login_user": "user01",
  "login_password": "P@ssw0rd"
}
EOF
vault kv put kv/myapp/system3 @myapp_system3.json

# 特定のkey値をファイルから登録
vault kv put kv/myapp/cert cert=@cert
```

### Policy 設定例

```hcl
# kv/myapp/ 以下のkey-value 管理
path "kv/myapp/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# kv/myapp/ 以下のkey-value 読み取り
path "kv/myapp/*" {
  capabilities = [ "read", "list" ]
}

# kv/myapp/system1, kv/myapp/system2 など同一階層のkey-value 読み取り
path "kv/myapp/+" {
  capabilities = ["read", "list"]
}

# 設定可能な値の制限
# hostname, location は必須、locationは指定値のいずれか
# ※keyは小文字のみ  大文字を含むとうまく動作しないので注意
path "kv/myapp/system1" {
  capabilities = ["create", "read", "update", "delete", "list"]
  required_parameters = ["hostname", "location"]
  allowed_parameters = {
    "*"   = []
    "location" = ["dc", "cloud", "tokyo", "osaka", "nagoya", "fukuoka"]
  }
}
# allowed_parameters   keyに対して許可されているvalue指定可能
# denied_parameters    keyに対して許可されていない値
# required_parameters  指定する必要のあるパラメータ
```

## kv-v2

バージョン管理、ロールバックに対応により、意図しないデータ損失、上書き操作に備えることができる。
ただしパフォーマンスはv1のほうがよい
シンプルに使うならv1、上記機能が必要ならばv2

https://www.vaultproject.io/docs/secrets/kv

### secret利用

```shell
# pathを指定してkv-v2 secret 作成
# kv version2 の場合、-version=2 オプションまたは kv-v2 と指定する
vault secrets enable -path=kv-v2/myapp -version=2 kv
vault secrets enable -path=kv-v2/myapp kv-v2

# v1 からv2 に変更
vault kv enable-versioning kv-v2/myapp

# 指定kv secret の設定確認
vault read kv-v2/myapp/config
# kv-v2/myapp全体でバージョン保持数を指定(デフォルト0 → 10個保持される)
vault read kv-v2/myapp/config max_versions=10


# 値を登録
vault kv put kv-v2/myapp/it password="foo"
# 一覧
vault kv list kv-v2/myapp/
# 値の確認（version 1 となる）
vault kv get kv-v2/myapp/it
# 値の変更（新バージョンに更新）
vault kv put kv-v2/myapp/it password="bar"
# 値の確認（version 2 となる）
vault kv get kv-v2/myapp/it
# 値の削除 （最新バージョンのみ削除される）
vault kv delete kv-v2/myapp/it
# 完全削除
vault kv metadata delete kv-v2/myapp/it

# 複数項目を登録
vault kv put kv-v2/myapp/system1 hostname="system1" ipaddress="192.168.0.1" login_user="operator" login_password="password"

# putでまるごと変更（version 2 となる）
vault kv put kv-v2/myapp/system1 hostname="system1" ipaddress="192.168.0.1" login_user="operator" login_password="P@ssw0rd"

# patchで部分変更（version 3 となる）
vault kv patch kv-v2/myapp/system1 login_password="PASSWORD"

# 最新バージョンを取得
vault kv get kv-v2/myapp/system1
# バージョン指定で取得
vault kv get -version=1 kv-v2/myapp/system1
# metadata を取得
vault kv metadata get kv-v2/myapp/system1

# 特定バージョンに戻す
vault kv rollback -version=2 kv-v2/myapp/system1
# バージョン1、2を削除(delete)
vault kv delete -versions="1,2" kv-v2/myapp/system1
# バージョン2のみ戻す(undelete)
vault kv undelete -versions=2 kv-v2/myapp/system1
vault kv get -version=2 kv-v2/myapp/system1
# バージョン1を完全削除(destroy)
vault kv destroy -versions=1 kv-v2/myapp/system1
# 全バージョン削除
vault kv metadata delete kv-v2/myapp/system1

# 特定のシークレットでバージョン保持数を制限
vault kv metadata put -max-versions=4 kv-v2/myapp/system1

# 指定時間後に自動でdelete
# undeleteしても指定時間後またdeleteとなる
vault kv metadata put -delete-version-after=24h kv-v2/myapp/temporary
```

### Policy 設定例

kv v2利用時は、Policyの記法が異なるため注意
他にもキーの最新バージョン削除、任意のバージョン削除、復元、バージョン破棄などの権限が異なるため注意

```hcl
# kv-v2/myapp/ 以下のkey-value 管理
path "kv-v2/myapp/*" {
  capabilities = [ "create", "read", "update", "list" , "delete", "patch"]
}

# kv-v2/myapp/system1, kv-v2/myapp/system2 など同一階層のkey-value 読み取り
path "kv-v2/myapp/data/+" {
  capabilities = [ "read", "list" ]
}
path "kv-v2/myapp/metadata/+" {
  capabilities = [ "read", "list" ]
}
```

### Link

- [KV Secrets Engine](https://www.vaultproject.io/docs/secrets/kv)
- [Versioned Key/Value Secrets Engine (Tutorial)](https://developer.hashicorp.com/vault/tutorials/secrets-management/versioned-kv)
- [KV Secrets Engine - Version 2 (API)](https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2)
- [Compare Key/Value Secrets Engine v1 and v2](https://developer.hashicorp.com/vault/tutorials/secrets-management/compare-kv-versions)

## aws secret

AWSの必要権限をもった一時IAM AccessKeyを発行し、利用が終わったら破棄する
発行するAccessKeyは期間終了後自動破棄となるため、漏洩リスクをおさえられる。
管理が必要なAccessKeyは1つのみ。なおかつAccessKey更新操作もvaultで行えるため、初期設定以降は、AccessKeyを人が管理する必要はなくなる。

対応できる認証タイプは3つ

- iam_user
- assumed_role
- federation_token

### AWS IAM User、Policy など準備

あらかじめAWSにてvault用のIAMユーザーを用意し、`accesskey`、`secretkey`を取得。
該当IAMユーザーに、必要なポリシーを付与する。
(EC2でvaultを稼働時は、IAM Roleへの割当てでも可)

iam userを利用する場合のポリシー設定例

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachUserPolicy",
                "iam:CreateAccessKey",
                "iam:CreateUser",
                "iam:DeleteAccessKey",
                "iam:DeleteUser",
                "iam:DeleteUserPolicy",
                "iam:DetachUserPolicy",
                "iam:GetUser",
                "iam:ListAccessKeys",
                "iam:ListAttachedUserPolicies",
                "iam:ListGroupsForUser",
                "iam:ListUserPolicies",
                "iam:TagUser",
                "iam:PutUserPolicy",
                "iam:AddUserToGroup",
                "iam:RemoveUserFromGroup"
            ],
            "Resource": [
                "arn:aws:iam::*:user/*",
                "arn:aws:iam::*:group/*"
            ]
        }
    ]
}
```

assume role を利用する場合のポリシー設定例

```json
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::xxxxxxxxxx:role/AssumeUsersRole"
  }
}
```

引き受ける側のroleの信頼ポリシー設定例

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::yyyyyyyy:user/vault"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

### aws secret 設定

```shell
# pathを指定してaws secret作成
vault secrets enable -path=aws/myapp -description="aws for myapp" aws

# root 設定
vault write aws/myapp/config/root \
     access_key="$access_key" \
     secret_key="$secret_key" \
     region=ap-northeast-1

# EC2でvaultを稼働し、IAM Roleで権限を付与した場合は、-force オプション指定で追加可能
vault write -force aws/myapp/config/root

# root 設定確認
vault read aws/myapp/config/root

# lease時間設定  ※lease, lease_max は一度に設定する必要あり
vault write aws/myapp/config/lease lease=15m lease_max=60m
vault read aws/myapp/config/lease

# configに登録したaccesskey を更新
# accesskey更新後、利用できるようになるまで10秒程度かかるので注意
vault write -f aws/myapp/config/rotate-root
```

### role設定 (iam user)

一時 iam user に付与するポリシー関連の設定

```shell
# role作成 policy_documentでインラインポリシー指定
vault write aws/myapp/roles/my-role \
    credential_type=iam_user \
    policy_document=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::*"
    }
  ]
}
EOF

# ファイルからPolicy読み込みも可
vault write aws/myapp/roles/my-role \
    credential_type=iam_user \
    policy_document=@my-role.json

# role作成 policy_arnsで既存のIAMポリシー指定
vault write aws/myapp/roles/s3_readonly \
    credential_type=iam_user \
    policy_arns=arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# policy_arnsを複数指定する場合
vault write aws/myapp/roles/s3_ec2_full \
    credential_type=iam_user \
    policy_arns=arn:aws:iam::aws:policy/AmazonEC2FullAccess \
    policy_arns=arn:aws:iam::aws:policy/AmazonS3FullAccess

# role 作成 iam_groupsで所属グループ指定
vault write aws/myapp/roles/readonly \
    credential_type=iam_user \
    iam_groups=ReadOnly

# role 一覧
vault list aws/myapp/roles
# role 内容
vault read aws/myapp/roles/s3_readonly
# role削除
vault delete aws/myapp/roles/readonly

# tag付け
vault write aws/myapp/roles/s3_ec2_full \
    iam_tags="system=vault" iam_tags="created=saitamanokusa"
```

### 動作チェック (iam user)

```shell
# 一時 AccessKey 発行
# ※実際に認証、操作できるようになるまで10秒程度かかるので注意
res=$(vault read --format=json aws/myapp/creds/my-role)
echo "$res"

# 取得した一時ユーザーで操作ができることを確認
export AWS_ACCESS_KEY_ID=$(echo $res |jq -r .data.access_key)
export AWS_SECRET_ACCESS_KEY=$(echo $res |jq -r .data.secret_key)
export AWS_DEFAULT_REGION=ap-northeast-1

aws sts get-caller-identity
aws iam list-users
aws s3 ls
aws ec2 describe-instances

# lease id で情報確認、破棄
vault lease lookup $(echo $res |jq -r .lease_id)
vault lease revoke $(echo $res |jq -r .lease_id)
```

### role設定、動作チェック (assume role)

```shell
# role作成 role_arns で利用するroleを指定
vault write aws/myapp/roles/assume_user \
    role_arns=arn:aws:iam::xxxxxxxxxx:role/AssumeUsersRole \
    credential_type=assumed_role \
    default_sts_ttl=15m max_sts_ttl=60m

vault read aws/myapp/roles/assume_user

# 一時 AccessKey 発行
# ※assume role 利用では、すぐに認証、操作が可能
res=$(vault read --format=json aws/myapp/creds/assume_user)
echo "$res"

export AWS_ACCESS_KEY_ID=$(echo $res |jq -r .data.access_key)
export AWS_SECRET_ACCESS_KEY=$(echo $res |jq -r .data.secret_key)
export AWS_SESSION_TOKEN=$(echo $res |jq -r .data.security_token)
export AWS_DEFAULT_REGION=ap-northeast-1

aws sts get-caller-identity
aws iam list-users
aws s3 ls
aws ec2 describe-instances

# 動作確認後、破棄
vault lease lookup $(echo $res |jq -r .lease_id)
vault lease revoke $(echo $res |jq -r .lease_id)
```

### Policy 設定例

```hcl
# aws/myapp/ 以下の管理
path "aws/myapp/*" {
  capabilities = ["create", "read", "update", "list" , "delete"]
}
path "sys/leases/lookup/aws/myapp/creds/*" {
  capabilities = ["create", "update"]
}
path "sys/leases/revoke/aws/myapp/creds/*" {
  capabilities = [ "read","update"]
}

# aws secret aws/myapp/ の利用
## role一覧
path "aws/myapp/roles" {
  capabilities = ["list"]
}
## accesskey 発行
path "aws/myapp/creds/*" {
  capabilities = ["read"]
}
## aws secretのlookup, revoke
path "sys/leases/lookup/aws/myapp/creds/*" {
  capabilities = ["create", "update"]
}
path "sys/leases/revoke/aws/myapp/creds/*" {
  capabilities = [ "read","update"]
}

# my-roleのみ利用に限定
## accesskey 発行
path "aws/myapp/creds/my-role" {
  capabilities = ["read"]
}
## aws secretのlookup, revoke
path "sys/leases/lookup/aws/myapp/creds/my-role/*" {
  capabilities = ["create", "update"]
}
path "sys/leases/revoke/aws/myapp/creds/my-role/*" {
  capabilities = [ "read","update"]
}

# aws secret aws/xxxx/, aws/yyyy/ の利用(2階層で複数のsecretを利用)
## role一覧
path "aws/+/roles" {
  capabilities = ["list"]
}
## accesskey 発行
path "aws/+/creds/*" {
  capabilities = ["read"]
}
## aws secretのlookup, revoke
path "sys/leases/lookup/aws/+/creds/*" {
  capabilities = ["create", "update"]
}
path "sys/leases/revoke/aws/+/creds/*" {
  capabilities = [ "read","update"]
}
```

### Link

- [AWS Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/aws)
- [Dynamic Secrets](https://learn.hashicorp.com/tutorials/vault/getting-started-dynamic-secrets?in=vault/getting-started)
- [AWS Secrets Engine (API)](https://developer.hashicorp.com/vault/api-docs/secret/aws)

## cubbyhole

Token 保持者自身しか閲覧できない情報

```shell
test_token=$(vault token create -policy=default -format=json | jq -r ".auth.client_token")

# test_token 保持者として、cubbyholeに書き込み
VAULT_TOKEN=$test_token vault write cubbyhole/private mobile="123-456-7890"
# test_token 保持者は、cubbyholeの内容を閲覧可能
VAULT_TOKEN=$test_token vault list cubbyhole
VAULT_TOKEN=$test_token vault read cubbyhole/private mobile="123-456-7890"

# それ以外の者は、閲覧できない
vault list cubbyhole
vault read cubbyhole/private
```

# Auth

認証により、期限付き、一定の権限を持ったTokenを発行
以降はそのTokenを利用し、secret （kv-store、aws 一時ユーザーなど）の利用
利用が終わったら、Tokenを破棄する

認証により取得するTokenと、Root Token (init時発行、無期限) を混同しないように

## 認証設定の管理（共通）

```shell
# 現在のauth一覧
vault auth list
vault auth list -detailed

# auth 作成 ※Token認証はデフォルト設定のみ
vault auth enable userpass
# path 指定
vault auth enable -path userpass/local userpass

# デフォルト設定確認
vault read sys/auth/userpass/tune
# ユーザー認証時のデフォルトToken期間を修正
vault auth tune -default-lease-ttl=8h -max-lease-ttl 48h userpass/

# auth 削除 (pathで指定)
vault auth disable userpass/
```

## Token

一番基本的な認証方法
Token毎に適当なPolicyを割り当てて利用。用が済んだら破棄
※init時に発行された root token は、無期限かつ root policy がついている

他の認証方法を利用する場合でも、押さえたほうがよい
※どの認証を利用する場合でも、認証により発行されたTokenを利用する

### Tokenの発行

```shell
# 現在の設定チェック
vault read sys/auth/token/tune
# ※デフォルトでは  lease_ttl 768h (32日),service token など

# デフォルト設定の修正
vault write sys/auth/token/tune default_lease_ttl=8h max_lease_ttl=72h


# Token 生成
# 現在のTokenの子Tokenとして、同じPolicyが割り当てられる
# 子Token： 親Token権限の範囲内、期限切れや削除時に一緒に削除される
# root で発行すると、オプション未指定時は root tokenが発行されるため注意
vault token create

# 特定Policyを割り当てたToken生成
# 現Tokenに適用されたPolicyのみ指定可能  ※root は任意のPolicyを指定可
vault token create -policy=default
vault token create -policy=my-policy -policy=other-policy

# default policy をつけない
# 別途必要なPolicyをつけないと、vault token revoke -self すらできない
vault token create -no-default-policy

# 独立したTokenを発行  ※root のみ利用可能
# 親Tokenを削除しても影響を受けない
vault token create -orphan

# Token区別のために display-name 指定
vault token create -display-name "token-test-user" -policy=default

# meta情報を追加
vault token create -metadata "hostname = vault-test" -metadata "user = vault-user" -policy=default
```

### Tokenの確認

```shell
# 現在の利用中のToken情報確認
# policy, 有効期限、残り時間などの情報を確認可能
vault token lookup
# Token指定で確認
vault token lookup xxxxxxxxx
# accessor指定で確認
vault token lookup -accessor xxxxxxx

# 指定Tokenで、auth/token/lookup への権限状況の確認 (パスは任意)
vault token capabilities auth/token/create
vault token capabilities {任意のtoken} auth/token/lookup
```

### Tokenの削除

```shell
# Token 削除
vault token revoke -self

# TokenIDを指定してToken削除
vault token revoke xxxxxxxxx

# accessorを指定してToken削除
vault token revoke -accessor xxxxxxxxxxxxxxx

# 子Tokenは残したまま削除
vault token revoke -mode=orphan xxxxxxxxxxxxx

```

### Tokenの更新

Tokenの期限切れ前にrenewすれば、延長し続けられる。
ただし最大 `sys/auth/token/tune` の max_lease_ttl 値まで

```shell
# 有効期限指定を指定してToken発行
# 一時的な作業用途など、消し忘れてもすぐに消える時間にしておくとよい
vault token create -ttl=10m

# 期限を延長する (ttlの指定と同じ時間)
vault token renew
# 期限を延長する (incrementで指定した時間)
vault token renew -increment 5m
# renewを行った場合の最大期限指定
vault token create -ttl 30m -explicit-max-ttl 2h

# 発行、更新時の期限指定 ※root のみ利用可能
# renew 時は、 increment オプションが効かず、固定となる
vault token create -period=10m

# Tokenの利用回数を制限
vault token create -use-limit 10

```

### Tokenの管理

```shell
# Token の数をチェック
vault read sys/internal/counters/tokens

# token accessorsの一覧  ※root token のみ可能
vault list auth/token/accessors

# 特定のToken accessorの情報チェック
vault token lookup -accessor xxxxxxxxxxx

# 特定のToken を破棄
vault token revoke -accessor xxxxxxxxxxx

# Token認証用に発行されたTokenをまとめて破棄
vault token revoke -mode path auth/token/create
```

### Policy 設定例

```shell
# Token 発行
path "auth/token/create" {
  capabilities = [ "create", "update" ]
}

# Token 発行 sudo を付与で、" -orphan" オプション利用、任意のPolicy付与が可能など
path "auth/token/create" {
  capabilities = [ "create", "update", "sudo" ]
}

# 自身のToken管理 (Tokenチェック、権限チェック、更新、破棄)
# → default policy をつけるのが無難

# Token 管理 （Token利用状況チェック、作成、更新、削除など）
path "auth/token/*" {
  capabilities = ["create", "update", "read", "list" ]
}
```

### Link

- [Tokens](https://developer.hashicorp.com/vault/docs/concepts/tokens)
- [Tokens(Tutorial)](https://developer.hashicorp.com/vault/tutorials/tokens/tokens)
- [Token Auth Method (API)](https://developer.hashicorp.com/vault/api-docs/auth/token)

## userpass

userid,password での認証
user毎にPolicy割り当ての定義が可能
※グループ管理をおこなう場合はEntityを利用

### userpass認証の設定

```shell
# auth 作成
vault auth enable userpass
# path 指定
vault auth enable -path userpass/local userpass
# ユーザー認証時のデフォルトToken期間を修正
vault auth tune -default-lease-ttl=8h -max-lease-ttl 48h userpass


# 認証ユーザー一覧
vault list auth/userpass/users

# 認証ユーザー作成
vault write auth/userpass/users/mitchellh password=foo
# 認証ユーザー情報確認
vault read auth/userpass/users/mitchellh
# 認証時に割り当てられるPolicy追加
vault write auth/userpass/users/mitchellh policies=it_policy policies=security_policy

# ユーザー個別にTokenの制限追加
# 初期1h、renew時も最大1h、更新含めて最長4h
vault write auth/userpass/users/mitchellh token_ttl=1h token_max_ttl=1h token_explicit_max_ttl=4h
# 認証可能なIP範囲を限定
vault write auth/userpass/users/mitchellh token_bound_cidrs="10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1"
# ユーザーの削除
vault delete auth/userpass/users/mitchellh
```

### userpass の認証管理

```shell
# userpass 認証
vault login -method=userpass username=mitchellh
# path を指定、ユーザー名、パスワード指定
vault login -method=userpass -path=userpass/local username=mitchellh password=foo

# 特定ユーザーの認証で発行されたTokenを破棄
vault token revoke -mode path auth/userpass/login/mitchellh
# userpass で発行されたTokenをまとめて破棄
vault token revoke -mode path auth/userpass/login
```

※グループ設定はIdentityを使えばできる

### Policy 設定例

### Link

- [Userpass Auth Method](https://developer.hashicorp.com/vault/docs/auth/userpass)
- [Userpass Auth Method (HTTP API)](https://developer.hashicorp.com/vault/api-docs/auth/userpass)

## LDAP

LDAPサーバーに登録済みのユーザーを使って認証を行う。
LDAPユーザー毎、グループ毎でPolicy割り当ての定義が可能

### LDAP認証の設定

```shell
# auth作成
vault auth enable ldap
# path指定
vault auth enable -path=ldap/sample.local ldap

# デフォルトの設定
vault read sys/auth/ldap/tune
# デフォルト設定の修正
vault write sys/auth/ldap/tune default_lease_ttl=8h max_lease_ttl=72h
```

### LDAP認証 config設定

```shell
# ldap config チェック
vault read auth/ldap/config

# LDAP 接続設定
vault write auth/ldap/config url="ldaps://ldap.saitamanokusa.net"
vault write auth/ldap/config binddn="cn=readonly,dc=sample,dc=local"
vault write auth/ldap/config bindpass="readonly"
vault write auth/ldap/config starttls=true
vault write auth/ldap/config insecure_tls=true
# LDAPユーザー関連の設定
vault write auth/ldap/config userdn="dc=sample,dc=local"
vault write auth/ldap/config userattr="cn"
vault write auth/ldap/config userfilter="(&({{.UserAttr}}={{.Username}})(objectclass=person))"
# LDAPグループ関連の設定
vault write auth/ldap/config groupdn="dc=sample,dc=local"
vault write auth/ldap/config groupattr="cn"
vault write auth/ldap/config groupfilter="(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))"
```

上記設定ならば、下記ldapsearchコマンドで検索できるユーザー、グループで認証可能

```shell
# user検索
ldapsearch -x -H ldaps://ldap.saitamanokusa.net \
  -b dc=sample,dc=local -D "cn=readonly,dc=sample,dc=local" -w "readonly" \
  "(&(cn=user01)(objectclass=person))"

# group検索
ldapsearch -x -H ldaps://ldap.saitamanokusa.net \
  -b dc=sample,dc=local -D "cn=readonly,dc=sample,dc=local" -w "readonly" \
  "(|(memberUid=user01)(member=上記UserDN)(uniqueMember=上記UserDN))"
```

```shell
# その他
# Token 期限 初期8h、renew時も最大8h、更新含めて最長24hに指定
vault write auth/ldap/config token_ttl=8h token_max_ttl=8h token_explicit_max_ttl=24h
# ldap 認証で割り当てられるPolicy
vault write auth/ldap/config token_policies="ldap_token_policy"
# 認証が可能なIP範囲を限定
vault write auth/ldap/config token_bound_cidrs="10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1"
```

### LDAP認証 ユーザー・グループ設定

個別のLDAPユーザー、LDAPグループ毎に、割り当てるPolicyをカスタマイズする場合の設定
※この設定をしなくとも、認証および共通のPolicy割当ては可能

```shell
# LDAPユーザー user01 にPolicyを割当て
vault write auth/ldap/users/user01 policies=ldap_user_policy
# LDAPユーザー user02 にグループを割当て
vault write auth/ldap/users/user02 groups=security
# 設定を割り当てたユーザーの確認
vault list auth/ldap/users
vault read auth/ldap/users/user02
vault delete auth/ldap/users/user02


# グループ追加、グループ単位でPolicy割り当て
# 上記でLDAPユーザーに割り当てたグループ以外に、LDAPグループを対象とすることも可能。
# Group Filterで取得できるグループのAttribute(デフォルト CN)をグループ名として定義する。
vault write auth/ldap/groups/it policies=it_policy
vault write auth/ldap/groups/security policies=security_policy

# 設定を割り当てたグループの確認
vault list auth/ldap/groups
vault read auth/ldap/groups/security
vault delete auth/ldap/groups/security
```

### LDAP認証管理

```shell
# LDAP認証  ※username未指定だと現在のユーザー名が使われる
vault login -method=ldap
# ユーザー名指定
vault login -method=ldap username=user01
# path を指定、ユーザー名、パスワード指定
vault login -method=ldap -path=ldap/sample.local username=user01 password=pass
# Token確認、破棄
vault token lookup
vault token revoke -self

# 特定ユーザーの認証で発行されたTokenを破棄
vault token revoke -mode path auth/ldap/sample.local/login/eve
# LDAP認証で発行されたTokenをまとめて破棄
vault token revoke -mode path auth/ldap/sample.local/login
```

### Policy 設定例

### Link

- [LDAP auth method](https://developer.hashicorp.com/vault/docs/auth/ldap)
- [LDAP Auth Method (API)](https://developer.hashicorp.com/vault/api-docs/auth/ldap)

## AppRole

### AppRole認証の設定

```shell
# AppRole有効化
vault auth enable approle
# path指定
vault auth enable -path=approle/myapp approle
# デフォルトの設定
vault read sys/auth/approle/tune
# デフォルト設定の修正
vault write sys/auth/approle/tune default_lease_ttl=8h max_lease_ttl=72h
```

### Role設定

```shell
# roleを作成
# オプションなしで作る場合は -force が必要
vault write -force auth/approle/role/worker

# role の設定追加
vault write auth/approle/role/worker token_policies="approle_worker_policy"
vault write auth/approle/role/worker token_ttl=1h
vault write auth/approle/role/worker token_max_ttl=1h
vault write auth/approle/role/worker token_explicit_max_ttl=4h

# role 一覧
vault list auth/approle/role
# 特定Roleの設定
vault read auth/approle/role/worker
# role id の確認
vault read auth/approle/role/worker/role-id
# role id を分かりやすくカスタム値に変更
vault write auth/approle/role/worker/role-id role_id="worker_role"

# role削除
vault delete auth/approle/role/worker
```

### Secret設定

secret_idはパスワードに相当するため取り扱い注意。
secret_idは、作成時しか確認できない。
secretの設定項目は、作成時に一括で追加する。※後から編集できない

```shell
# secret 追加
vault write -force auth/approle/role/worker/secret-id

# secret に必要設定を追加したうえで作成
# AppRole認証を利用できるIP範囲制限、区別しやすいようにmetadataを追加
# ※secret は編集できないため、作成時に必要な設定を追加しておく
vault write auth/approle/role/worker/secret-id \
  cidr_list="10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1/32" \
  metadata="system=myApp,hostname=dev202301"

# secret id をカスタム値で作成することも可能（非推奨な手段）
vault write auth/approle/role/worker/custom-secret-id \
  secret_id=workder_secret_id  \
  cidr_list="10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1/32"

# 発行したsecret の一覧 (secret_id_accessor の一覧)
vault list auth/approle/role/worker/secret-id
# secret_id 指定でlookup
vault write auth/approle/role/worker/secret-id/lookup secret_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# secret_id_accessor 指定でlookup
vault write auth/approle/role/worker/secret-id-accessor/lookup secret_id_accessor=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# secret_id 指定で削除
vault write auth/approle/role/worker/secret-id/destroy secret_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# secret_id_accessor 指定で削除
vault write auth/approle/role/worker/secret-id-accessor/destroy secret_id_accessor=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

### AppRole認証管理

```shell
# AppRole 認証
role_id=worker_role
secret_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
vault write auth/approle/login role_id="$role_id" secret_id="$secret_id"

# AppRole 認証で発行されたTokenをまとめて破棄
vault token revoke -mode path auth/approle/login

# クリーンナップ
# アクセサーごとに、対応するトークンをチェック、存在しない場合はアクセサーを削除
# 不要なTokenが残っている場合、関連子リソース、cubbyholeなど含めて削除
vault write -force auth/approle/tidy/secret-id
```

### Policy 設定例

```hcl
# Mount the AppRole auth method
path "sys/auth/approle" {
  capabilities = [ "create", "read", "update", "delete", "sudo" ]
}

# Configure the AppRole auth method
path "sys/auth/approle/*" {
  capabilities = [ "create", "read", "update", "delete" ]
}

# Create and manage roles
path "auth/approle/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# Grant 'update' permission on the 'auth/approle/role/<role_name>/secret-id' path
path "auth/approle/role/+/secret-id" {
   capabilities = [ "update" ]
}
```

### Link

- [AppRole Auth Method](https://www.vaultproject.io/docs/auth/approle)
- [AppRole Auth Method (API)](https://developer.hashicorp.com/vault/api-docs/auth/approle)

## aws auth

IAM USERや、IAM Role、EC2の情報でvaultの認証を行う。
`~/.aws/config`の定義をしたPCや、IAM Roleを割り当てたEC2などから認証が可能。
ec2認証ならばAMIやEC2でも可能（動作未確認）

### AWS IAM User、Policy など準備

あらかじめAWSにてvault用のIAMユーザーを用意し、`accesskey`、`secretkey`を取得。
該当IAMユーザーに、必要なポリシーを付与する。
(EC2でvaultを稼働時は、IAM Roleへの割当てでも可)

ポリシー設定例（認証チェックおよび自身のAccessKey更新権限）

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "iam:GetInstanceProfile",
                "iam:GetUser",
                "iam:ListRoles",
                "iam:GetRole"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ManageOwnAccessKeys",
            "Effect": "Allow",
            "Action": [
                "iam:CreateAccessKey",
                "iam:DeleteAccessKey",
                "iam:GetAccessKeyLastUsed",
                "iam:GetUser",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        }
    ]
}
```

### AWS認証の設定

```shell
# auth作成
vault auth enable aws
# pathを指定してaws auth作成（以降のコマンド例はこちらを使用）
vault auth enable -path aws/my_account aws

# 認証チェック時に使用する接続情報追加
accesskey=xxxxxxxxxx
secretkey=xxxxxxxxxx
vault write auth/aws/my_account/config/client access_key=$accesskey secret_key=$secretkey

# iam role でPolicy付与している場合は forceオプション指定で追加できる
vault write -force auth/aws/my_account/config/client

# configに登録したaccesskey を更新
# accesskey更新後、利用できるようになるまで10秒程度かかるので注意
vault write -f auth/aws/my_account/config/rotate-root

# auth_typeにiamを使用する場合、headerにvaultサーバーのDNS名指定推奨  ※無くても認証はできるが、開発環境、本番環境などの区別がないため危険
vault write auth/aws/my_account/config/client iam_server_id_header_value="vault.saitamanokusa.net"

# 設定確認
vault read auth/aws/my_account/config/client

# デフォルトの設定
vault read sys/auth/aws/my_account/tune
# デフォルト設定の修正
vault write sys/auth/aws/my_account/tune default_lease_ttl=8h max_lease_ttl=72h


```

### AWS認証 role設定

```shell
# AWS認証を許可するIAM User, IAM Roleを、arn指定で定義

# IAM UserのARN指定で追加
vault_role_name="myuser"
iam_arn="arn:aws:iam::123456789012:user/myuser"
vault write auth/aws/my_account/role/$vault_role_name \
    auth_type=iam \
    bound_iam_principal_arn="$iam_arn"

# TokenのTTLや、割り当てられるPolicyを指定
vault write auth/aws/my_account/role/$vault_role_name \
    token_ttl=1h token_max_ttl=4h \
    policies=aws_token_policy

# 設定したroleの確認
vault list auth/aws/my_account/role
vault read auth/aws/my_account/role/$vault_role_name

# IAM RoleもARN指定で同じように追加できる（groupやpolicyのARNはNG）
vault_role_name="vault_auth_role"
iam_arn="arn:aws:iam::123456789012:role/vault_auth_role"
vault write auth/aws/my_account/role/$vault_role_name \
    auth_type=iam \
    bound_iam_principal_arn="$iam_arn"

# 該当AWSアカウント中の任意のIAM Userを許可する
# ワイルドカードは最後のみ可能（プレフィックスで一致）
vault_role_name="any_user"
iam_arn="arn:aws:iam::123456789012:user/*"
vault write auth/aws/my_account/role/$vault_role_name auth_type=iam bound_iam_principal_arn="$iam_arn"

# 指定AWSアカウント中の任意のIAM Roleを指定
vault_role_name="any_role"
iam_arn="arn:aws:iam::123456789012:role/*"
vault write auth/aws/my_account/role/$vault_role_name auth_type=iam bound_iam_principal_arn="$iam_arn"

vault write auth/aws/my_account/role/vault-role-for-aws-lambdarole \
    auth_type=iam \
    bound_iam_principal_arn=arn:aws:iam::123456789012:role/aws-lambdarole-for-vault-authmethod \
    policies=vault-policy-for-aws-ec2role

```

### AWS認証の認証管理

```shell
# （~/.aws/config 設定済み、もしくは IAM Role割当てがある前提で）
# あらかじめaws-cliの認証がとおることを確認
aws sts get-caller-identity

# path, role 指定でログイン
vault login -method=aws -path aws/my_account role=myuser
vault login -method=aws -path aws/my_account role=vault_auth_role

# header指定でログイン(iam認証時は推奨)
header="vault.saitamanokusa.net"
vault login -method=aws -path aws/my_account header_value=$header role=myuser

# aws/my_account で発行されたTokenをまとめて破棄
vault token revoke -mode path auth/aws/my_account/login
````

### Link

[AWS Auth Method](https://developer.hashicorp.com/vault/docs/auth/aws)

[Set up AWS Auth Method for HCP Vault](https://developer.hashicorp.com/vault/tutorials/cloud-ops/vault-auth-method-aws)

[AWS Auth Method (API)](https://developer.hashicorp.com/vault/api-docs/auth/aws)

## Identity

userpass, ldap, github など様々なログイン手段利用時でも、統一的にユーザー、グループへのポリシー管理などを行う
ユーザー認証を複数使い分けている場合に利用

※ここで割当てられるポリシーは、identity_policies として反映される

### Entity作成、管理

```shell
# 新規Entity作成
vault write identity/entity name="user01"
# Entity 確認
vault read identity/entity/name/user01
# EntityにPolicy割当て
vault write identity/entity/name/user01 policies=base policies=education

# Entity一覧
vault list /identity/entity/name
# Entity 削除
vault delete /identity/entity/name/user01
# 名前の変更はid 指定じゃないと上手くいかなかった
entity_id=$(vault read -format json /identity/entity/name/xxxxx |jq -r .data.id)
vault write /identity/entity/id/${entity_id} name=user01_ldap
```

### Entityに認証ユーザーを割当て

認証を行えば自動的にEntityが作成される。
既存のEntityを整理する手段と、新たな認証時に既存のEntity設定を反映させる手段を説明

```shell
# entity のマージ
# userpass用、ldap用など個別にEntityが作られている場合の対応
ldap_entity_id=$(vault read -format json /identity/entity/name/user01_ldap | jq -r .data.id)
userpass_entity_id=$(vault read -format json /identity/entity/name/user01_ldap | jq -r .data.id)
to_entity_id=$(vault read -format json /identity/entity/name/user01 | jq -r .data.id)
vault write /identity/entity/merge \
  from_entity_ids=$ldap_entity_id from_entity_ids=$userpass_entity_id to_entity_id=$to_entity_id


# Alias追加
# まだuserpass,ldap などのEntityが作られていない場合の対応

# userpass認証で、ユーザー名 user01用の設定を追加
accessor=$(vault auth list -format json | jq -r '.["userpass/"].accessor')
entity_id=$(vault read -format json /identity/entity/name/user01 | jq -r .data.id)
vault write identity/entity-alias name="user01" canonical_id=$entity_id mount_accessor=$accessor

# ldap認証で、ユーザー名 user01用の設定を追加
accessor=$(vault auth list -format json | jq -r '.["ldap/"].accessor')
vault write identity/entity-alias name="user01" canonical_id=$entity_id mount_accessor=$accessor

# alias 一覧
vault list /identity/entity-alias/id/

# 内容確認
vault read /identity/entity-alias/id/{alisas_id}
vault delete /identity/entity-alias/id/{alisas_id}
```

### Group

Entity（ユーザー単位）をさらにグループで管理する（内部グループ）
またはLDAPグループ等に対して、グループを割り当てる（外部グループ）

```shell
# Entity をグループ単位でPolicy管理など行えるように
entity_id=$(vault read -format json /identity/entity/name/user01 | jq -r .data.id)
# 内部グループ作成
vault write identity/group name="vault_users" type=internal
# 確認、必要設定の追加
vault read identity/group/name/vault_users
vault write identity/group/name/vault_users policies="common_policy"
vault write identity/group/name/vault_users member_entity_ids=$entity_id

# グループ一覧
vault list identity/group/name
# グループ削除
vault delete identity/group/name/vault_users

# 外部グループ
# LDAPのadminsグループを、Identityのldap_adminsグループに割り当てる
vault write identity/group name="ldap_admins" type="external" policies="ldap_admins_policy"
group_id=$(vault read -format json /identity/group/name/ldap_admins | jq -r .data.id)
accessor=$(vault auth list -format json | jq -r '.["ldap/"].accessor')
vault write identity/group-alias name="admins" mount_accessor=$accessor canonical_id=$group_id

# alias 一覧
vault list /identity/group-alias/id/
# 内容確認
vault read /identity/group-alias/id/{alisas_id}
vault delete /identity/group-alias/id/{alisas_id}
```

### Link

- [Identity](https://developer.hashicorp.com/vault/docs/concepts/identity)
- [Identity: Entities and Groups (Tutorial)](https://developer.hashicorp.com/vault/tutorials/auth-methods/identity#create-an-external-group)
- [Identity Secrets Engine (API)](https://developer.hashicorp.com/vault/api-docs/secret/identity)

# Policy

## policy関連の操作

```shell
# policy 追加
# ヒアドキュメントでPolicy内容を指定
vault policy write kv_write_policy -<<EOF
# kv write policy
path "kv/myapp/*" {
  capabilities = [ "read", "list", "update", "delete"]
}
EOF

# あらかじめ .hcl ファイルを用意し、書き込む
vault policy write kv_read_policy kv_read_policy.hcl

## policy 一覧
vault policy list
# policy 中身確認
vault policy read kv_write_policy
# 削除
vault policy delete kv_read_policy


# 操作に必要なPolicyチェック  (-output-policy オプション)
vault kv list -output-policy kv/myapp
vault kv get -output-policy kv/myapp/sw-010
vault kv put -output-policy kv/myapp/sw-010 HostName="sw-010"

# 認証Tokenより、指定pathに割り振られた権限をチェック
vault token capabilities kv/myapp
```

## policy記述例

```shell
# policy 作成、管理
path "sys/policies/acl/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# + で1つのパスセグメントのみ対応 * では何階層でも対象となる
path "kv/myapp/+" {
  capabilities = ["read"]
}

# パラメータを利用したpath指定 {{ }} で囲うことで、動的path指定が可能
path "kv-v2/myapp/data/{{identity.entity.id}}/*" {
  capabilities = ["create", "update", "patch", "read", "delete"]
}
# 他にも
# https://developer.hashicorp.com/vault/docs/concepts/policies#templated-policies

```

- 設定できる種類 create, read, update, patch, delete, list, sudo, deny, sudo
  sudo は root制限機能の許可 → root権限必要な操作は [Root protected API endpoints](https://developer.hashicorp.com/vault/tutorials/policies/policies#root-protected-api-endpoints)
- 同一階層の場合は、権限は足し算される ※Denyは優先される
- 下位に別権限のPolicyを当てた場合、下位はそのPolicyで上書きされる

## Link

- [Policies](https://developer.hashicorp.com/vault/docs/concepts/policies)
- [Vault Policies (Tutorial)](https://developer.hashicorp.com/vault/tutorials/policies/policies)
- [Write a Policy using Audit Logs](https://developer.hashicorp.com/vault/tutorials/policies/write-a-policy-using-audit-logs)

# 管理

## root token 作成

初期のinit時以外で、root token を作成する方法

手段１．Root Tokenを使用して、通常のToken発行操作

```shell
# root token、または親がroot tokenでsudo権限があれば可能
vault token create --format=json -policy=root
```

手段２・unsealkeyを使って生成

unseal key  (auto-unseal利用時は recovery key)があれば、root token を追加作成できる
※BestPracticeは 初期設定後、RootToken削除であるため、必要時に再生成する用途？
※認証できなくとも生成でき、RootTokenを取得できた

```shell
# One Time Password生成
$ otp=$(vault operator generate-root -generate-otp)

# generate-root プロセス開始(OTPを指定)
$ vault operator generate-root -init -otp $otp

# unsealkeyもしくはrecoverykeyを使用して開封(OTPを指定)
# 指定回数のUnsealでEncoded Tokenが出力される
$ vault operator generate-root -otp $otp

Nonce            xxxxx
Started          true
Progress         3/3
Complete         true
Encoded Token    xxxxxxxxxxxxxxxxx

# デコードで使用できるtokenが出力される
vault operator generate-root -decode "xxxxxxxxxxxxxxxxx" -otp $otp

# 途中で中断したい場合
vault operator generate-root -cancel


# 最初のOTP生成、Initの処理は、OTPを指定しなければ、一度に実行される
vault operator generate-root -init
A One-Time-Password has been generated for you and is shown in the OTP field.
You will need this value to decode the resulting root token, so keep it safe.
Nonce         e963e399-26c0-b237-50c3-1185f3a5e6a4
Started       true
Progress      0/2
Complete      false
OTP           FZeumLmmSaHyB0gxAf7bdWRcxQik
OTP Length    28

```

[Generate Root Tokens Using Unseal Keys](https://developer.hashicorp.com/vault/tutorials/operations/generate-root)

## rekey

unseal key や、recovery key の変更を行う。
※例えば下記の場合に、unseal key 変更が必要となる

- unseal 権限者の退職  (unseal key を分担して所有した場合)
- unseasl keyの共有数、しきい値の変更
- 定期的に unseal key を更新する運用

※ unseal / recovery key は 下記用途で使う

- auto-unseal のトリガー
- Rekey
- Root token generation

```shell
# rekey の処理開始（unseal key を更新）
vault operator rekey -init
vault operator rekey -init -key-shares 5 -key-threshold 2

# unseal の回数分rekeyの操作を行うと、新たなunseal key が生成される
vault operator rekey
Unseal Key (will be hidden): unseal key を入力

# 途中でやめる場合
vault operator rekey -cancel

```

```shell
# auto-unseal 環境では、-target recovery オプションを指定する
# rekey の処理開始（recorery key を更新）
vault operator rekey -init -target recovery
# キーの数を指定
vault operator rekey -init -key-shares 5 -key-threshold 2 -target recovery

# unseal の回数分rekeyの操作を行うと、新たなunseal key が生成される
vault operator rekey -target recovery
Unseal Key (will be hidden): recovery key を入力

# 途中でやめる場合
vault operator rekey -target recovery -cancel
```

[Rekeying & Rotating Vault](https://learn.hashicorp.com/tutorials/vault/rekeying-and-rotating)

## unseal - auto-unseal 切り替え

通常のunseal利用環境を、auto-unseal利用に切り替え
またはauto-unseal利用環境を、通常のunseal利用に切り替え

---

auto-unseal から 通常seal への切り替え

```shell
# /etc/vault.d/vault.hcl にて、seal ブロックに、disabled = "true" を登録
# （省略）
# AWS KMS auto unseal
seal "awskms" {
  region = "ap-northeast-1"
  kms_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  disabled = "true"
}
# （省略）

sudo systemctl restart vault
# -migrate オプションを指定して、必要回数 unseal 操作
vault operator unseal -migrate
（recovery key を入力）

# 次回以降は、通常のunseal に切り替わる  ※recovery keyがunseal keyに置き換わる
sudo systemctl restart vault
vault status

# 以降は、/etc/vault.d/vault.hcl にて、seal ブロックは消しても問題ない
```

unseal から auto-unseal への切り替え

```shell
# /etc/vault.d/vault.hcl にて、seal ブロックで auto-unseal の設定を追加
# （省略）
# AWS KMS auto unseal
seal "awskms" {
  region = "ap-northeast-1"
  kms_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
# （省略）

sudo systemctl restart vault
# -migrate オプションを指定して、必要回数 unseal 操作
vault operator unseal -migrate
（recovery key を入力）

# 次回以降は、auto-unseal に切り替わる  ※unseal keyがrecovery keyに置き換わる
sudo systemctl restart vault
vault status
```

[Seal/Unseal](https://developer.hashicorp.com/vault/docs/concepts/seal)