次のステップ
高度な機能
Vaultの高度な機能と活用方法
最終更新: 2026/2/17
高度な機能
Vaultの基本を習得したら、次は高度な機能を活用してさらなる価値を引き出しましょう。
Namespaces(Enterprise版)
Namespacesは、Vaultを論理的に分離する機能です。
用途
- マルチテナント: 複数のチームや組織で共有
- 環境分離: 開発、ステージング、本番の分離
- 管理の委譲: チームごとの自律的な管理
基本操作
# Namespaceの作成
vault namespace create team-a
# Namespaceの一覧
vault namespace list
# Namespace内での操作
vault kv put -namespace=team-a secret/config key=value
# Namespace内でのログイン
vault login -namespace=team-a
階層構造
root/
├── team-a/
│ ├── dev/
│ └── prod/
└── team-b/
├── dev/
└── prod/
Sentinel(Enterprise版)
Sentinelは、ポリシーをコードとして定義するPolicy as Code機能です。
基本的なSentinelポリシー
# require-ttl.sentinel
import "time"
# TTLが24時間以内であることを確認
main = rule {
time.load(request.data.ttl).hours <= 24
}
適用
# Sentinelポリシーの作成
vault write sys/policies/egp/require-ttl \
policy=@require-ttl.sentinel \
enforcement_level="hard-mandatory" \
paths="auth/token/create"
ユースケース
- コンプライアンス: 規制要件の強制
- セキュリティ: セキュリティポリシーの自動化
- ガバナンス: 組織のルールの適用
Transform(Enterprise版)
Transformは、データの変換と暗号化を行う機能です。
Format Preserving Encryption(FPE)
# Transformシークレットエンジンの有効化
vault secrets enable transform
# ロールの作成
vault write transform/role/payments \
transformations=card-number
# 変換の作成
vault write transform/transformation/card-number \
type=fpe \
template=builtin/creditcardnumber \
tweak_source=internal \
allowed_roles=payments
# クレジットカード番号の暗号化
vault write transform/encode/payments \
value=1234-5678-9012-3456
# 出力: 8901-2345-6789-0123(形式を保持)
マスキング
# マスキング変換の作成
vault write transform/transformation/ssn-mask \
type=masking \
template=builtin/socialsecuritynumber \
masking_character=X \
allowed_roles=hr
# SSNのマスキング
vault write transform/encode/hr \
value=123-45-6789
# 出力: XXX-XX-6789
Replication(Enterprise版)
Performance Replication
用途: 読み取りパフォーマンスの向上
# プライマリクラスターで有効化
vault write -f sys/replication/performance/primary/enable
# セカンダリトークンの生成
vault write sys/replication/performance/primary/secondary-token \
id=secondary-tokyo
# セカンダリクラスターで有効化
vault write sys/replication/performance/secondary/enable \
token=<secondary-token>
Disaster Recovery Replication
用途: ディザスタリカバリ
# プライマリクラスターで有効化
vault write -f sys/replication/dr/primary/enable
# セカンダリトークンの生成
vault write sys/replication/dr/primary/secondary-token \
id=dr-osaka
# セカンダリクラスターで有効化
vault write sys/replication/dr/secondary/enable \
token=<dr-token>
Control Groups
Control Groupsは、複数の承認者による承認を必要とする機能です。
設定
# control-group-policy.hcl
path "secret/data/sensitive/*" {
capabilities = ["read"]
control_group = {
factor "approvers" {
identity {
group_names = ["managers"]
approvals = 2
}
}
}
}
使用フロー
# 1. リクエスト
vault kv get secret/sensitive/data
# 出力: Control Group request created
# 2. 承認者1が承認
vault write sys/control-group/authorize \
accessor=<accessor>
# 3. 承認者2が承認
vault write sys/control-group/authorize \
accessor=<accessor>
# 4. リクエスト者がアクセス
vault kv get secret/sensitive/data
Response Wrapping
Response Wrappingは、レスポンスを一時的にラップする機能です。
基本的な使用
# レスポンスをラップ
vault kv get -wrap-ttl=1h secret/myapp/config
# 出力:
# wrapping_token: hvs.CAESIJ...
# wrapping_accessor: abc123...
# wrapping_token_ttl: 1h
# ラップされたトークンでアンラップ
vault unwrap hvs.CAESIJ...
ユースケース
- 安全な配布: シークレットを安全に配布
- 一度だけの使用: トークンは一度だけ使用可能
- 監査: アンラップの記録
Cubbyhole
Cubbyholeは、トークンごとのプライベートストレージです。
特徴
- トークンに紐付いたストレージ
- 他のトークンからアクセス不可
- トークン失効時に自動削除
使用例
# Cubbyholeにデータを保存
vault write cubbyhole/temp-data \
key=value
# Cubbyholeからデータを取得
vault read cubbyhole/temp-data
# トークンを失効するとデータも削除される
vault token revoke -self
Lease Management
リースの一括管理
# すべてのリースを一覧表示
vault list sys/leases/lookup/database/creds/my-role
# プレフィックスに一致するリースを失効
vault lease revoke -prefix database/creds/my-role/
# 特定のアクセサーのリースを失効
vault lease revoke -accessor abc123
リースの自動更新
import hvac
import threading
import time
def auto_renew_lease(client, lease_id):
while True:
try:
# リースの半分の時間で更新
time.sleep(1800) # 30分
client.sys.renew_lease(lease_id=lease_id)
print(f"Lease {lease_id} renewed")
except Exception as e:
print(f"Failed to renew lease: {e}")
break
# 使用例
client = hvac.Client(url='http://vault:8200', token='hvs.CAESIJ...')
creds = client.secrets.database.generate_credentials(name='my-role')
lease_id = creds['lease_id']
# バックグラウンドで自動更新
thread = threading.Thread(target=auto_renew_lease, args=(client, lease_id))
thread.daemon = True
thread.start()
Plugin System
カスタムシークレットエンジン
package main
import (
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/plugin"
)
func main() {
apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:])
plugin.Serve(&plugin.ServeOpts{
BackendFactoryFunc: Factory,
})
}
カスタム認証方法
func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
b := &backend{}
b.Backend = &framework.Backend{
BackendType: logical.TypeCredential,
AuthRenew: b.pathAuthRenew,
PathsSpecial: &logical.Paths{
Unauthenticated: []string{"login"},
},
Paths: []*framework.Path{
&framework.Path{
Pattern: "login",
Fields: map[string]*framework.FieldSchema{
"username": &framework.FieldSchema{
Type: framework.TypeString,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.UpdateOperation: b.pathLogin,
},
},
},
}
return b, nil
}
Vault Agent
自動認証
config.hcl:
pid_file = "./pidfile"
vault {
address = "https://vault.example.com:8200"
}
auto_auth {
method {
type = "approle"
config = {
role_id_file_path = "/etc/vault/role-id"
secret_id_file_path = "/etc/vault/secret-id"
}
}
sink {
type = "file"
config = {
path = "/tmp/vault-token"
}
}
}
template {
source = "/etc/vault/config.tmpl"
destination = "/etc/myapp/config.json"
}
config.tmpl:
{{- with secret "secret/data/myapp/config" }}
{
"database": {
"host": "{{ .Data.data.db_host }}",
"username": "{{ .Data.data.db_username }}",
"password": "{{ .Data.data.db_password }}"
}
}
{{- end }}
Vault Agent Injector(Kubernetes)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp"
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "secret/data/myapp/config" -}}
export DB_HOST="{{ .Data.data.db_host }}"
export DB_PASSWORD="{{ .Data.data.db_password }}"
{{- end }}
spec:
containers:
- name: myapp
image: myapp:latest
Vault CSI Provider(Kubernetes)
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
serviceAccountName: myapp
containers:
- name: myapp
image: myapp:latest
volumeMounts:
- name: secrets
mountPath: "/mnt/secrets"
readOnly: true
volumes:
- name: secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-secrets"
次のステップ
高度な機能を理解したら、継続的な学習リソースで学習を続けましょう。
段階的な導入高度な機能は、基本機能を十分に理解してから導入してください。まずは小規模な環境で検証し、徐々に本番環境に展開することをお勧めします。