Vault

Vaultにおけるパスベースのルーティング: マウントとAPI構造を読み解く

2026-04-19
NicheeLab編集部

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パラメータを付与可能)というパターンが基本です。

  • 全APIは /v1/ をプレフィックスに持つ
  • 最長一致の前方一致でマウントを決定(例: payments/ と payments/internal/ があれば後者が優先)
  • 予約パス: sys/, auth/, identity/ はユーザマウントと衝突しない
  • LISTメソッドが使えない環境では GET ?list=true を利用可能
  • パス末尾のスラッシュ有無は原則どちらも許容だが、統一するのが無難
パスタイプ解決先認可の基点
シークレットエンジン/v1/secret/data/appマウント secret/ のKV v2path "secret/data/*"
認証メソッド/v1/auth/approle/loginauth/approle/ のloginpath "auth/approle/login"
システム管理/v1/sys/mountsマウント一覧の管理APIpath "sys/mounts"
アイデンティティ/v1/identity/entityEntity管理APIpath "identity/*"

Vaultのルーティング解決(概念図)

Client/v1/<path>Routersys/*auth/*<mounts>secret/KV v2data/, metadata/payments/KV v1keys...最長一致でマッチ: /v1/payments/internal/* は payments/internal/ を優先

基本の確認: マウントテーブルとルーティングの把握

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 .

シークレットエンジンのマウント設計(KV v1/v2とTransit)

マウント名はAPIパスそのものになるため、環境や領域を表す語彙を事前に決め、将来の拡張や移行を見据えた階層を選びます。特にKV v2は data/ と metadata/ のサブパスを持つ点が重要で、v1とは互換ではありません。

Transitは暗号化サービスであり、保存型のKVとはAPIも責務も異なります。読み替えを試みるとパスも権限も不一致になりやすいため、用途ごとに別マウントと別ポリシーを割り当てます。

  • KV v2はバージョニング対応。読み書きは secret/data/<name>、メタは secret/metadata/<name>
  • KV v1は単純で secret/<name> に対して読書き
  • Transitは鍵名に対して encrypt/<key>, decrypt/<key> を呼ぶ
  • 移行を見込む場合、業務境界/環境/機能でマウントを分ける(例: app/ と platform/)
  • 同名キーの衝突を避けるため、アプリケーション名を第1セグメントに含めると良い
エンジンデータパス例バージョニング主な補助パス
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 .

認証メソッドのパスとloginの扱い

認証メソッドは auth/<method>/ にマウントされ、トークン発行の入口は login エンドポイントです。アプリ側はloginでVaultトークンを取得し、その後はシークレットエンジンのパスに対して通常のAPIを呼びます。

同じメソッドでもマウントパス名を変えれば併用可能です(例: auth/approle/ と auth/approle-ci/)。パスが変わればlogin先も変わるため、クライアント設定とポリシーの両方でマウント名を一致させる必要があります。

  • AppRoleのloginは auth/approle/login(role_id と secret_id を送る)
  • Kubernetesのloginは auth/kubernetes/login(JWTとrole)
  • Userpassは auth/userpass/login/<username>(パスにユーザ名)
  • OIDCはブラウザフローで callback など追加パスを使用
  • マウント名を変えたら必ずクライアント設定も更新する
メソッドloginパス主なリクエスト項目備考
AppRole/v1/auth/approle/loginrole_id, secret_idマウント別名に注意(例: approle-ci)
Kubernetes/v1/auth/kubernetes/loginjwt, roleK8s 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 .

システムAPIとメタデータ: sys/以下の使い分け

sys/ はVaultの管理系API群で、マウント・認証メソッドの有効化や設定、ヘルスチェック、ポリシー、トークン検査などを担います。アプリケーションコードから直接呼ぶことは少なく、運用・自動化(TerraformやCI)で多用します。

権限は強力なため、必要最小限のパスに限定します。特に sys/mounts/* と sys/auth/* は管理者ロールのみに付与し、アプリには与えないのが基本です。

  • sys/mounts: シークレットエンジンの管理(有効化、tune、無効化)
  • sys/auth: 認証メソッドの管理
  • sys/health: ヘルスチェック(read-only)
  • sys/capabilities[-self]: トークンの権限確認
  • リース関連は sys/leases で参照・破棄
エンドポイント用途代表的な動詞注意点
/v1/sys/mountsマウント一覧・作成GET, POST作成時にtypeを指定
/v1/sys/mounts/<path>/tuneチューニング(説明・バージョン数など)POSTKV v2のmax_versions等
/v1/sys/auth認証メソッド管理GET, POSTメソッドtypeとパスを一致させる
/v1/sys/healthヘルスチェックGETUI/LoadBalancerのヘルスに使用
/v1/sys/capabilities-self自身の権限確認POSTポリシーデバッグに有用

sys/ APIの役割配置

Operators / Automation/v1/sys/*管理プレーンmountsauthpolicy ...sys/* は管理プレーン。アプリは通常 /v1/<mount>/* のデータプレーンを利用

典型的な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の取り扱いも区別しましょう。

ルーティングは最長一致のため、広い許可と狭い拒否が交差する設計は複雑さを増やします。原則として必要な範囲にのみ陽に許可し、不要なワイルドカードは避けます。

  • KV v2の読み取り: path "secret/data/app/*" に read を付与
  • キー一覧の必要があれば path "secret/metadata/app" に list を付与
  • 書き込みは data/ に create, update が必要
  • バージョン完全削除は destroy/ に delete が必要(権限は慎重に)
  • sys/系は原則アプリには付与しない
用途対象パス例必要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になりました。最も可能性が高い原因はどれですか。

  1. KV v2では data/ サブパスを経由せずに読み取ろうとしている
  2. トークンにreadではなくlistのみが付与されている
  3. sys/mountsが無効化されているため
  4. auth/メソッドが未有効化のため

正解: 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が必要です。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Vault

Vault のコア概念を最短距離で理解する:Secret / Auth / Policy / Token

HashiCorp Vault Associate レベルで押さえるべきコア概念(Secret Engine、Auth ...

Vault

Vault Operations Professional: 上位資格としての範囲を実務目線で押さえる

HashiCorp Vault Operations Professional(Ops Pro)の出題範囲を、Assoc...

Vault

Vaultにおけるパスベースのルーティング: マウントとAPI構造を読み解く

HashiCorp Vaultのパスベースのルーティングを、マウント設計とAPIパスの観点から整理。Associateレ...

Vault

Vault Tokens の基礎: 認証の起点となる概念

HashiCorp Vault におけるトークンの役割、種類、ライフサイクル、ポリシー連携、設計パターンをAssocia...

Vault

Vault のトークン種類を正しく使い分ける: service / batch 実践

HashiCorp Vault Associate 向けの試験対策と実務運用を両立させた、service トークンと b...

Vaultの記事一覧 (101件)
© 2026 NicheeLab All rights reserved.