IBM Bobで実装しながら理解する:HashiCorp VaultとSPIFFEによるゼロトラストなワークロード認証
1. はじめに
この記事について
本記事は、IBM BOB(AI駆動型開発アシスタント)を活用して執筆・実装されています。IBM BOBは、コード生成、デバッグ、ドキュメント作成などを支援し、開発生産性を大幅に向上させるツールです。
IBM BOBとは?: https://www.ibm.com/jp-ja/new/announcements/ibm-project-bob
本記事では、AI開発アシスタント「IBM Bob」を活用しながら、IBM Vault Self ManagedのSPIFFE認証機能を実装し、AI Agentなどのワークロードに対するゼロトラストなアイデンティティ管理を実現した検証環境の構築と動作確認結果を紹介します。
IBM Bobとの対話を通じて、SPIFFE/SPIREの概念理解から実装、トラブルシューティングまでを段階的に進めることで、複雑なセキュリティ技術を実践的に習得できました。
2. 検証環境の概要
本記事で紹介する実装は、WSL2 Ubuntu環境でバイナリベースのインストールを行っています。
本検証では以下のコンポーネントを統合しました。
| コンポーネント | バージョン | 役割 |
|---|---|---|
| SPIRE Server(スパイア サーバー) | 1.14.5 | SPIFFE IDの発行と管理 |
| SPIRE Agent(スパイア エージェント) | 1.14.5 | ワークロードへのSVID提供 |
| IBM Vault Self Managed | 2.0.0+ent | SPIFFE認証とシークレット管理 |
| Python Workload | 3.9+ | テスト用AI Agent |
SPIRE(スパイア): SPIFFE Runtime Environment
SPIFFE(スピッフィ): Secure Production Identity Framework for Everyone
2.1. SPIRE AgentとWorkloadの配置
SPIFFE/SPIREアーキテクチャでは、SPIRE AgentとWorkloadは同一ノード(筐体)上で稼働させる必要があります。
Agents expose the SPIFFE Workload API locally to workloads, and must be installed on each node on which a workload is running.
重要なポイント:
- SPIRE AgentはWorkload APIを**ローカルに(locally)**公開
- Agentはワークロードが実行される各ノードにインストールが必要
- Unix系システムではUnix Domain Socketを使用してローカル通信
- ワークロードはローカルのAgentからSVIDを取得
本検証環境では、SPIRE Agent、Vault、および3つのワークロード(test-client、ai-agent-1、ai-agent-2)をすべて同一ノード上で実行しています。
2.2. アーキテクチャ図
以下の図は、SPIFFE/SPIREとVaultの統合アーキテクチャを示しています。
Attestation(アテステーション)とは
Attestationは「証明」「検証」を意味し、SPIRE AgentがSPIRE Serverに対して自身の正当性を証明するプロセスです。
本環境での動作:
- SPIRE AgentがSPIRE Serverに接続
- Join Token(事前共有トークン)を使用してAgent自身を証明
- SPIRE ServerがAgentを信頼し、ワークロード検証を委任
- 以降、AgentはワークロードにSVIDを発行可能
Attestationの種類:
-
join_token: 事前共有トークン(本環境で使用) -
aws_iid: AWS EC2インスタンスメタデータ -
gcp_iit: GCP インスタンスアイデンティティトークン -
k8s_sat: Kubernetes Service Account Token
本検証ではjoin_tokenを使用していますが、クラウド環境では各プラットフォームのアイデンティティサービスを活用できます。
稼働前提条件: SPIRE AgentとWorkloadの同一ノード配置
図中の「同一ノード(筐体)」で囲まれた領域は、SPIRE AgentとWorkloadが必ず同じノード上で稼働する必要があることを示しています。
なぜ同一ノードが必要か:
- SPIRE AgentはUnix Domain Socket(
/tmp/spire-agent/public/api.sock)でWorkload APIを公開 - Unix Domain Socketはローカルプロセス間通信(IPC)の仕組みで、ネットワーク越しにはアクセス不可
- ワークロードは環境変数
SPIFFE_ENDPOINT_SOCKETで指定されたローカルソケットに接続してSVIDを取得 - この設計により、ネットワーク経由の攻撃を防ぎ、高速かつセキュアな通信を実現
本検証環境の構成:
- SPIRE Server: 別ノードでも可(本検証では同一ノード)
- SPIRE Agent: ワークロードと同一ノードで稼働(必須)
- Workloads(test-client、ai-agent-1、ai-agent-2): SPIRE Agentと同一ノードで稼働(必須)
- Vault: 別ノードでも可(本検証では同一ノード)
本検証では、すべてのコンポーネントを1台のWSL2 Ubuntu環境で実行していますが、本番環境では複数ノードに分散配置する場合でも、各ノードにSPIRE Agentをインストールし、そのノード上のワークロードにSVIDを提供する構成となります。
3. SPIFFE/SPIREとは
SPIFFE(Secure Production Identity Framework for Everyone)は、異種環境全体でワークロードに一貫した暗号化アイデンティティを提供するフレームワークです。
3.1. SPIFFEの主要概念
| 概念 | 説明 | 例 |
|---|---|---|
| SPIFFE ID | ワークロードを一意に識別するURI形式のID | spiffe://example.org/workload/ai-agent-1 |
| SVID | SPIFFE Verifiable Identity Document。X.509証明書またはJWT形式でワークロードの身元を証明 | X.509証明書、JWT |
| Trust Domain | SPIFFE IDの名前空間を定義する管理境界 | example.org |
| Trust Bundle | SPIRE ServerのCA証明書集合。SVID発行と署名検証に使用 | ルートCA証明書 + 中間CA証明書 |
3.2. SPIREの役割
SPIRE(SPIFFE Runtime Environment)は、SPIFFEの本番環境対応実装です。
| 機能 | 説明 |
|---|---|
| Node Attestation | ノード(サーバー)の身元を自動的に検証 |
| Workload Attestation | ワークロードの身元をセレクタ(UID、パスなど)で検証 |
| SVID自動更新 | 短いTTLのSVIDを自動的にローテーション |
3.3. SPIRE ServerのCA機能
SPIRE Serverは、Trust Domain内でCA(認証局)として機能し、ワークロードにSVIDを発行します。
A server acts as a signing authority for identities issued to a set of workloads via agents.
自己署名CA証明書の自動生成:
SPIRE Serverは起動時に以下を自動実行します:
- ルートCA証明書を生成(自己署名)
- このCAを使用してSVID(X.509証明書)を発行
- Trust Bundleとして配布
SPIRE Serverは、デフォルトで自己署名ルートCAとして動作します。KeyManagerプラグインが署名鍵を管理し、外部CAとの統合が必要な場合は、UpstreamAuthorityプラグインを使用できます。
KeyManager: Implements both signing and key storage logic for the server's signing operations.
外部CAは必須ではない:
- 有償CA(DigiCert、GlobalSign等)は必須ではない
- Let's EncryptなどのパブリックCAも必須ではない
- SPIRE Serverが自己完結型のPKI(公開鍵基盤)を提供
- オプションとして
UpstreamAuthorityプラグインで外部CAと統合も可能(AWS PCA、HashiCorp Vault等)
なぜ自己署名で問題ないのか:
SPIFFEの設計思想は、クローズドなTrust Domain内での認証です。
Trust Domainは、システムの信頼ルートに対応します。
The trust domain corresponds to the trust root of a system. A trust domain could represent an individual, organization, environment or department running their own independent SPIFFE infrastructure.
- インターネット上の不特定多数との通信ではない
- Trust Domain内の参加者全員が同じルートCAを信頼
- ワークロード間の相互認証に特化
本検証環境では、SPIRE Serverが自動生成した自己署名CA証明書を使用しています。
4. Vault SPIFFE認証の仕組み
重要: SPIFFE認証機能はIBM Vault Self Managedでのみ利用可能です。
- 公式ドキュメント: https://developer.hashicorp.com/vault/docs/auth/spiffe
- IBM Vault Self Managedライセンスが必要です。
- Vault Community Edition(OSS版)では使用できません
IBM Vault Self ManagedのSPIFFE認証メソッドは、SPIREが発行したSVIDを使用してワークロードを認証します。
4.1. 認証フロー
以下のシーケンス図は、ワークロードがVaultからシークレットを取得するまでの流れを示しています。
Trust Bundle設定について
本検証環境ではstaticプロファイルを使用しているため、Trust Bundle(SPIRE ServerのCA証明書)は事前にIBM Vaultに登録されています。認証時にSPIRE Serverへの問い合わせは発生しません。
本番環境でhttps_spiffe_bundleプロファイルを使用する場合は、IBM VaultがSPIRE ServerのTrust Bundleエンドポイントから自動的にCA証明書を取得・更新します。
4.2. mTLS(相互TLS認証)
SPIFFE認証では、クライアントとサーバーの両方が証明書で身元を証明するmTLSを使用します。
- クライアント認証: ワークロードがSVID証明書を提示
- サーバー認証: VaultがTLS証明書を提示
- 双方向検証: 両者が相手の証明書を検証
5. 環境構築手順
SPIRE ServerとAgent、IBM Vault Self Managedを順番にインストールし、統合環境を構築します。
5.1. 前提条件
# 必要なパッケージのインストール
sudo apt update
sudo apt install -y curl wget jq openssl python3 python3-pip
5.2. SPIRE Server/Agentのインストール
SPIRE公式サイトから最新バイナリをダウンロードします。
# SPIRE 1.14.5のダウンロードと展開
wget https://github.com/spiffe/spire/releases/download/v1.14.5/spire-1.14.5-linux-amd64-musl.tar.gz
tar xzf spire-1.14.5-linux-amd64-musl.tar.gz
sudo mv spire-1.14.5 /opt/spire
5.3. SPIRE Server設定
SPIRE Serverの設定ファイルを作成します。
server {
bind_address = "0.0.0.0"
bind_port = "8081"
trust_domain = "example.org"
data_dir = "/opt/spire/data/server"
log_level = "INFO"
socket_path = "/tmp/spire-server/private/api.sock"
}
plugins {
DataStore "sql" {
plugin_data {
database_type = "sqlite3"
connection_string = "/opt/spire/data/server/datastore.sqlite3"
}
}
NodeAttestor "join_token" {
plugin_data {}
}
KeyManager "disk" {
plugin_data {
keys_path = "/opt/spire/data/server/keys.json"
}
}
}
# Trust Bundleエンドポイント設定
federation {
bundle_endpoint {
address = "0.0.0.0"
port = 8443
}
}
5.4. SPIRE Agent設定
SPIRE Agentの設定ファイルを作成します。
agent {
data_dir = "/opt/spire/data/agent"
log_level = "INFO"
server_address = "127.0.0.1"
server_port = "8081"
socket_path = "/tmp/spire-agent/public/api.sock"
trust_domain = "example.org"
insecure_bootstrap = true
}
plugins {
NodeAttestor "join_token" {
plugin_data {}
}
KeyManager "disk" {
plugin_data {
directory = "/opt/spire/data/agent"
}
}
WorkloadAttestor "unix" {
plugin_data {}
}
WorkloadAttestor "systemd" {
plugin_data {}
}
}
5.5. IBM Vault Self Managedのインストール
IBM Vault Self Managedライセンスについて
- SPIFFE認証機能を使用するには、IBM Vault Self Managedライセンスが必要です
- 評価版ライセンスはHashiCorp公式サイトから取得可能
- ライセンスファイル(
.hclic)を/opt/vault/vault.hclicに配置してください
# IBM Vault Self Managedバイナリのダウンロード
wget https://releases.hashicorp.com/vault/2.0.0+ent/vault_2.0.0+ent_linux_amd64.zip
unzip vault_2.0.0+ent_linux_amd64.zip
sudo mv vault /opt/vault/bin/
sudo chmod +x /opt/vault/bin/vault
# ライセンスファイルの配置(事前に取得が必要)
sudo cp vault.hclic /opt/vault/vault.hclic
5.6. Vault設定
Vaultの設定ファイルを作成します。
storage "raft" {
path = "/opt/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault-cert.pem"
tls_key_file = "/opt/vault/tls/vault-key.pem"
}
api_addr = "https://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8201"
ui = true
log_level = "INFO"
license_path = "/opt/vault/vault.hclic"
SPIFFE認証を使用する場合、VaultはHTTPSで動作する必要があります。自己署名証明書でも動作しますが、本番環境では正式なCA証明書を使用してください。
5.7. サービス起動
systemdサービスとして各コンポーネントを起動します。
# SPIRE Server起動
sudo systemctl start spire-server
sudo systemctl enable spire-server
# SPIRE Server起動確認
sudo systemctl status spire-server
5.8. SPIRE AgentのJoin Token生成と参加
SPIRE AgentがSPIRE Serverに参加するためのJoin Tokenを生成します。
# Join Token生成
sudo /opt/spire/bin/spire-server token generate \
-spiffeID spiffe://example.org/agent/myagent \
-socketPath /tmp/spire-server/private/api.sock
# 出力例:
# Token: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Join Tokenによる認証フロー
-
初回接続(Bootstrap)
- SPIRE ServerがAgent用のワンタイムトークンを生成
- SPIRE Agent起動時にこのトークンを使用してServerに接続
- ServerがAgentを認証し、Agent自身のSVIDを発行
- Agent SVIDは
/opt/spire/data/agentに保存
-
2回目以降の接続
- 保存されたAgent SVIDを使用してmTLS認証
- Join Tokenは不要(1回限り使用)
-
insecure_bootstrap設定
-
spire-agent.confのinsecure_bootstrap = true - 初回接続時のTLS検証をスキップ(Join Token検証のみ)
- 本番環境では
falseにしてTLS検証を有効化推奨
-
生成したトークンを環境変数に設定してSPIRE Agentを起動します。
# Join Tokenを環境変数に設定(実際のトークンに置き換え)
export JOIN_TOKEN="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# SPIRE Agent起動(Join Token使用)
sudo -E /opt/spire/bin/spire-agent run \
-config /path/to/spire-agent.conf \
-joinToken $JOIN_TOKEN &
# または、systemdサービスとして起動
sudo systemctl start spire-agent
sudo systemctl enable spire-agent
# Agent起動確認
sudo systemctl status spire-agent
5.9. Vault起動
# Vault起動
sudo systemctl start vault
sudo systemctl enable vault
# Vault起動確認
sudo systemctl status vault
5.10. Vault初期化
export VAULT_ADDR='https://127.0.0.1:8200'
export VAULT_SKIP_VERIFY=1
# 初期化(テスト環境のため鍵分割数1で実行。本番環境では複数の鍵分割を推奨)
vault operator init -key-shares=1 -key-threshold=1 > vault-init.json
# アンシール
vault operator unseal $(jq -r '.unseal_keys_b64[0]' vault-init.json)
# ルートトークン設定
export VAULT_TOKEN=$(jq -r '.root_token' vault-init.json)
6. SPIFFE認証の設定
IBM VaultでSPIFFE認証メソッドを有効化し、SPIRE Serverと連携させます。
6.1. SPIFFE認証メソッドの有効化
vault auth enable spiffe
6.2. Trust Bundle設定
SPIRE ServerのTrust BundleをVaultに設定します。
# SPIRE ServerからCA証明書を取得
sudo /opt/spire/bin/spire-server bundle show -format pem > /tmp/spire-ca-bundle.pem
# staticプロファイルを使用してTrust Bundleを設定
vault write auth/spiffe/config \
trust_domain="example.org" \
profile="static" \
bundle=@/tmp/spire-ca-bundle.pem
Trust Bundleプロファイルの比較
本実装ではstaticプロファイルを使用していますが、Vault SPIFFE認証では4つのプロファイルから選択できます。
| プロファイル | 更新方法 | 用途 | メリット | デメリット |
|---|---|---|---|---|
static |
手動 | 検証環境 | シンプル、オフライン可 | 手動更新が必要 |
https_spiffe_bundle |
自動 | 本番環境 | 自動更新、運用負荷低 | エンドポイント設定が必要 |
https_web_bundle |
自動 | SPIRE以外のSPIFFE実装 | 柔軟性が高い | SPIRE専用ではない |
https_web_pem |
自動 | レガシー統合 | 既存CA統合が容易 | SPIFFE標準外 |
本番環境での推奨設定(https_spiffe_bundle):
# SPIRE ServerのTrust Bundleエンドポイントから自動取得
vault write auth/spiffe/config \
trust_domain="example.org" \
profile="https_spiffe_bundle" \
bundle_endpoint_url="https://127.0.0.1:8443"
メリット:
- CA証明書のローテーション時に自動更新
- 手動更新作業が不要
- ヒューマンエラーの防止
本検証環境では理解しやすさを優先してstaticプロファイルを使用していますが、本番環境ではhttps_spiffe_bundleプロファイルの使用を強く推奨します。
6.3. ワークロード登録
SPIRE Serverにワークロードを登録します。
セレクタ(Selector)とは
セレクタは、SPIRE Agentがワークロードを識別するための条件です。ワークロードのプロセス情報(UID、PID、パス、systemdサービス名など)を使って、どのワークロードにどのSVIDを発行するかを決定します。
参考: SPIRE公式ドキュメント
本環境で使用するセレクタ:
-
systemd:id:ai-agent-1.service- systemdサービス名で識別
他の利用可能なセレクタ:
| セレクタ | 説明 | 例 | systemd必須 |
|---|---|---|---|
systemd:id |
systemdサービス名 | systemd:id:myapp.service |
✓ |
unix:uid |
ユーザーID | unix:uid:1000 |
✗ |
unix:gid |
グループID | unix:gid:1000 |
✗ |
unix:path |
実行ファイルパス | unix:path:/opt/app/bin |
✗ |
unix:sha256 |
実行ファイルハッシュ | unix:sha256:abc123... |
✗ |
systemdセレクタの利点:
- サービス名による明確な識別
- 複数インスタンスの区別が容易
- systemdの依存関係管理と統合
重要: セレクタで指定した条件(例: ai-agent-1.service)と実際のワークロード起動方法が一致している必要があります。systemdセレクタを使用する場合、ワークロードは必ずsystemdサービスとして起動する必要があります。
# AI Agent 1の登録
# SVID TTL: 15秒(検証用に短く設定)
sudo /opt/spire/bin/spire-server entry create \
-socketPath /tmp/spire-server/private/api.sock \
-spiffeID spiffe://example.org/aiagent1 \
-parentID spiffe://example.org/agent/myagent \
-selector systemd:id:ai-agent-1.service \
-x509SVIDTTL 15
# AI Agent 2の登録
# SVID TTL: 15秒(検証用に短く設定)
sudo /opt/spire/bin/spire-server entry create \
-socketPath /tmp/spire-server/private/api.sock \
-spiffeID spiffe://example.org/aiagent2 \
-parentID spiffe://example.org/agent/myagent \
-selector systemd:id:ai-agent-2.service \
-x509SVIDTTL 15
# Test Clientの登録
# SVID TTL: 15秒(検証用に短く設定)
sudo /opt/spire/bin/spire-server entry create \
-socketPath /tmp/spire-server/private/api.sock \
-spiffeID spiffe://example.org/testclient \
-parentID spiffe://example.org/agent/myagent \
-selector systemd:id:test-client.service \
-x509SVIDTTL 15
登録内容の確認
登録したエントリを確認します。
sudo /opt/spire/bin/spire-server entry show
出力例:
Found 4 entries
Entry ID : cbe1a0ae-0028-4945-b1d7-a194af2b2645
SPIFFE ID : spiffe://example.org/agent/myagent
Parent ID : spiffe://example.org/spire/agent/join_token/3aa7ec19-8939-4ec3-980d-fbeadcde113f
Revision : 0
X509-SVID TTL : default
JWT-SVID TTL : default
Selector : spiffe_id:spiffe://example.org/spire/agent/join_token/3aa7ec19-8939-4ec3-980d-fbeadcde113f
Entry ID : 404a5941-8ff3-48a2-a93f-de9a9357037f
SPIFFE ID : spiffe://example.org/aiagent1
Parent ID : spiffe://example.org/agent/myagent
Revision : 0
X509-SVID TTL : 15
JWT-SVID TTL : default
Selector : systemd:id:ai-agent-1.service
Entry ID : 5f18f4a2-1ac0-4a46-b486-6ce8e6b8b242
SPIFFE ID : spiffe://example.org/aiagent2
Parent ID : spiffe://example.org/agent/myagent
Revision : 0
X509-SVID TTL : 15
JWT-SVID TTL : default
Selector : systemd:id:ai-agent-2.service
Entry ID : fe62a9cb-4662-4da0-8035-02e89d06f651
SPIFFE ID : spiffe://example.org/testclient
Parent ID : spiffe://example.org/agent/myagent
Revision : 0
X509-SVID TTL : 15
JWT-SVID TTL : default
Selector : systemd:id:test-client.service
エントリ情報の読み方
- Entry ID: エントリの一意識別子
- SPIFFE ID: ワークロードに発行されるSPIFFE ID
- Parent ID: 親エンティティ(SPIRE Agent)のSPIFFE ID
- X509-SVID TTL: X.509証明書の有効期限(秒)
- Selector: ワークロード識別条件
最初のエントリ(spiffe://example.org/agent/myagent)は、SPIRE Agent自身のエントリです。これは5.8. SPIRE AgentのJoin Token生成と参加で作成されたものです。
本検証では、異なる権限レベルを持つ3つのワークロードを登録しました。
| ワークロード | SPIFFE ID | 権限レベル |
|---|---|---|
| test-client | spiffe://example.org/testclient |
最小 |
| ai-agent-1 | spiffe://example.org/aiagent1 |
標準 |
| ai-agent-2 | spiffe://example.org/aiagent2 |
拡張 |
権限設計の詳細
各ワークロードの権限は、後述するVaultポリシー(6.4. Vaultポリシー作成参照)で定義します。
- test-client: 共有設定とテスト用シークレットのみアクセス可能
- ai-agent-1: 共有設定と自身専用シークレットにアクセス可能(読み取りのみ)
- ai-agent-2: 共有設定、自身専用シークレット(読み書き可能)、管理者シークレット(読み取りのみ)にアクセス可能
この3段階の権限設計により、ワークロード間の権限分離と最小権限の原則を実証します。
6.4. Vaultポリシー作成
各ワークロードに対応するVaultポリシーを作成します。
# 共有設定への読み取りアクセス
path "secret/data/shared/*" {
capabilities = ["read", "list"]
}
# 自身専用のシークレットへのアクセス
path "secret/data/ai-agent-1/*" {
capabilities = ["read", "list"]
}
# 動的データベースクレデンシャル取得(将来の拡張用)
path "database/creds/ai-agent-1-role" {
capabilities = ["read"]
}
# メタデータ読み取り
path "secret/metadata/ai-agent-1/*" {
capabilities = ["read", "list"]
}
ポリシーを適用します。
vault policy write ai-agent-1-policy config/policies/ai-agent-1.hcl
6.5. SPIFFEロール設定
SPIFFE IDをVaultポリシーにマッピングします。
vault write auth/spiffe/role/ai-agent-1 \
workload_id_patterns="/aiagent1" \
token_policies="ai-agent-1-policy" \
token_ttl="30m" \
token_max_ttl="4h" \
token_bound_cidrs="127.0.0.1/32" \
token_no_default_policy=true
workload_id_patternsには、SPIFFE IDのパス部分(/aiagent1)を指定します。完全なSPIFFE ID(spiffe://example.org/aiagent1)ではありません。
6.6. テスト用シークレット作成
# KV v2シークレットエンジンの有効化
vault secrets enable -path=secret kv-v2
# AI Agent 1用シークレット
vault kv put secret/ai-agent-1/credentials \
api_key="test-api-key-1" \
database_url="postgresql://localhost:5432/db1"
# AI Agent 2用シークレット
vault kv put secret/ai-agent-2/credentials \
api_key="test-api-key-2" \
database_url="postgresql://localhost:5432/db2"
# 共有設定
vault kv put secret/shared/config \
environment="development" \
log_level="INFO"
7. ワークロード実装
Python製のテストワークロードを実装しました。
必要なライブラリ
pip install spiffe requests
spiffeパッケージはcryptographyを依存関係として含んでいるため、自動的にインストールされます。
ワークロードコード
以下は、SPIFFE認証を使用してVaultからシークレットを取得するPythonコードの抜粋です。
実際のワークロードは、5秒ごとにSVIDを取得し、Vault認証とシークレット取得を繰り返す継続的監視モードで動作します。
import os
import time
from datetime import datetime
from spiffe import WorkloadApiClient
import requests
import tempfile
from cryptography.hazmat.primitives import serialization
def run_test_cycle(agent_name, vault_addr):
"""1回のテストサイクルを実行"""
print("\n=== SVID取得 ===")
# SPIFFE Workload APIからX.509-SVIDを取得
with WorkloadApiClient() as client:
x509_context = client.fetch_x509_context()
x509_svid = x509_context.default_svid
print(f"SVID取得成功: {x509_svid.spiffe_id}")
# 証明書と秘密鍵を一時ファイルに保存
cert_chain = x509_svid.cert_chain
private_key = x509_svid.private_key
cert_pem = b""
for cert in cert_chain:
cert_pem += cert.public_bytes(serialization.Encoding.PEM)
key_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
with tempfile.NamedTemporaryFile(mode='wb', suffix='.pem', delete=False) as cert_file:
cert_file.write(cert_pem)
cert_path = cert_file.name
with tempfile.NamedTemporaryFile(mode='wb', suffix='.key', delete=False) as key_file:
key_file.write(key_pem)
key_path = key_file.name
try:
# Vault SPIFFE認証
print("\n=== Vault SPIFFE認証 ===")
response = requests.post(
f"{vault_addr}/v1/auth/spiffe/login",
cert=(cert_path, key_path),
json={"role": agent_name},
verify=False
)
if response.status_code == 200:
auth_data = response.json()['auth']
token = auth_data['client_token']
print("Vault認証成功")
# シークレット取得
print("\n=== シークレット取得 ===")
secret_response = requests.get(
f"{vault_addr}/v1/secret/data/{agent_name}/credentials",
headers={"X-Vault-Token": token},
verify=False
)
if secret_response.status_code == 200:
secret_data = secret_response.json()['data']['data']
print(f"✓ シークレット取得成功")
return secret_data
finally:
# 一時ファイルをクリーンアップ
os.unlink(cert_path)
os.unlink(key_path)
def main():
agent_name = os.getenv('AGENT_NAME', 'ai-agent-1')
vault_addr = os.getenv('VAULT_ADDR', 'https://127.0.0.1:8200')
print(f"SPIFFE Workload Test: {agent_name}")
print("継続的監視モードで実行中...")
print("5秒ごとにテストサイクルを実行します")
cycle_count = 0
while True:
try:
cycle_count += 1
print(f"\nテストサイクル #{cycle_count} - {datetime.utcnow().isoformat()}Z")
run_test_cycle(agent_name, vault_addr)
print(f"\n次のサイクルまで5秒待機...")
time.sleep(5)
except KeyboardInterrupt:
print("\n終了シグナルを受信しました")
break
except Exception as e:
print(f"\nエラー: {e}")
time.sleep(5)
if __name__ == "__main__":
main()
WorkloadApiClientの接続先について
WorkloadApiClient()は、環境変数SPIFFE_ENDPOINT_SOCKETを使用してSPIRE Agentに接続します。この環境変数が設定されていない場合、エラーが発生します。
本検証環境の設定:
-
SPIRE Agent設定(
config/spire-agent.conf):agent { socket_path = "/tmp/spire-agent/public/api.sock" ... } -
ワークロードのsystemdサービス設定:
[Service] Environment="SPIFFE_ENDPOINT_SOCKET=unix:///tmp/spire-agent/public/api.sock" Environment="AGENT_NAME=test-client" Environment="VAULT_ADDR=https://127.0.0.1:8200"
接続の仕組み:
- systemdがワークロードを起動時に環境変数
SPIFFE_ENDPOINT_SOCKETを設定 - ワークロードが
WorkloadApiClient()を呼び出す - クライアントライブラリが環境変数からソケットパス(
unix:///tmp/spire-agent/public/api.sock)を取得 - Unix Domain Socketを通じてSPIRE Agentに接続
- SPIRE Agentがワークロードのプロセス情報(UID、PID、パスなど)を検証
- 登録されたセレクタ(
systemd:id:test-client.serviceなど)と一致すれば、対応するSVIDを返却
この仕組みにより、ワークロードコード内でソケットパスをハードコードする必要がなく、環境変数を通じて柔軟に設定できます。
参考: py-spiffe公式ドキュメント
WorkloadApiClientはsocket_path引数が省略された場合、SPIFFE_ENDPOINT_SOCKET環境変数を参照します- 環境変数が設定されていない場合は
ArgumentErrorが発生します
7.1. ワークロードのsystemdサービス化
ワークロードをsystemdサービスとして登録し、自動起動と監視を設定します。
systemdサービスファイルの作成
AI Agent 1用のサービスファイルを作成します。
[Unit]
Description=AI Agent 1 - SPIFFE Workload
After=spire-agent.service
Requires=spire-agent.service
[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/opt/agents/ai-agent-1
Environment="SPIFFE_ENDPOINT_SOCKET=unix:///tmp/spire-agent/public/api.sock"
Environment="AGENT_NAME=ai-agent-1"
Environment="VAULT_ADDR=https://127.0.0.1:8200"
Environment="VAULT_SKIP_VERIFY=1"
ExecStart=/usr/bin/python3 /opt/agents/ai-agent-1/spiffe-agent.py
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
systemdサービス設定のポイント
-
依存関係
-
After=spire-agent.service: SPIRE Agent起動後に起動 -
Requires=spire-agent.service: SPIRE Agentが必須
-
-
環境変数
-
SPIFFE_ENDPOINT_SOCKET: SPIRE Agentのソケットパス -
AGENT_NAME: ワークロード識別子(Vaultロール名) -
VAULT_ADDR: Vault APIエンドポイント -
VAULT_SKIP_VERIFY: TLS検証スキップ(検証環境用)
-
-
自動再起動
-
Restart=on-failure: 異常終了時に自動再起動 -
RestartSec=5s: 再起動までの待機時間
-
-
セレクタとの対応
- サービス名
ai-agent-1.serviceがSPIRE Serverのセレクタsystemd:id:ai-agent-1.serviceと一致
- サービス名
ワークロードファイルの配置
# ワークロードディレクトリ作成
sudo mkdir -p /opt/agents/ai-agent-1
sudo chown ubuntu:ubuntu /opt/agents/ai-agent-1
# ワークロードコードをコピー
cp workloads/spiffe-agent.py /opt/agents/ai-agent-1/
サービスの有効化と起動
# サービスファイルを配置
sudo cp ai-agent-1.service /etc/systemd/system/
# systemd設定を再読み込み
sudo systemctl daemon-reload
# サービスを有効化(自動起動設定)
sudo systemctl enable ai-agent-1.service
# サービスを起動
sudo systemctl start ai-agent-1.service
# 起動状態確認
sudo systemctl status ai-agent-1.service
# ログ確認
sudo journalctl -u ai-agent-1.service -f
他のワークロードも同様に設定
AI Agent 2とTest Clientも同じ手順で設定します。
# AI Agent 2
sudo systemctl enable ai-agent-2.service
sudo systemctl start ai-agent-2.service
# Test Client
sudo systemctl enable test-client.service
sudo systemctl start test-client.service
SPIRE Serverへのワークロード登録が必須
systemdサービスを起動する前に、必ず6.3. ワークロード登録でSPIRE Serverにワークロードを登録してください。登録されていない場合、SPIRE AgentはSVIDを発行できず、ワークロードは認証に失敗します。
8. 動作確認結果
8.1. SVID取得の確認
ワークロードがSPIRE AgentからSVIDを正常に取得できることを確認しました。
$ python3 workloads/spiffe-agent.py
SVID取得成功: spiffe://example.org/aiagent1
✓ シリアル番号: 1A2B3C4D5E6F
✓ 発行時刻: 2024-04-08T10:30:00Z
✓ 有効期限: 2024-04-08T11:30:00Z
8.2. Vault認証の確認
SVIDを使用したVault認証が成功することを確認しました。
=== Vault SPIFFE認証 ===
Vault認証成功
✓ Token: hvs.CAESIJ8xMzQ2Nz...
✓ Policies: default, ai-agent-1-policy
✓ Lease Duration: 1800s
8.3. Vault Audit Logの確認
SPIFFE認証リクエストからVaultトークン発行までの一連の操作は、Vault Audit Logに詳細に記録されます。
Audit Logの有効化
# Audit logディレクトリ作成
sudo mkdir -p /var/log/vault
sudo touch /var/log/vault/audit.log
sudo chmod 640 /var/log/vault/audit.log
# Audit log有効化
vault audit enable file file_path=/var/log/vault/audit.log
SPIFFE認証のAudit Log例
以下は、test-clientワークロードがSPIFFE認証を使用してVaultトークンを取得し、シークレットにアクセスした際の実際のAudit Logです。
SVID(X.509証明書)の扱いについて
SPIFFE認証では、クライアントがHTTPSリクエスト時にmTLS(相互TLS認証)でSVID(X.509証明書)を提示します。しかし、Audit Logには以下の理由から証明書の内容は記録されません:
- TLSレイヤーでの処理: 証明書の検証はTLSハンドシェイク時に行われ、Vaultのアプリケーションレイヤーに到達する前に完了
- セキュリティ: 証明書の秘密鍵や詳細な証明書チェーンをログに記録することはセキュリティリスク
-
認証結果のみ記録: Audit Logには認証が成功した結果(
spiffe_id、trust_domainなど)のみが記録される
実際のSVID検証プロセス:
- クライアントがHTTPS接続時にSVID証明書を提示(TLSレイヤー)
- VaultがTrust Bundleを使用して証明書を検証(TLSレイヤー)
- 検証成功後、証明書からSPIFFE IDを抽出
- SPIFFE IDに基づいてVaultトークンを発行
- Audit Logには認証結果(SPIFFE ID、ロール、ポリシーなど)のみ記録
1. SPIFFE認証リクエスト(ログイン):
{
"time": "2026-04-16T11:21:03.521262404Z",
"type": "response",
"auth": {
"client_token": "hmac-sha256:6f5100b7e6cc06d89243deffb8d49df5eaeab62ffb25b12de835e19853debc3f",
"accessor": "hmac-sha256:85339bbe91cc6da623730734eecd690ad5b0a4f65837d72b9f04f2001179040b",
"display_name": "spiffe-test-client",
"entity_id": "03eacdbd-7260-f1ae-b49f-0611246b0767",
"metadata": {
"role": "test-client",
"spiffe_id": "spiffe://example.org/testclient",
"trust_domain": "example.org"
},
"no_default_policy": true,
"policies": ["test-client-policy"],
"token_policies": ["test-client-policy"],
"token_ttl": 1800,
"token_type": "service"
},
"request": {
"id": "172b2997-f3a8-6300-1993-9c9fc9b83729",
"operation": "update",
"mount_accessor": "auth_spiffe_3f9123e8",
"mount_class": "auth",
"mount_point": "auth/spiffe/",
"mount_running_version": "v0.0.0-20260219131711-3fa6d7177299+builtin",
"mount_type": "spiffe",
"namespace": {
"id": "root"
},
"path": "auth/spiffe/login",
"data": {
"role": "hmac-sha256:ad7e06cee45317fd399fcb596e72de2944a43ec244cd3188b926b1c01e2baf45"
},
"headers": {
"user-agent": ["python-requests/2.25.1"]
},
"remote_address": "127.0.0.1",
"remote_port": 40120
},
"response": {
"auth": {
"client_token": "hmac-sha256:6f5100b7e6cc06d89243deffb8d49df5eaeab62ffb25b12de835e19853debc3f",
"accessor": "hmac-sha256:85339bbe91cc6da623730734eecd690ad5b0a4f65837d72b9f04f2001179040b",
"display_name": "spiffe-test-client",
"entity_id": "03eacdbd-7260-f1ae-b49f-0611246b0767",
"metadata": {
"role": "test-client",
"spiffe_id": "spiffe://example.org/testclient",
"trust_domain": "example.org"
},
"no_default_policy": true,
"policies": ["test-client-policy"],
"token_policies": ["test-client-policy"],
"token_ttl": 1800,
"token_type": "service"
},
"mount_accessor": "auth_spiffe_3f9123e8",
"mount_class": "auth",
"mount_point": "auth/spiffe/",
"mount_running_plugin_version": "v0.0.0-20260219131711-3fa6d7177299+builtin",
"mount_type": "spiffe"
}
}
2. シークレット取得(成功):
{
"time": "2026-04-16T11:21:12.806651976Z",
"type": "response",
"auth": {
"client_token": "hmac-sha256:b1ceda09f1977fbbb6368fef36c24efe70ab580beda55d4222eeac9c0b537287",
"accessor": "hmac-sha256:31bf22b0a70f82f37dd43bf47ab54a343d01e0ed52c32b867a9b930dfcd6b636",
"display_name": "spiffe-test-client",
"entity_id": "03eacdbd-7260-f1ae-b49f-0611246b0767",
"metadata": {
"role": "test-client",
"spiffe_id": "spiffe://example.org/testclient",
"trust_domain": "example.org"
},
"policies": ["test-client-policy"],
"token_policies": ["test-client-policy"],
"token_issue_time": "2026-04-16T20:21:12+09:00",
"token_ttl": 1800,
"token_type": "service",
"policy_results": {
"allowed": true,
"granting_policies": [
{"type": ""},
{"name": "test-client-policy", "namespace_id": "root", "type": "acl"}
]
}
},
"request": {
"id": "7e90c7f7-5a43-518f-7f02-76f3cf0c0591",
"operation": "read",
"client_id": "03eacdbd-7260-f1ae-b49f-0611246b0767",
"client_token": "hmac-sha256:b9c4a8b16c23f0cddcbd23f097b0fd62aa762d0ee9b44f39bbffc90be4e4d944",
"client_token_accessor": "hmac-sha256:31bf22b0a70f82f37dd43bf47ab54a343d01e0ed52c32b867a9b930dfcd6b636",
"mount_accessor": "kv_7ac6f0d6",
"mount_class": "secret",
"mount_point": "secret/",
"mount_running_version": "v0.26.2+builtin",
"mount_type": "kv",
"namespace": {
"id": "root"
},
"path": "secret/data/test-client/credentials",
"headers": {
"user-agent": ["python-requests/2.25.1"]
},
"remote_address": "127.0.0.1",
"remote_port": 43978
},
"response": {
"data": {
"data": {
"created_at": "hmac-sha256:6cccd1925d4ef9c95adcb7a12fef8baf3c03adfe9ddb3d67653a74efa89f2e20",
"workload": "hmac-sha256:ad7e06cee45317fd399fcb596e72de2944a43ec244cd3188b926b1c01e2baf45"
},
"metadata": {
"created_time": "hmac-sha256:1d9a4646007b8ae86bad90a0af2832066a54c7257ef7790986906073da496b99",
"custom_metadata": null,
"deletion_time": "hmac-sha256:723cc18a644b706d6fc8450de5b3ee8779449f0eab47b0062e9c2ba63a08555b",
"destroyed": false,
"version": 1
}
},
"mount_accessor": "kv_7ac6f0d6",
"mount_class": "secret",
"mount_point": "secret/",
"mount_running_plugin_version": "v0.26.2+builtin",
"mount_type": "kv"
}
}
3. アクセス拒否(権限なし):
{
"time": "2026-04-16T11:21:28.202371817Z",
"type": "response",
"auth": {
"client_token": "hmac-sha256:032861519f00f8432e1c6f9b7cf1e3aecf55b588e13c32494f69b24782b62bea",
"accessor": "hmac-sha256:484f1bef4d1035a6101286760c9afe57dc087a54701b3820fa88d72610fcff82",
"display_name": "spiffe-test-client",
"entity_id": "03eacdbd-7260-f1ae-b49f-0611246b0767",
"metadata": {
"role": "test-client",
"spiffe_id": "spiffe://example.org/testclient",
"trust_domain": "example.org"
},
"policies": ["test-client-policy"],
"token_policies": ["test-client-policy"],
"token_issue_time": "2026-04-16T20:21:28+09:00",
"token_ttl": 1800,
"token_type": "service",
"policy_results": {
"allowed": false
}
},
"request": {
"id": "5dd7b214-4038-3635-98a2-5f2f1999bc72",
"operation": "read",
"client_id": "03eacdbd-7260-f1ae-b49f-0611246b0767",
"client_token": "hmac-sha256:5352507d2f9333032861a2566421efeeddf41928881b719a38e1948a82d4635b",
"client_token_accessor": "hmac-sha256:484f1bef4d1035a6101286760c9afe57dc087a54701b3820fa88d72610fcff82",
"mount_class": "secret",
"mount_point": "secret/",
"mount_running_version": "v0.26.2+builtin",
"mount_type": "kv",
"namespace": {
"id": "root"
},
"path": "secret/data/ai-agent-1/credentials",
"headers": {
"user-agent": ["python-requests/2.25.1"]
},
"remote_address": "127.0.0.1",
"remote_port": 44716
},
"error": "1 error occurred:\n\t* permission denied\n\n",
"response": {
"data": {
"error": "hmac-sha256:9c57c3e1bd179b7307c396775ece5ea4d360a34c1ec65ed8b2d52df43bb13cb4"
},
"mount_class": "secret",
"mount_point": "secret/",
"mount_running_plugin_version": "v0.26.2+builtin",
"mount_type": "kv"
}
}
Audit Logから読み取れる情報
| 項目 | 説明 |
|---|---|
| 認証情報 |
display_name、spiffe_id、trust_domainでワークロードを特定 |
| ポリシー評価 |
policy_results.allowedでアクセス可否を記録 |
| 付与ポリシー |
granting_policiesで許可したポリシーを明示 |
| リクエスト詳細 |
operation、path、remote_addressで操作内容を記録 |
| タイムスタンプ | すべての操作に正確な時刻を記録 |
Audit Logでは、機密情報(トークン、シークレット値など)はHMAC-SHA256でハッシュ化されて記録されます。これにより、監査証跡を保持しながら、ログファイル自体からの情報漏洩を防ぎます。
8.5. シークレット取得の確認
認証後、ポリシーに基づいてシークレットを取得できることを確認しました。
=== シークレット取得テスト ===
[テスト1] 自身のシークレットにアクセス: ai-agent-1/credentials
✓ ai-agent-1/credentials へのアクセス成功
{
"api_key": "test-api-key-1",
"database_url": "postgresql://localhost:5432/db1"
}
8.6. アクセス制御の確認
他のワークロードのシークレットへのアクセスが正しく拒否されることを確認しました。
=== アクセス制御テスト ===
[テスト2] 他ワークロードのシークレットにアクセス: ai-agent-2/credentials
✓ ai-agent-2/credentials へのアクセス拒否(403 Forbidden)
✓ アクセス制御が正しく機能しています
8.7. SVID自動更新の確認
ワークロードを長時間実行し、SVIDが自動的に更新されることを確認しました。
テストサイクル #1 - 2024-04-08T10:30:00Z
SVID取得成功: spiffe://example.org/aiagent1
✓ 有効期限: 2024-04-08T11:30:00Z
(30秒後)
テストサイクル #2 - 2024-04-08T10:30:30Z
SVID取得成功: spiffe://example.org/aiagent1
✓ 有効期限: 2024-04-08T11:30:30Z
9. 検証結果のまとめ
本検証により、以下の点が確認できました。
成功した項目
- SPIRE Server/Agentの正常起動と連携
- ワークロードへのSPIFFE ID発行
- SVIDの取得と自動更新
- Vault SPIFFE認証メソッドの動作
- ポリシーベースのアクセス制御
- 複数ワークロード間の権限分離
10. ユースケースと応用
10.1. AI Agentのランタイムセキュリティ
複数のAI Agentが独立したアイデンティティを持ち、必要最小限のシークレットのみにアクセスできます。
- エージェントごとに異なるAPIキーを使用
- データベースアクセスの権限分離
- 監査ログによる行動追跡
10.2. サービスメッシュとの統合
Consul、Istioなどのサービスメッシュと統合することで、以下が実現できます。
- mTLSによるサービス間通信の暗号化
- 同一のSPIFFE IDでVault認証とメッシュ認証を統一
- サイドカープロキシによる透過的なセキュリティ
10.3. 動的クレデンシャル(将来の拡張)
本検証環境では、Vaultポリシーに動的シークレットのパスを定義していますが、実際のデータベースシークレットエンジンの設定は未実装です。
将来的には、以下のような設定で短いTTLのデータベースクレデンシャルを発行できます。
# データベースシークレットエンジンの設定(参考例)
vault secrets enable database
vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@localhost:5432/mydb" \
allowed_roles="ai-agent-1-role"
vault write database/roles/ai-agent-1-role \
db_name=postgresql \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';" \
default_ttl="1h" \
max_ttl="24h"
11. まとめ
本記事では、HashiCorp VaultとSPIFFE/SPIREを統合したゼロトラストなワークロード認証環境を構築し、動作確認を行いました。
主な成果
- SPIFFE IDによる一貫したワークロードアイデンティティの実現
- Vault SPIFFE認証による柔軟なアクセス制御
- ポリシーベースの権限分離
- SVIDの自動更新による運用負荷の軽減
参考資料
SPIFFE/SPIRE関連:
Vault関連:
IBM Bob:
付録A: SPIREコマンドリファレンス
本セクションでは、SPIRE運用で頻繁に使用するコマンドを紹介します。詳細はSPIRE公式ドキュメントを参照してください。
A.1. SPIRE Serverコマンド
エントリ管理
# エントリ一覧表示
sudo /opt/spire/bin/spire-server entry show
# 特定のエントリ表示
sudo /opt/spire/bin/spire-server entry show -entryID <entry-id>
# SPIFFE IDで検索
sudo /opt/spire/bin/spire-server entry show -spiffeID spiffe://example.org/aiagent1
# エントリ削除
sudo /opt/spire/bin/spire-server entry delete -entryID <entry-id>
# エントリ更新(SVID TTL変更)
sudo /opt/spire/bin/spire-server entry update \
-entryID <entry-id> \
-x509SVIDTTL 30
# 新規エントリ作成
sudo /opt/spire/bin/spire-server entry create \
-spiffeID spiffe://example.org/myworkload \
-parentID spiffe://example.org/agent/myagent \
-selector unix:uid:1000
参考: SPIRE Server CLI - Entry Management
Trust Bundle管理
# Trust Bundle表示(PEM形式)
sudo /opt/spire/bin/spire-server bundle show -format pem
# Trust Bundle表示(JWKS形式)
sudo /opt/spire/bin/spire-server bundle show -format jwks
# Trust Bundle表示(SPIFFE形式)
sudo /opt/spire/bin/spire-server bundle show -format spiffe
参考: SPIRE Server CLI - Bundle Commands
Agent管理
# Agent一覧表示
sudo /opt/spire/bin/spire-server agent list
# Agent詳細表示
sudo /opt/spire/bin/spire-server agent show -spiffeID spiffe://example.org/agent/myagent
# Agent削除(Agentが停止している場合)
sudo /opt/spire/bin/spire-server agent evict -spiffeID spiffe://example.org/agent/myagent
# Agent Ban(悪意のあるAgentをブロック)
sudo /opt/spire/bin/spire-server agent ban -spiffeID spiffe://example.org/agent/badagent
# Agent数の確認
sudo /opt/spire/bin/spire-server agent count
参考: SPIRE Server CLI - Agent Management
Join Token管理
# Join Token生成
sudo /opt/spire/bin/spire-server token generate \
-spiffeID spiffe://example.org/agent/newagent
# Join Token生成(TTL指定、デフォルトは600秒)
sudo /opt/spire/bin/spire-server token generate \
-spiffeID spiffe://example.org/agent/newagent \
-ttl 3600
# Join Token生成(出力形式指定)
sudo /opt/spire/bin/spire-server token generate \
-spiffeID spiffe://example.org/agent/newagent \
-output json
参考: SPIRE Server CLI - Token Commands
A.2. SPIRE Agentコマンド
SVID確認
# Agent自身のSVID確認
sudo /opt/spire/bin/spire-agent api fetch x509
# ワークロードのSVID確認(Agentソケット経由)
sudo /opt/spire/bin/spire-agent api fetch x509 \
-socketPath /tmp/spire-agent/public/api.sock
# JWT-SVID取得
sudo /opt/spire/bin/spire-agent api fetch jwt \
-audience myservice \
-spiffeID spiffe://example.org/myworkload
参考: SPIRE Agent CLI - API Commands
ヘルスチェック
# Agent健全性確認
sudo /opt/spire/bin/spire-agent healthcheck
# Server接続確認(詳細出力)
sudo /opt/spire/bin/spire-agent healthcheck -verbose
# 特定のソケットパスでヘルスチェック
sudo /opt/spire/bin/spire-agent healthcheck \
-socketPath /tmp/spire-agent/public/api.sock
参考: SPIRE Agent CLI - Health Check
A.3. トラブルシューティング用コマンド
ログ確認
# Server ログ(リアルタイム)
sudo journalctl -u spire-server -f
# Agent ログ(リアルタイム)
sudo journalctl -u spire-agent -f
# 特定期間のログ
sudo journalctl -u spire-server --since "1 hour ago"
# エラーログのみ表示
sudo journalctl -u spire-server -p err
# ログをファイルに出力
sudo journalctl -u spire-server --since today > spire-server.log
デバッグモード
# Serverをデバッグモードで起動
sudo /opt/spire/bin/spire-server run \
-config /opt/spire/conf/server/server.conf \
-logLevel DEBUG
# Agentをデバッグモードで起動
sudo /opt/spire/bin/spire-agent run \
-config /opt/spire/conf/agent/agent.conf \
-logLevel DEBUG
# 設定ファイルの検証
sudo /opt/spire/bin/spire-server validate \
-config /opt/spire/conf/server/server.conf
参考: SPIRE Troubleshooting Guide
接続確認
# Server APIエンドポイント確認
curl -k https://localhost:8081/healthz
# Agent UDSソケット確認
ls -la /tmp/spire-agent/public/api.sock
# Server-Agent間の通信確認
sudo /opt/spire/bin/spire-agent api fetch x509 -verbose
参考: SPIRE Production Deployment Guide
12. おわりに
SPIFFE/SPIREとVaultの統合により、マイクロサービスやAI Agentなどの動的なワークロードに対して、強固なアイデンティティ管理とシークレット管理を実現できることを確認しました。
AI開発アシスタントを活用することで、新しい技術の学習曲線を大幅に短縮し、より実践的なスキルを効率的に習得できることを実感しました。
本記事が、ゼロトラストアーキテクチャの実装を検討されている方、またAI開発アシスタントを活用した技術学習に興味がある方の参考になれば幸いです。