データベースのパスワードや外部APIのキーを、いまも .env ファイルやソースコードに直書きしていないでしょうか。HashiCorp Vault は、シークレットを一元管理し、暗号化して保存しながらアプリには短命のトークンで渡すための専用サーバーです。漏れたら困る値をサーバーのあちこちに散らさず、1か所で厳重に管理できます。
本記事では Ubuntu 24.04 LTS 上に HashiCorp Vault v2.0.2 を file ストレージ構成(本番に近い形)で実際に構築し、初期化(init)・解錠(unseal)から、KVシークレットの保存、ポリシーによる権限制御、AppRole 認証でのアプリ連携までを Docker コンテナで動かして検証しました。コマンドの実出力と Web UI の実画面をそのまま掲載します。
この記事のポイント
- Vault は起動直後は「封印(sealed)」状態で、生成された5本のアンシール鍵のうちしきい値の3本を入力するまでデータを復号できない
- インストールは Docker イメージ(
hashicorp/vault)でも公式 apt リポジトリでも可能。今回はどちらもv2.0.2だった - KV v2 エンジンは値を上書きせず
versionを増やす。古いパスワードにも戻せる - 本番アプリには root トークンを置かず、
AppRoleで TTL付きの短命トークンを発行して渡す - 本番では TLS 有効化・auto-unseal・監査ログを必ず併用する(検証では TLS を無効化)
目次
- HashiCorp Vault とは:なぜシークレット専用サーバーが必要か
- 前提環境
- Vault のインストール(Docker と apt)
- サーバーの起動・初期化・解錠
- Web UI にログインする
- KV v2 でシークレットを保存・取得する
- ポリシーで最小権限を設定する
- AppRole でアプリから安全にアクセスする
- 本番運用のチェックリスト
- よくあるエラーと解決策
- まとめ
HashiCorp Vault とは:なぜシークレット専用サーバーが必要か
Vault は HashiCorp(Terraform などで有名)が開発するシークレット管理ツールです。データベース認証情報・APIキー・証明書といった「漏れたら困る値」を暗号化して一元管理し、アクセスを認証・認可・監査します。
最大の特徴が「封印(seal)」という仕組みです。Vault はデータをすべて暗号化して保存しますが、その復号に使うキー自体も、起動しただけでは使えない状態(封印)になっています。封印を解く(unseal)には、初期化時に分割された複数の鍵をそろえる必要があります。

つまり、サーバーが盗まれてディスクごと持ち出されても、アンシール鍵がそろわなければ中身は開けません。鍵を複数人に分散して配ることが、そのままセキュリティになる設計です。
注意
本記事のコマンドは Ubuntu 24.04 LTS(Docker公式イメージ ubuntu:24.04 / arm64)と hashicorp/vault:latest(v2.0.2)で検証しています。検証の都合上 TLS を無効化していますが、本番では必ず TLS を有効化してください(後述)。
前提環境
- OS: Ubuntu 24.04 LTS(
ubuntu:24.04Docker イメージ、2026-06-14 実測) - Vault: v2.0.2(
hashicorp/vault:latest/ 2026-06-04 ビルド) - ストレージ: file バックエンド(単一ノード。本番の最小構成に相当)
- Docker がインストールされていること(VPS なら
apt install docker.io)
Vault のインストール(Docker と apt)
Vault の導入には2つの王道があります。コンテナで動かすなら公式 Docker イメージ、ホストに直接入れるなら HashiCorp 公式 apt リポジトリです。実際に両方を試したところ、どちらも同じ v2.0.2 でした。
$ docker run –rm hashicorp/vault:latest version
Vault v2.0.2 (a71d5add7ef4…), built 2026-06-04T13:18:11Z
# ② Ubuntu 24.04 に公式 apt リポジトリを追加
$ wget -qO- https://apt.releases.hashicorp.com/gpg \
| gpg –dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo “deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main” \
| sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt-get update && apt-cache policy vault
vault:
Installed: (none)
Candidate: 2.0.2-1
2.0.2-1 / 2.0.1-1 / 1.21.4-1 … 1.7.7(過去版もすべて提供)
$ sudo apt-get install -y vault && vault version
Vault TLS key and self-signed certificate have been generated in ‘/opt/vault/tls’.
Vault v2.0.2 (a71d5add7ef4…), built 2026-06-04T13:18:11Z

正直、ここで少し驚いたのが apt リポジトリのバージョンの豊富さです。1.7.7 から最新の 2.0.2 まで全バージョンが並んでおり、バージョン固定もしやすくなっています。apt 版はインストール時に /opt/vault/tls へ自己署名証明書まで自動生成してくれるのも親切です。
サーバーの起動・初期化・解錠
ここが Vault でいちばん独特な部分です。サーバーを起動しても、すぐには使えません。初期化(init)して解錠(unseal)するまでは封印状態です。まず file ストレージを使う最小の本番設定を書きます。
disable_mlock = true
storage “file” {
path = “/vault/file”
}
listener “tcp” {
address = “0.0.0.0:8200”
tls_disable = 1 # ← 検証用。本番では必ず TLS を有効に
}
api_addr = “http://127.0.0.1:8200”
この設定でサーバーを起動し(vault server -config=/vault/config/vault.hcl)、別のターミナルから初期化と解錠を行います。
Unseal Key 1: gPXCJWXkbjb9fGhX**********************
Unseal Key 2: v8fYpcVoEdgVLB+X**********************
Unseal Key 3 〜 5: …(合計5本が表示される)
Initial Root Token: hvs.Tf8s********************
Vault initialized with 5 key shares and a key threshold of 3.
$ vault status # 初期化直後は封印されている
Sealed true Total Shares 5 Threshold 3
$ vault operator unseal <Key 1> # Unseal Progress 1/3
$ vault operator unseal <Key 2> # Unseal Progress 2/3
$ vault operator unseal <Key 3> # しきい値3に到達 → 解錠
$ vault status
Sealed false
Storage Type file
Cluster Name vault-cluster-3ab9b456
Version 2.0.2

実際に試すと、鍵を1本・2本入れても Sealed: true のままで、3本目を入れた瞬間に解錠されました。1〜2本では絶対に開きません。これが Shamir の秘密分散で、鍵を別々の管理者に配れば1人では開けられない運用にできます。
注意:再起動するたびに unseal が必要
Vault はサーバーを再起動すると再び封印されます。アンシール鍵と Initial Root Token は init のときに一度しか表示されません。安全な場所(パスワードマネージャーや別管理者の手元)に必ず控えてください。失うと復旧できません。
Web UI にログインする
設定で ui = true にしているので、ブラウザから http://<サーバーIP>:8200 にアクセスすると Web UI が使えます。認証方式に「Token」を選び、先ほどの Root Token を貼り付けてサインインします。

ログインすると、ダッシュボードに Vault v2.0.2、有効なシークレットエンジン、そして Cluster information(Storage type が file、TLS が Disabled になっている点に注目)が表示されます。

KV v2 でシークレットを保存・取得する
シークレットを保存する最も基本的な場所が KV(Key-Value)シークレットエンジンです。バージョン2を有効化すると、値の変更履歴が残ります。
Success! Enabled the kv secrets engine at: secret/
$ vault kv put secret/myapp/db username=appuser password=S3cr3t-Pass-v1 host=10.0.0.5 port=5432
version 1
$ vault kv put secret/myapp/db username=appuser password=R0tated-Pass-v2 host=10.0.0.5 port=5432
version 2 ← 上書きではなく新バージョンとして追加
$ vault kv get -version=1 secret/myapp/db # 古い値も取り出せる
password S3cr3t-Pass-v1
$ vault kv get secret/myapp/db # 既定は最新(v2)
password R0tated-Pass-v2

同じパスに put しても上書きされず、version が 1 → 2 と増えました。パスワードをローテーションしたあとでも、-version=1 を付ければ以前の値(S3cr3t-Pass-v1)をそのまま取り出せます。誤って壊しても直前に戻せるのが KV v2 の安心感です。
Web UI からも同じシークレットを確認できます。secret/ エンジンを開くと myapp/ フォルダが見え、その中の db を開くと現在のバージョンや API パスが表示されます。


詳細画面では Current version: 2 と、CLI/API から参照するときのパス(/v1/secret/data/myapp/db)が一目で分かります。コマンドが苦手なメンバーでも、この画面なら値の確認やローテーションができます。
ポリシーで最小権限を設定する
Vault は「デフォルト拒否」のシステムです。明示的に許可していないパスは、たとえ存在しても読めません。アプリには「自分の領域だけ読める」最小権限のポリシーを与えます。
path “secret/data/myapp/*” {
capabilities = [“read”, “list”]
}
EOF
Success! Uploaded policy: app-ro
# このポリシーを持つトークンの「能力」を確認
$ vault token create -policy=app-ro -ttl=1h # → トークン発行
$ vault token capabilities <token> secret/data/myapp/db
list, read ← 自分の領域は読める
$ vault token capabilities <token> secret/data/other/db
deny ← 許可していない他人の領域は拒否
myapp 配下は read, list が返り、許可していない other 配下は deny になりました。Web UI の「Access control → ACL policies」からも同じポリシーを GUI で管理できます。

AppRole でアプリから安全にアクセスする
ここが本番運用の肝です。アプリに root トークンを渡すのは絶対にNG。代わりに AppRole 認証を使い、アプリには「RoleID + SecretID」で TTL付きの短命トークンを発行します。
Success! Enabled approle auth method at: approle/
$ vault write auth/approle/role/myapp token_policies=app-ro token_ttl=1h token_max_ttl=4h
$ vault read auth/approle/role/myapp/role-id
role_id 2b41680f-cc1e-6f0c-8723-e2748a591334
$ vault write -f auth/approle/role/myapp/secret-id
secret_id 0d3101b6-39f3-afee-d94f-99ccd9466071
# アプリ起動時に role_id + secret_id でログイン
$ vault write auth/approle/login role_id=<rid> secret_id=<sid>
token hvs.CAESIHD0…(TTL 3600秒の短命トークン)
token_policies [app-ro default]

RoleID はアプリの設定に埋め込んでもよい公開値、SecretID だけを CI/CD や起動スクリプトから安全に注入します。発行されるトークンは TTL 1時間(3600秒)の短命トークンで、app-ro ポリシーが付くので許可されたパスしか読めません。万が一漏れても、影響範囲と有効時間が限定されます。
本番運用のチェックリスト
今回の構築で実測できた数値をまとめます。

そのうえで、検証構成から本番へ進むときに最低限おさえたいのが次の3点です。
本番化で必ずやること
tls_disable = 1をやめ、TLS を有効化する(Let’s Encrypt や apt 版が生成する/opt/vault/tlsを利用)- auto-unseal を設定する(クラウドKMSや Transit エンジンで、再起動のたびの手動 unseal を自動化)
- 監査ログを有効化する(
vault audit enable file file_path=/var/log/vault_audit.log)
注意:単一ノードの file ストレージは学習・小規模向け
file バックエンドは構成が単純で個人VPSでの学習に向いていますが、冗長化(HA)はできません。可用性が必要な本番では Integrated Storage(Raft)構成や複数ノードを検討してください。
こうしたシークレット管理サーバーは、自分の VPS を1台借りて常時起動しておくと一気に実用的になります。東京リージョンがあり時間課金で試しやすい Vultr あたりが、Vault のような常駐サービスの検証には扱いやすいです。
よくあるエラーと解決策
① Vault is sealed
エラー
Error ... Vault is sealed
原因:サーバーは起動しているが解錠されていません。再起動後は必ず封印されます。アンシール鍵をしきい値ぶん(今回は3本)入力して解錠してください。
Sealed true
$ vault operator unseal # 対話で鍵を3回入力
② permission denied
原因:トークンの権限不足です。Vault はデフォルト拒否なので、アクセスしたいパスを許可するポリシーがトークンに付いているか vault token capabilities <token> <path> で確認してください。KV v2 のパスは secret/data/...(API上は data/ が入る)である点に注意します。
③ missing client token
原因:VAULT_TOKEN 環境変数が未設定です。export VAULT_TOKEN=hvs.... でトークンを設定するか、vault login でログインしてください。同様に接続先は export VAULT_ADDR=http://127.0.0.1:8200 で指定します。
④ Web UI に root token を入れてもログイン後すぐ戻される
root トークンはセキュリティ上ブラウザに保存されません。画面を更新すると再ログインが必要です。日常運用では root を使わず、ユーザーごとの認証メソッド(userpass や OIDC)を有効化して個別アカウントでログインするのが正解です。
まとめ
Ubuntu 24.04 LTS 上に HashiCorp Vault v2.0.2 を file ストレージ構成で構築し、初期化から AppRole 連携までを実際に動かして確認しました。
- Vault は起動直後は封印状態。5本中3本のアンシール鍵で解錠する(Shamirの秘密分散)
- インストールは Docker でも apt でも可能で、今回はどちらも v2.0.2 だった
- KV v2 は値を上書きせずバージョンを増やすので、古いシークレットにも戻せる
- ポリシーはデフォルト拒否。アプリには最小権限の read/list だけを与える
- 本番アプリには root を渡さず、AppRole で TTL 1時間の短命トークンを発行する
- 本番化では TLS 有効化・auto-unseal・監査ログを必ず併用する
シークレット管理は、VPS で本番サーバーを運用し始めると必ずぶつかる課題です。最初は file ストレージの単一ノードで十分動くので、まずは自分の VPS に1台立てて、KV と AppRole の感覚をつかむところから始めるのがおすすめです。
VPS の選び方や Ubuntu サーバーの初期設定については、以下も参考にしてください。
[LINK_X_ARTICLE]



コメント