mcpField
A
azure-security-keyvault-secrets-java

azure-security-keyvault-secrets-java

github.com/sickn33セキュリティ48.7k65 回インストール今日更新
リポジトリ

azure-security-keyvault-secrets-java について

Azure SDKを通じてAzure Key Vaultのシークレットを管理するJava向けスキルです。作成、取得、バージョン管理、復元、バックアップに加え、認証情報や破壊的操作の安全な扱いを説明します。

主な機能

  1. 01シークレットの作成と取得
  2. 02シークレットの属性とバージョンの一覧表示
  3. 03シークレットのメタデータ更新
  4. 04シークレットの削除と復元
  5. 05シークレットのバックアップと復元
  6. 06同期または非同期クライアントの利用

活用シーン

  1. 01Vaultからのアプリ認証情報の読み込み
  2. 02ローテーション時の新しいシークレットバージョン作成
  3. 03保存済みシークレットの復旧や復元

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill azure-security-keyvault-secrets-java

インストール後、Claude Code で/azure-security-keyvault-secrets-javaを入力して読み込まれたか確認します。

詳細

Azure Key Vault シークレット(Java)

パスワード、API キー、接続文字列などのシークレットを安全に保存、管理します。

変更を行う前に、ボールト、テナント、RBAC、および対象のシークレット/バージョンを確認してください。例では合成値を使用しています。実際の値は承認されたシークレット入力から取得し、ソースコードやチャットから取得しないでください。バックアップには機密性の高い暗号化データが含まれ、サービスによる復元制限もあります。ファイルと保持期間を保護してください。有効期限メタデータを設定しても、発行元サービスで認証情報がローテーションされるわけではありません。必須のシークレットを利用できない場合は、フェイルクローズにしてください。不完全な設定でサイレントに起動しないでください。非同期のスニペットにはエラー処理と、完了を待機するアプリケーションのライフサイクルが必要です。

インストール

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-security-keyvault-secrets</artifactId>
    <version>4.9.0</version>
</dependency>

クライアントの作成

import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;

// Sync client
SecretClient secretClient = new SecretClientBuilder()
    .vaultUrl("https://<vault-name>.vault.azure.net")
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildClient();

// Async client
SecretAsyncClient secretAsyncClient = new SecretClientBuilder()
    .vaultUrl("https://<vault-name>.vault.azure.net")
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildAsyncClient();

シークレットの作成/設定

import com.azure.security.keyvault.secrets.models.KeyVaultSecret;

// Simple secret
KeyVaultSecret secret = secretClient.setSecret("database-password", "P@ssw0rd123!");
System.out.println("Secret name: " + secret.getName());
System.out.println("Secret ID: " + secret.getId());

// Secret with options
KeyVaultSecret secretWithOptions = secretClient.setSecret(
    new KeyVaultSecret("api-key", "sk_live_abc123xyz")
        .setProperties(new SecretProperties()
            .setContentType("application/json")
            .setExpiresOn(OffsetDateTime.now().plusYears(1))
            .setNotBefore(OffsetDateTime.now())
            .setEnabled(true)
            .setTags(Map.of(
                "environment", "production",
                "service", "payment-api"
            ))
        )
);

シークレットの取得

// Get latest version
KeyVaultSecret secret = secretClient.getSecret("database-password");
String value = secret.getValue();
// Consume value in memory; never print secret material.

// Get specific version
KeyVaultSecret specificVersion = secretClient.getSecret("database-password", "<version-id>");

// Get only properties (no value)
SecretProperties props = secretClient.getSecret("database-password").getProperties();
System.out.println("Enabled: " + props.isEnabled());
System.out.println("Created: " + props.getCreatedOn());

シークレットのプロパティの更新

// Get secret
KeyVaultSecret secret = secretClient.getSecret("api-key");

// Update properties (cannot update value - create new version instead)
secret.getProperties()
    .setEnabled(false)
    .setExpiresOn(OffsetDateTime.now().plusMonths(6))
    .setTags(Map.of("status", "rotating"));

SecretProperties updated = secretClient.updateSecretProperties(secret.getProperties());
System.out.println("Updated: " + updated.getUpdatedOn());

シークレットの一覧表示

import com.azure.core.util.paging.PagedIterable;
import com.azure.security.keyvault.secrets.models.SecretProperties;

// List all secrets (properties only, no values)
for (SecretProperties secretProps : secretClient.listPropertiesOfSecrets()) {
    System.out.println("Secret: " + secretProps.getName());
    System.out.println("  Enabled: " + secretProps.isEnabled());
    System.out.println("  Created: " + secretProps.getCreatedOn());
    System.out.println("  Content-Type: " + secretProps.getContentType());
    
    // Get value if needed
    if (secretProps.isEnabled()) {
        KeyVaultSecret fullSecret = secretClient.getSecret(secretProps.getName());
        // Do not print even a prefix of the secret.
    }
}

// List versions of a secret
for (SecretProperties version : secretClient.listPropertiesOfSecretVersions("database-password")) {
    System.out.println("Version: " + version.getVersion());
    System.out.println("Created: " + version.getCreatedOn());
    System.out.println("Enabled: " + version.isEnabled());
}

シークレットの削除

import com.azure.core.util.polling.SyncPoller;
import com.azure.security.keyvault.secrets.models.DeletedSecret;

// Begin delete (returns poller for soft-delete enabled vaults)
SyncPoller<DeletedSecret, Void> deletePoller = secretClient.beginDeleteSecret("old-secret");

// Wait for deletion
DeletedSecret deletedSecret = deletePoller.poll().getValue();
System.out.println("Deleted on: " + deletedSecret.getDeletedOn());
System.out.println("Scheduled purge: " + deletedSecret.getScheduledPurgeDate());

deletePoller.waitForCompletion();

削除したシークレットの復元

// List deleted secrets
for (DeletedSecret deleted : secretClient.listDeletedSecrets()) {
    System.out.println("Deleted: " + deleted.getName());
    System.out.println("Deletion date: " + deleted.getDeletedOn());
}

// Recover deleted secret
SyncPoller<KeyVaultSecret, Void> recoverPoller = secretClient.beginRecoverDeletedSecret("old-secret");
recoverPoller.waitForCompletion();

KeyVaultSecret recovered = secretClient.getSecret("old-secret");
System.out.println("Recovered: " + recovered.getName());

削除したシークレットの完全消去

// This is a separate irreversible operation, not the next step after recovery.
// Get deleted secret info first
DeletedSecret deleted = secretClient.getDeletedSecret("old-secret");
System.out.println("Will purge: " + deleted.getName());
secretClient.purgeDeletedSecret("old-secret");

バックアップと復元

// Backup secret (all versions)
byte[] backup = secretClient.backupSecret("important-secret");

// Save to file
Files.write(Paths.get("secret-backup.blob"), backup);

// Restore from backup
byte[] backupData = Files.readAllBytes(Paths.get("secret-backup.blob"));
KeyVaultSecret restored = secretClient.restoreSecretBackup(backupData);
System.out.println("Restored: " + restored.getName());

非同期操作

SecretAsyncClient asyncClient = new SecretClientBuilder()
    .vaultUrl("https://<vault>.vault.azure.net")
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildAsyncClient();

// Set secret async
asyncClient.setSecret("async-secret", "async-value")
    .subscribe(
        secret -> System.out.println("Created: " + secret.getName()),
        error -> System.out.println("Error: " + error.getMessage())
    );

// Get secret async
asyncClient.getSecret("async-secret")
    .subscribe(secret -> { /* consume secret.getValue() without logging it */ });

// List secrets async
asyncClient.listPropertiesOfSecrets()
    .doOnNext(props -> System.out.println("Found: " + props.getName()))
    .subscribe();

設定パターン

複数のシークレットを読み込む
public class ConfigLoader {
    private final SecretClient client;
    
    public ConfigLoader(String vaultUrl) {
        this.client = new SecretClientBuilder()
            .vaultUrl(vaultUrl)
            .credential(new DefaultAzureCredentialBuilder().build())
            .buildClient();
    }
    
    public Map<String, String> loadSecrets(List<String> secretNames) {
        Map<String, String> secrets = new HashMap<>();
        for (String name : secretNames) {
            try {
                KeyVaultSecret secret = client.getSecret(name);
                secrets.put(name, secret.getValue());
            } catch (ResourceNotFoundException e) {
                System.out.println("Secret not found: " + name);
            }
        }
        return secrets;
    }
}

// Usage
ConfigLoader loader = new ConfigLoader("https://my-vault.vault.azure.net");
Map<String, String> config = loader.loadSecrets(
    Arrays.asList("db-connection-string", "api-key", "jwt-secret")
);
シークレットのローテーションパターン
public void rotateSecret(String secretName, String newValue) {
    // Get current secret
    KeyVaultSecret current = secretClient.getSecret(secretName);
    
    // Create and verify the new credential at its issuing service first.
    // Create a new version; migrate and verify consumers before retiring the old one.
    KeyVaultSecret newSecret = secretClient.setSecret(secretName, newValue);
    System.out.println("Rotated to version: " + newSecret.getProperties().getVersion());
}

エラー処理

import com.azure.core.exception.HttpResponseException;
import com.azure.core.exception.ResourceNotFoundException;

try {
    KeyVaultSecret secret = secretClient.getSecret("my-secret");
    // Consume secret.getValue() without logging it.
} catch (ResourceNotFoundException e) {
    System.out.println("Secret not found");
} catch (HttpResponseException e) {
    int status = e.getResponse().getStatusCode();
    if (status == 403) {
        System.out.println("Access denied - check permissions");
    } else if (status == 429) {
        System.out.println("Rate limited - retry later");
    } else {
        System.out.println("HTTP error: " + status);
    }
}

シークレットのプロパティ

プロパティ説明
nameシークレット名
valueシークレットの値(文字列)
id完全な識別子 URL
contentTypeMIME タイプのヒント
enabledシークレットを取得できるかどうか
notBefore有効化時刻
expiresOn有効期限
createdOn作成日時
updatedOn最終更新日時
recoveryLevel論理削除からの復元レベル
tagsユーザー定義のメタデータ

環境変数

AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net

ベストプラクティス

  1. 論理削除を有効にする - 誤削除から保護します
  2. タグを使用する - シークレットに環境、サービス、所有者のタグを付けます
  3. 有効期限を設定する - ローテーションが必要な認証情報には setExpiresOn() を使用します
  4. コンテンツタイプ - 形式(例:application/json)を示すために contentType を設定します
  5. バージョン管理 - ローテーション中に古いバージョンをすぐに削除しないでください
  6. アクセスログ - Key Vault の診断ログを有効にします
  7. 最小権限 - 環境ごとに別々のボールトを使用します

一般的なシークレットの種類

// Database connection string
secretClient.setSecret(new KeyVaultSecret("db-connection", 
    "Server=myserver.database.windows.net;Database=mydb;...")
    .setProperties(new SecretProperties()
        .setContentType("text/plain")
        .setTags(Map.of("type", "connection-string"))));

// API key
secretClient.setSecret(new KeyVaultSecret("stripe-api-key", "sk_live_...")
    .setProperties(new SecretProperties()
        .setContentType("text/plain")
        .setExpiresOn(OffsetDateTime.now().plusYears(1))));

// JSON configuration
secretClient.setSecret(new KeyVaultSecret("app-config", 
    "{\"endpoint\":\"https://...\",\"key\":\"...\"}")
    .setProperties(new SecretProperties()
        .setContentType("application/json")));

// Certificate password
secretClient.setSecret(new KeyVaultSecret("cert-password", "CertP@ss!")
    .setProperties(new SecretProperties()
        .setContentType("text/plain")
        .setTags(Map.of("certificate", "my-cert"))));

トリガーフレーズ

  • 「Key Vault シークレット Java」、「シークレット管理 Java」
  • 「パスワードを保存」、「API キーを保存」、「接続文字列」
  • 「シークレットを取得」、「シークレットをローテーション」
  • 「Azure シークレット」、「ボールトのシークレット」

使用するタイミング

このスキルは、概要に記載されたワークフローやアクションを実行する場合に適用できます。

制限事項

  • タスクが上記の説明された範囲に明確に一致する場合にのみ、このスキルを使用してください。
  • 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を止めて確認してください。

コメント