KMS Agent は、アプリケーションのシークレット取得を集中管理するクライアントサイド HTTP プロキシです。各アプリケーションに KMS SDK を統合する代わりに、アプリケーションはエージェントにローカル HTTP リクエストを送信します。エージェントは、アプリケーションに代わって認証、キャッシング、および KMS との通信を処理します。
仕組み
エージェントはシークレット値をメモリにキャッシュし、設定した Time To Live (TTL) に基づいて定期的に更新します。アプリケーションがシークレットをリクエストした場合:
エージェントは、サーバーサイドリクエストフォージェリ (SSRF) トークンファイルを使用してリクエストを検証します。
有効なキャッシュ値が存在し、有効期限が切れていない場合、エージェントはそれを直ちに返します (キャッシュヒット)。
有効なキャッシュエントリが存在しない場合、エージェントはリクエストを KMS に転送します。KMS はエージェントの ID を検証し、シークレットを復号して返します。エージェントはキャッシュを更新し、値をアプリケーションに返します (キャッシュミス)。
以下の図は、両方のフローを示しています。
キャッシュヒットのプロセス
キャッシュミス (キャッシュなし、またはキャッシュ期限切れ) のプロセス
キャッシュされたシークレット値は、暗号化されずにメモリに保存されます。エージェントに適切なプロセスアクセス権限を適用し、メモリ保護メカニズムを有効にし、メモリリーク検出ツールをデプロイして、シークレット値を保護してください。
エージェントは、物理サーバー、Elastic Compute Service (ECS) などの仮想マシン、または Kubernetes ポッドなどのコンテナ上のアプリケーションとともにデプロイします。ソースコードとデプロイガイドについては、「alibabacloud-kms-agent」をご参照ください。
アーキテクチャ
エージェントは、HTTP サーバー、キャッシュ、KMS クライアント、ログの 4 つのコンポーネントで構成されます。
4 つのコンポーネントはすべて、単一の設定ファイルで設定します。以下の設定例は、利用可能なすべてのオプションとそのデフォルト値を示しています。
# すべての設定項目
[Server]
# オプション。デフォルト値は 2025 です。エージェントは 127.0.0.1:2025 でリッスンします。
HttpPort = 2025
# オプション。デフォルト値は ["X-KMS-Token", "X-Vault-Token"] です。
# エージェントへのリクエストには SSRF ヘッダーを含める必要があります。ヘッダーがないリクエストは拒否されます。
SSRFHeaders = ["X-KMS-Token"]
# オプション。デフォルト値は ["KMS_TOKEN", "KMS_SESSION_TOKEN", "KMS_CONTAINER_AUTHORIZATION_TOKEN"] です。
# 値はリテラル文字列またはファイルパス (例: file:///var/run/awssmatoken) を指定できます。
# エージェントは指定された環境変数から SSRF トークンを読み取り、
# アプリケーションのリクエストヘッダー内のトークンと比較します。一致した場合にのみアクセスが許可されます。
SSRFEnvVariables = ["KMS_TOKEN"]
# オプション。デフォルト値は "/v1/" です。パスベースのリクエストの URI プレフィックスです。
PathPrefix = "/v1/"
# オプション。デフォルト値は 800 です。同時リクエストの最大数です。
MaxConn = 800
# オプション。デフォルト値は 0 です。
# 0: KMS GetSecretValue レスポンス形式
# 1: AWS Secrets Manager GetSecretValue レスポンス形式
# 2: HashiCorp Vault KV 構造
ResponseType = 0
# オプション。デフォルト値は true です。
# true の場合、KMS が一時的に到達不能な場合、エージェントは期限切れのキャッシュ値を返します。
IgnoreTransientErrors = true
[Kms]
# オプション。デフォルト値は cn-hangzhou です。
Region = "cn-hangzhou"
# オプション。デフォルト値は kms.cn-hangzhou.aliyuncs.com です。
# 共有ゲートウェイエンドポイントと専用ゲートウェイエンドポイントの両方に対応しています。
Endpoint = "kms.cn-hangzhou.aliyuncs.com"
[Cache]
# オプション。デフォルト値は InMemory です。現在、インメモリキャッシングのみがサポートされています。
CacheType = "InMemory"
# オプション。デフォルト値は 1000 です。0 に設定すると、キャッシングが無効になり、すべての
# リクエストが直接 KMS に送信されます。
CacheSize = 1000
# オプション。デフォルト値は 300 s です。
TtlSeconds = 300
# オプション。デフォルト値は false です。
# false: キャッシュが満杯の場合、最も古いキャッシュされたシークレットを削除します。
# true: アクセス頻度に基づいて、Least Recently Used (LRU) のシークレットを削除します。
EnableLRU = false
[Log]
# オプション。デフォルト値は Debug です。
LogLevel = "Debug"
# オプション。デフォルト値は、アプリケーションの起動ディレクトリを基準とした ./logs/ です。
LogPath = "./logs/"
# オプション。デフォルト値は 100 MB です。ログファイルあたりの最大サイズです。
MaxSize = 100
# オプション。デフォルト値は 2 です。保持するログファイルの数です。
MaxBackups = 2HTTP サーバー
HTTP サーバーは、シークレット取得のためのアプリケーションリクエストを処理します。デフォルトでは、レスポンスは KMS の GetSecretValue 形式を使用します。ResponseType を設定することで、代わりに AWS Secrets Manager または HashiCorp Vault KV 形式を返すことができます。
サポートされているリクエスト形式:
パスベース:
GET /v1/<secret-name>クエリベース:
GET /secretsmanager/get?secretId=<secret-name>
curl を使用したリクエスト例 (ファイルから SSRF トークンを読み取る):
curl -s \
-H "X-KMS-Token: $(cat /var/run/kmstoken)" \
"http://127.0.0.1:2025/v1/<secret-name>"Python を使用したリクエスト例:
with open("/var/run/kmstoken") as f:
token = f.read().strip()
headers = {"X-KMS-Token": token}
response = requests.get("http://127.0.0.1:2025/v1/<secret-name>", headers=headers)
print(response.json())<secret-name> を取得するシークレットの名前に置き換えます。
サポートされているレスポンス形式:
エージェントは、AWS Secrets Manager および HashiCorp Vault KV のレスポンス形式と互換性があります。コードがすでに Spring Vault を統合している場合、アクセスエンドポイントを KMS Agent のアドレスに変更し、エージェントを介して設定を調整することで、迅速に Alibaba Cloud プラットフォームに切り替えることができます。
Alibaba Cloud KMS (デフォルト、
ResponseType=0):{ "CreateTime": "2025-01-03T07:59:17Z", "RequestId": "cc315250-04c9-4caf-a055-6648f36598b9", "SecretData": "{\"k3\":\"v3\"}", "SecretDataType": "text", "SecretName": "agent-test", "SecretType": "Generic", "VersionId": "v2", "VersionStages": { "VersionStage": [ "ACSCurrent" ] } }AWS Secrets Manager (
ResponseType=1):{ "ARN": "", "Name": "agent-test", "VersionId": "v2", "SecretString": "{\"k3\":\"v3\"}", "VersionStages": [ "ACSCurrent" ], "CreatedDate": "2025-01-03T07:59:17Z" }HashiCorp Vault (
ResponseType=2):{ "data": { "k3": "v3" } }
キャッシュ
エージェントはシークレット値をメモリにキャッシュし、KMS に送信されるリクエストの数を減らします。アクセスパターンとシークレットのローテーションスケジュールに合わせて、キャッシュの TTL、サイズ、削除ポリシーを設定します。
パラメーター | 説明 | デフォルト |
| キャッシュバックエンド。現在、 |
|
| キャッシュするシークレットの最大数。 |
|
| キャッシュされた値が有効と見なされる期間 (秒単位)。 |
|
| キャッシュが満杯の場合の削除ポリシー。 |
|
KMS クライアント
KMS クライアントは、エージェントを KMS に接続します。Region と Endpoint を KMS のデプロイメントに合わせて設定します。共有ゲートウェイエンドポイントと専用ゲートウェイエンドポイントの両方がサポートされています。
専用ゲートウェイエンドポイントを使用する場合、エージェントにはすべてのリージョンの CA 証明書が組み込まれているため、追加の証明書設定は不要です。
ログ
エージェントは Zap ロギングフレームワークを使用して、構造化された JSON ログを出力します。運用要件に合わせて、ログレベル、ファイルサイズの制限、および保持数を設定します。
セキュリティ
認証と認可
KMS に対するエージェントの認証
エージェントは、Alibaba Cloud のデフォルトの認証情報プロバイダーチェーンを使用します。このプロバイダーチェーンは、credentials.NewDefaultCredentialsProvider() で特定の初期化メソッドが提供されていない限り、環境変数、OIDC IdP RAM ロール、config.json、ECS RAM ロール、認証情報 URI の順でソースをチェックします。
エージェントには、シークレットの取得と復号に必要な権限のみを付与してください。RAM ポリシーを設定する際は、最小権限の原則に従ってください。
エージェントに対するアプリケーションの認証
エージェントは起動時に SSRF トークンファイル (例: /var/run/kmstoken) を生成します。アプリケーションは、このトークンをリクエストヘッダーに含める必要があります。有効なトークンがないリクエストは拒否されます。
トークンファイルへのアクセスは、デフォルトで制限されています。
Linux:エージェントプロセスとアプリケーションの OS ユーザーのみがトークンファイルを読み取ることができます。
サイドカーコンテナ:トークンファイルへのアクセスは、ポッド内に制限されます。
通信のセキュリティ
エージェントから KMS へ:すべてのトラフィックは Transport Layer Security (TLS) を使用します。より強力な分離のためには、専用ゲートウェイエンドポイントを使用してください。これにより、トラフィックは VPC 内に留まり、パブリックインターネットに公開されません。
エージェントからアプリケーションへ:エージェントは
127.0.0.1でのみリッスンするため、アクセスはローカルマシンに制限されます。
監査とロギング
すべてのシークレット取得操作は、Zap フレームワークを使用して JSON 形式でログに記録されます。ログはファイルサイズと保持数を設定可能で、エージェントのアクティビティの監査可能な記録を提供します。
安定性
エージェントは、ネットワークの切断や一時的な障害が発生した場合でも、利用可能な状態を維持するように設計されています。
起動時の自己チェック:起動時に、エージェントは KMS への接続性を検証します。検証に失敗した場合、エージェントは劣化した状態で起動するのではなく、終了します。
自動リトライ:エージェントは、Alibaba Cloud SDK (V2) の組み込みリトライロジックを使用します。HTTP 429 (スロットリング) および HTTP 500 (内部サーバーエラー) のレスポンスに対しては、エクスポネンシャルバックオフ方式を使用して 3 回リトライします。
古いキャッシュへのフォールバック:IgnoreTransientErrors が有効な場合 (デフォルト)、KMS が一時的に到達不能な場合、エージェントは最新のキャッシュ値を返します。これにより、短時間のネットワークやサーバーの問題によるアプリケーションの障害を防ぎます。
高可用性:
Linux (systemd):
systemdはエージェントプロセスを監視し、クラッシュした場合は自動的に再起動します。Kubernetes (init コンテナ):init コンテナとしてデプロイされるため、エージェントに障害が発生するとコンテナが再起動され、アプリケーションの安定性が保証されます。
KMS Agent と Secret Client の比較
KMS Agent は中間層として機能し、アプリケーションは KMS を直接呼び出すのではなく、エージェントを介してシークレットにアクセスします。Secret Client は、各アプリケーションに KMS SDK を統合します。デプロイ規模とアクセス制御の要件に基づいて選択してください。
観点 | KMS Agent | Secret Client |
推奨対象 | 複数のアプリケーションと多様なプログラミング言語を使用し、集中化されたアクセス制御を必要とする企業 | 単一のアプリケーション、またはシンプルなアクセス制御要件を持つ小規模なデプロイ |
デプロイ | 独立したプロセスで、アプリケーションから分離 | アプリケーションコードに統合されたライブラリ |
統合の複雑さ | 低 | 高 |
アクセス制御 | 集中管理:すべてのアプリケーションに対して単一のポイントで強制 | 分散管理:各アプリケーションが独自のポリシーを管理 |
言語サポート | 任意の言語 (HTTP インターフェース) | Java 8+、Python、Go |
パフォーマンス | インメモリキャッシュにより、高頻度のシナリオにおけるレイテンシーと KMS のスロットリングを最小限に抑えます | 高頻度のアクセスは KMS のスロットリングをトリガーする可能性があります |
シークレットのローテーション | 設定可能な TTL でキャッシュされ、有効期限が切れると KMS から自動的に更新されます | 更新メカニズムとリトライロジックを使用して自動的に取得されます |
メンテナンス | 低:すべてのアプリケーションに対して 1 つの設定 | 高:アプリケーションごとに個別の設定 |