VaultはHTTPパスで全てを表現します。シークレットエンジンや認証メソッドは「マウント」され、最長一致の前方一致でルーティングされます。パスの設計を誤ると認可や互換性でつまずくため、基本の型を正しく押さえることが重要です。
本稿では、パス解決の原理、KV v1/v2の違い、認証メソッドのloginパス、sys/の管理系API、そしてポリシーでのパス指定の要点を、試験でも頻出の落とし穴とあわせて整理します。
VaultのHTTP APIは /v1/ 配下に集約され、先頭のセグメントで大きく3系統に分かれます。sys/ は管理系、auth/ は認証メソッド、その他はユーザがマウントしたシークレットエンジン等です。実際の処理は、要求パスとマウントテーブルを照合する最長一致の前方一致で解決されます。
同じパスでもエンジンの種類により下位のサブパス構造が異なります。例えばKV v2では data/ と metadata/ サブパスを使う一方、Transitは encrypt/ や decrypt/ を使います。HTTP動詞は、readはGET、書き込みはPOST、一覧はLIST(またはGETにlist=trueパラメータを付与可能)というパターンが基本です。
| パスタイプ | 例 | 解決先 | 認可の基点 |
|---|---|---|---|
| シークレットエンジン | /v1/secret/data/app | マウント secret/ のKV v2 | path "secret/data/*" |
| 認証メソッド | /v1/auth/approle/login | auth/approle/ のlogin | path "auth/approle/login" |
| システム管理 | /v1/sys/mounts | マウント一覧の管理API | path "sys/mounts" |
| アイデンティティ | /v1/identity/entity | Entity管理API | path "identity/*" |
Vaultのルーティング解決(概念図)
基本の確認: マウントテーブルとルーティングの把握
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=<root-or-suitable-token>
# マウント一覧
curl -sH "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/sys/mounts | jq .
# LISTが通らない場合の一覧取得(例: KV v2のトップ階層)
curl -sH "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/secret/metadata?list=true" | jq .マウント名はAPIパスそのものになるため、環境や領域を表す語彙を事前に決め、将来の拡張や移行を見据えた階層を選びます。特にKV v2は data/ と metadata/ のサブパスを持つ点が重要で、v1とは互換ではありません。
Transitは暗号化サービスであり、保存型のKVとはAPIも責務も異なります。読み替えを試みるとパスも権限も不一致になりやすいため、用途ごとに別マウントと別ポリシーを割り当てます。
| エンジン | データパス例 | バージョニング | 主な補助パス |
|---|---|---|---|
| KV v1 | /v1/kv/app/config | なし | n/a |
| KV v2 | /v1/secret/data/app/config | あり(version指定可) | /v1/secret/metadata/app/config, /v1/secret/destroy/... |
| Transit | /v1/transit/encrypt/orders | 対象外 | /v1/transit/decrypt/<key>, /v1/transit/rotate/<key> |
KV v2の下位パス構造
secret/ (mount)
|
+-- data/<name> (値の読み書き: GET/POST)
+-- metadata/<name> (メタ情報・バージョン管理)
+-- destroy/<name> (特定versionの完全削除)
+-- delete/<name> (論理削除: version無効化)
KV v2をsecret/にマウントして読み書きする
# KV v2を有効化(既にあれば不要)
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-d '{"type":"kv","options":{"version":"2"}}' \
$VAULT_ADDR/v1/sys/mounts/secret
# 書き込み(KV v2は data/ サブパス)
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":{"username":"app","password":"s3cr3t"}}' \
$VAULT_ADDR/v1/secret/data/app/config | jq .
# 読み取り(最新版)
curl -sH "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/secret/data/app/config | jq .
# バージョン指定の読み取り(例: version=2)
curl -sH "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/secret/data/app/config?version=2" | jq .認証メソッドは auth/<method>/ にマウントされ、トークン発行の入口は login エンドポイントです。アプリ側はloginでVaultトークンを取得し、その後はシークレットエンジンのパスに対して通常のAPIを呼びます。
同じメソッドでもマウントパス名を変えれば併用可能です(例: auth/approle/ と auth/approle-ci/)。パスが変わればlogin先も変わるため、クライアント設定とポリシーの両方でマウント名を一致させる必要があります。
| メソッド | loginパス | 主なリクエスト項目 | 備考 |
|---|---|---|---|
| AppRole | /v1/auth/approle/login | role_id, secret_id | マウント別名に注意(例: approle-ci) |
| Kubernetes | /v1/auth/kubernetes/login | jwt, role | K8s SA JWTとロール名の対応が必要 |
| Userpass | /v1/auth/userpass/login/<user> | password | ユーザ名はパス、PWはボディ |
認証からシークレット取得までの流れ
App -> POST /v1/auth/<method>/login -> Token
Token -> GET /v1/<mount>/... -> Secret
^ |
|---- Policy ----------|
AppRoleでのloginと続く読み取りの例
# AppRoleでlogin
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"role_id":"<ROLE_ID>","secret_id":"<SECRET_ID>"}' \
$VAULT_ADDR/v1/auth/approle/login | jq .
# 取得した client_token を使ってKV v2を読む
APP_TOKEN=<client_token_from_response>
curl -sH "X-Vault-Token: $APP_TOKEN" \
$VAULT_ADDR/v1/secret/data/app/config | jq .sys/ はVaultの管理系API群で、マウント・認証メソッドの有効化や設定、ヘルスチェック、ポリシー、トークン検査などを担います。アプリケーションコードから直接呼ぶことは少なく、運用・自動化(TerraformやCI)で多用します。
権限は強力なため、必要最小限のパスに限定します。特に sys/mounts/* と sys/auth/* は管理者ロールのみに付与し、アプリには与えないのが基本です。
| エンドポイント | 用途 | 代表的な動詞 | 注意点 |
|---|---|---|---|
| /v1/sys/mounts | マウント一覧・作成 | GET, POST | 作成時にtypeを指定 |
| /v1/sys/mounts/<path>/tune | チューニング(説明・バージョン数など) | POST | KV v2のmax_versions等 |
| /v1/sys/auth | 認証メソッド管理 | GET, POST | メソッドtypeとパスを一致させる |
| /v1/sys/health | ヘルスチェック | GET | UI/LoadBalancerのヘルスに使用 |
| /v1/sys/capabilities-self | 自身の権限確認 | POST | ポリシーデバッグに有用 |
sys/ APIの役割配置
典型的なsys/操作
# Transitエンジンを有効化
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"transit"}' \
$VAULT_ADDR/v1/sys/mounts/transit
# KV v2のmax_versionsを10に設定
data='{"options":{"version":"2"},"description":"App secrets","max_versions":10}'
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d "$data" \
$VAULT_ADDR/v1/sys/mounts/secret/tune
# 自トークンの権限を確認
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"paths":["secret/data/app/*","sys/mounts"]}' \
$VAULT_ADDR/v1/sys/capabilities-self | jq .VaultのACLポリシーはパス単位でcapabilitiesを付与します。KV v2では data/ と metadata/ を別々に扱うため、readだけ許可したい場合は少なくとも data/ と metadata/ のlistを検討する必要があります。destroy/deleteの取り扱いも区別しましょう。
ルーティングは最長一致のため、広い許可と狭い拒否が交差する設計は複雑さを増やします。原則として必要な範囲にのみ陽に許可し、不要なワイルドカードは避けます。
| 用途 | 対象パス例 | 必要capabilities | 備考 |
|---|---|---|---|
| KV v2 読み取りのみ | secret/data/app/* | read | 一覧が必要なら metadata に list 追加 |
| KV v2 書き込み | secret/data/app/* | create, update | 初回作成はcreate、更新はupdate |
| KV v2 論理削除 | secret/delete/app/* | update | 指定versionを無効化 |
| KV v2 物理削除 | secret/destroy/app/* | delete | 復元不可、最小権限を徹底 |
リクエストの評価とポリシー適用
Request: GET /v1/secret/data/app/config
|
v
[ポリシー集合]
- path "secret/data/app/*" { capabilities = ["read"] }
- path "secret/metadata/*" { capabilities = ["list"] }
|
v
判定: 許可(readが一致)最小権限のポリシー例と検証
# ポリシー定義(HCL)
cat > app-readonly.hcl <<'EOF'
path "secret/data/app/*" {
capabilities = ["read"]
}
path "secret/metadata/app" {
capabilities = ["list"]
}
EOF
# ポリシー作成
curl -sX PUT -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d @- $VAULT_ADDR/v1/sys/policies/acl/app-readonly <<'JSON'
{"policy": "$(sed 's/"/\\"/g' app-readonly.hcl)"}
JSON
# 自トークンのcapabilitiesを自己診断
curl -sX POST -H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"paths":["secret/data/app/config","secret/metadata/app"]}' \
$VAULT_ADDR/v1/sys/capabilities-self | jq .Associate
問題 1
KV v2を secret/ にマウントしている環境で、アプリが /v1/secret/app/config にGETでアクセスしたところ404になりました。最も可能性が高い原因はどれですか。
正解: A
KV v2の読み取りは /v1/<mount>/data/<name> を使います。/v1/secret/app/config はKV v1の形であり、v2では404になります。適切なパスは /v1/secret/data/app/config です。
マウント名の変更は安全に行えますか?
稼働中のアプリに影響するため計画的に行ってください。一般的には新しいマウントを用意してデータ移行(例: kv migrate ツールや読み書きの二重化)後に切替えます。移行中は両方のパスを許容するポリシーを一時的に付与する方法が安全です。
LISTメソッドがプロキシで拒否されます。どうすればよいですか?
GETにクエリパラメータ list=true を付与する代替が用意されています。例: /v1/secret/metadata?list=true。応答形式はLISTと同等です。
KV v2のread権限だけを付けたのにアプリが一覧を取得できません。
KV v2の一覧は metadata/ に対するlistが必要です。例として path "secret/metadata/app" に capabilities=["list"] を追加してください。読み取り対象そのものには path "secret/data/app/*" のreadが必要です。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Vault のコア概念を最短距離で理解する:Secret / Auth / Policy / Token
HashiCorp Vault Associate レベルで押さえるべきコア概念(Secret Engine、Auth ...
Vault Operations Professional: 上位資格としての範囲を実務目線で押さえる
HashiCorp Vault Operations Professional(Ops Pro)の出題範囲を、Assoc...
Vaultにおけるパスベースのルーティング: マウントとAPI構造を読み解く
HashiCorp Vaultのパスベースのルーティングを、マウント設計とAPIパスの観点から整理。Associateレ...
Vault Tokens の基礎: 認証の起点となる概念
HashiCorp Vault におけるトークンの役割、種類、ライフサイクル、ポリシー連携、設計パターンをAssocia...
Vault のトークン種類を正しく使い分ける: service / batch 実践
HashiCorp Vault Associate 向けの試験対策と実務運用を両立させた、service トークンと b...