hashicorp-vault について
HashiCorp Vaultでシークレット、暗号化、アクセスを一元管理するためのガイドです。セキュリティチームやプラットフォームチーム向けに、シークレットエンジン、認証、ポリシー、アプリ連携を扱います。
主な機能
- 01KV、データベース、AWS、PKIシークレットの管理
- 02AppRole、Kubernetes、OIDC認証の設定
- 03ポリシーによるアクセス制御
- 04PythonアプリへのVault統合
- 05Kubernetes Sidecarによるシークレット注入
活用シーン
- 01アプリ設定と認証情報の一元管理
- 02データベースとAWSの動的認証情報の発行
- 03PKIと証明書の管理
- 04Kubernetesワークロードへのシークレット提供
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill hashicorp-vaultインストール後、Claude Code で/hashicorp-vaultを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/kubernetes-auth.yamlvault-config.hclreferences/secrets-engines.mdvault-policies.mdscripts/vault-backup.shvault-init.sh詳細
HashiCorp Vault
HashiCorp Vault を使用して、シークレット、暗号化、アクセスを一元管理します。
このスキルを使用する場合
次の場合にこのスキルを使用します。
- シークレット管理を一元化する
- 動的な認証情報を実装する
- PKI と証明書を管理する
- 機密データを暗号化する
- コンプライアンス要件を満たす
前提条件
- Vault サーバー(開発環境または本番環境)
- Vault CLI のインストール
- Vault へのネットワークアクセス
クイックスタート
開発サーバー
# Start dev server
vault server -dev
# Set environment
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='root'
# Verify connection
vault status
本番環境へのデプロイ
# config.hcl
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault.crt"
tls_key_file = "/opt/vault/tls/vault.key"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
ui = true
# Initialize Vault
vault operator init -key-shares=5 -key-threshold=3
# Unseal (run 3 times with different keys)
vault operator unseal <key-1>
vault operator unseal <key-2>
vault operator unseal <key-3>
# Login
vault login <root-token>
シークレットエンジン
KV シークレット
# Enable KV v2
vault secrets enable -path=secret kv-v2
# Write secret
vault kv put secret/myapp/config \
username="admin" \
password="s3cr3t"
# Read secret
vault kv get secret/myapp/config
vault kv get -field=password secret/myapp/config
# Update secret
vault kv put secret/myapp/config \
username="admin" \
password="new-password"
# List secrets
vault kv list secret/
# Delete secret
vault kv delete secret/myapp/config
# Version history
vault kv metadata get secret/myapp/config
データベースシークレット
# Enable database engine
vault secrets enable database
# Configure PostgreSQL connection
vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@localhost:5432/mydb" \
allowed_roles="readonly,readwrite" \
username="vault" \
password="vault-password"
# Create role
vault write database/roles/readonly \
db_name=postgresql \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
# Get credentials
vault read database/creds/readonly
AWS シークレット
# Enable AWS engine
vault secrets enable aws
# Configure root credentials
vault write aws/config/root \
access_key=AKIA... \
secret_key=secret... \
region=us-east-1
# Create role
vault write aws/roles/deploy \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": ["arn:aws:s3:::my-bucket/*"]
}
]
}
EOF
# Get credentials
vault read aws/creds/deploy
PKI シークレット
# Enable PKI engine
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
# Generate root CA
vault write -field=certificate pki/root/generate/internal \
common_name="example.com" \
ttl=87600h > ca_cert.crt
# Configure URLs
vault write pki/config/urls \
issuing_certificates="https://vault.example.com:8200/v1/pki/ca" \
crl_distribution_points="https://vault.example.com:8200/v1/pki/crl"
# Create role
vault write pki/roles/web-server \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="720h"
# Issue certificate
vault write pki/issue/web-server \
common_name="web.example.com" \
ttl="24h"
認証方式
AppRole
# Enable AppRole
vault auth enable approle
# Create role
vault write auth/approle/role/myapp \
token_policies="myapp-policy" \
token_ttl=1h \
token_max_ttl=4h \
secret_id_ttl=10m
# Get role ID
vault read auth/approle/role/myapp/role-id
# Generate secret ID
vault write -f auth/approle/role/myapp/secret-id
# Login
vault write auth/approle/login \
role_id=<role-id> \
secret_id=<secret-id>
Kubernetes
# Enable Kubernetes auth
vault auth enable kubernetes
# Configure
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# Create role
vault write auth/kubernetes/role/myapp \
bound_service_account_names=myapp \
bound_service_account_namespaces=default \
policies=myapp-policy \
ttl=1h
OIDC
# Enable OIDC auth
vault auth enable oidc
# Configure
vault write auth/oidc/config \
oidc_discovery_url="https://accounts.google.com" \
oidc_client_id="your-client-id" \
oidc_client_secret="your-client-secret" \
default_role="default"
# Create role
vault write auth/oidc/role/default \
bound_audiences="your-client-id" \
allowed_redirect_uris="http://localhost:8250/oidc/callback" \
user_claim="sub" \
policies="default"
ポリシー
ポリシーの定義
# myapp-policy.hcl
# Read secrets
path "secret/data/myapp/*" {
capabilities = ["read", "list"]
}
# Database credentials
path "database/creds/myapp-db" {
capabilities = ["read"]
}
# PKI certificates
path "pki/issue/web-server" {
capabilities = ["create", "update"]
}
# Deny access to other secrets
path "secret/data/other/*" {
capabilities = ["deny"]
}
# Create policy
vault policy write myapp myapp-policy.hcl
# List policies
vault policy list
# Read policy
vault policy read myapp
アプリケーションとの統合
Python
import hvac
# Initialize client
client = hvac.Client(url='http://localhost:8200')
# AppRole authentication
client.auth.approle.login(
role_id='role-id',
secret_id='secret-id'
)
# Read secret
secret = client.secrets.kv.v2.read_secret_version(
path='myapp/config',
mount_point='secret'
)
password = secret['data']['data']['password']
# Get database credentials
db_creds = client.secrets.database.generate_credentials(
name='myapp-db'
)
Kubernetes サイドカー
apiVersion: v1
kind: Pod
metadata:
name: myapp
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_PASSWORD="{{ .Data.data.password }}"
{{- end }}
spec:
serviceAccountName: myapp
containers:
- name: myapp
image: myapp:latest
command: ["/bin/sh", "-c", "source /vault/secrets/config && ./start.sh"]
よくある問題
問題:Vault がシール状態
問題:再起動後に Vault がシール状態になっています 解決策:クラウド KMS または HSM を使用して、自動アンシールを実装します
問題:トークンの有効期限切れ
問題:アプリケーションのトークンの有効期限が切れています 解決策:トークンの更新を実装し、有効期間の短いトークンを使用します
問題:権限が拒否される
問題:シークレットにアクセスできません 解決策:ポリシーを確認し、トークンの機能を確認します
ベストプラクティス
- 有効期間の短いトークンを使用する
- 自動アンシールを実装する
- 監査ログを有効にする
- 分離のためにネームスペースを使用する
- ルートトークンを定期的にローテーションする
- 最小権限のポリシーを実装する
- 可能な場合は動的シークレットを使用する
- 定期的にバックアップと DR テストを実施する
関連スキル
- aws-secrets-manager - AWS ネイティブのシークレット
- sops-encryption - ファイル暗号化
- kubernetes-hardening - K8s セキュリティ
コメント
Markdown 対応