GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-security-keyvault-secrets-java

Azure Key Vault Secrets Java SDK for secret management. Use when storing, retrieving, or managing passwords, API keys, connection strings, or other sensitive configuration data.

Ciza · 0 points · 16 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_plugins_azure-sdk-java_skills_azure-security-keyvault-secrets-java-e58528d.zip · 6 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-java/skills/azure-security-keyvault-secrets-java
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git git clone https://github.com/microsoft/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Azure Key Vault Secrets (Java)

Securely store and manage secrets like passwords, API keys, and connection strings.

Installation

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

Client Creation

import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;

// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
TokenCredential credential = new DefaultAzureCredentialBuilder()
    .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
    .build();
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
// TokenCredential credential = new ManagedIdentityCredentialBuilder().build();

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

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

Create/Set Secret

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 Secret

// Get latest version
KeyVaultSecret secret = secretClient.getSecret("database-password");
String value = secret.getValue();
System.out.println("Secret value: " + value);

// 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());

Update Secret Properties

// 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());

List Secrets

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());
        System.out.println("  Value: " + fullSecret.getValue().substring(0, 5) + "...");
    }
}

// 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());
}

Delete Secret

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();

Recover Deleted Secret

// 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 = recoverPoller.getFinalResult();
System.out.println("Recovered: " + recovered.getName());

Purge Deleted Secret

// Permanently delete (cannot be recovered)
secretClient.purgeDeletedSecret("old-secret");

// Get deleted secret info first
DeletedSecret deleted = secretClient.getDeletedSecret("old-secret");
System.out.println("Will purge: " + deleted.getName());
secretClient.purgeDeletedSecret("old-secret");

Backup and Restore

// 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());

Async Operations

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 -> System.out.println("Value: " + secret.getValue()));

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

Configuration Patterns

Load Multiple Secrets

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")
);

Secret Rotation Pattern

public void rotateSecret(String secretName, String newValue) {
    // Get current secret
    KeyVaultSecret current = secretClient.getSecret(secretName);
    
    // Disable old version
    current.getProperties().setEnabled(false);
    secretClient.updateSecretProperties(current.getProperties());
    
    // Create new version with new value
    KeyVaultSecret newSecret = secretClient.setSecret(secretName, newValue);
    System.out.println("Rotated to version: " + newSecret.getProperties().getVersion());
}

Error Handling

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

try {
    KeyVaultSecret secret = secretClient.getSecret("my-secret");
    System.out.println("Value: " + secret.getValue());
} 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);
    }
}

Secret Properties

Property Description
name Secret name
value Secret value (string)
id Full identifier URL
contentType MIME type hint
enabled Whether secret can be retrieved
notBefore Activation time
expiresOn Expiration time
createdOn Creation timestamp
updatedOn Last update timestamp
recoveryLevel Soft-delete recovery level
tags User-defined metadata

Environment Variables

AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net  # Required for vault URL
AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production

Best Practices

  1. Enable Soft Delete - Protects against accidental deletion
  2. Use Tags - Tag secrets with environment, service, owner
  3. Set Expiration - Use setExpiresOn() for credentials that should rotate
  4. Content Type - Set contentType to indicate format (e.g., application/json)
  5. Version Management - Don't delete old versions immediately during rotation
  6. Access Logging - Enable diagnostic logging on Key Vault
  7. Least Privilege - Use separate vaults for different environments

Common Secret Types

// 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"))));

Trigger Phrases

  • "Key Vault secrets Java", "secret management Java"
  • "store password", "store API key", "connection string"
  • "retrieve secret", "rotate secret"
  • "Azure secrets", "vault secrets"
Files (skills)
  • references
    • examples.md 11.7 KB
      # Azure Key Vault Secrets SDK for Java - Examples
      
      Comprehensive code examples for the Azure Key Vault Secrets SDK for Java.
      
      ## Table of Contents
      - [Maven Dependency](#maven-dependency)
      - [Client Creation](#client-creation)
      - [Setting Secrets](#setting-secrets)
      - [Getting Secrets](#getting-secrets)
      - [Listing Secrets](#listing-secrets)
      - [Updating Secret Properties](#updating-secret-properties)
      - [Deleting and Recovering Secrets](#deleting-and-recovering-secrets)
      - [Purging Deleted Secrets](#purging-deleted-secrets)
      - [Backup and Restore](#backup-and-restore)
      - [Async Client Patterns](#async-client-patterns)
      - [Error Handling](#error-handling)
      
      ## Maven Dependency
      
      ```xml
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-security-keyvault-secrets</artifactId>
          <version>4.11.0-beta.1</version>
      </dependency>
      
      <!-- Required for authentication -->
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-identity</artifactId>
          <version>1.18.2</version>
      </dependency>
      ```
      
      ## Client Creation
      
      ### Sync SecretClient
      
      ```java
      import com.azure.identity.DefaultAzureCredentialBuilder;
      import com.azure.security.keyvault.secrets.SecretClient;
      import com.azure.security.keyvault.secrets.SecretClientBuilder;
      
      SecretClient secretClient = new SecretClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .vaultUrl("<your-key-vault-url>")
          .buildClient();
      ```
      
      ### Async SecretClient
      
      ```java
      import com.azure.security.keyvault.secrets.SecretAsyncClient;
      
      SecretAsyncClient secretAsyncClient = new SecretClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .vaultUrl("<your-key-vault-url>")
          .buildAsyncClient();
      ```
      
      ## Setting Secrets
      
      ### Simple Secret
      
      ```java
      import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
      
      KeyVaultSecret secret = secretClient.setSecret("<secret-name>", "<secret-value>");
      System.out.printf("Secret created with name \"%s\" and value \"%s\"%n", 
          secret.getName(), secret.getValue());
      ```
      
      ### Secret with Properties (Expiration)
      
      ```java
      import com.azure.security.keyvault.secrets.models.SecretProperties;
      import java.time.OffsetDateTime;
      
      KeyVaultSecret newSecret = new KeyVaultSecret("secretName", "secretValue")
          .setProperties(new SecretProperties().setExpiresOn(OffsetDateTime.now().plusDays(60)));
      
      KeyVaultSecret returnedSecret = secretClient.setSecret(newSecret);
      System.out.printf("Secret created with name %s and value %s%n", 
          returnedSecret.getName(), returnedSecret.getValue());
      ```
      
      ### With Response (includes HTTP metadata)
      
      ```java
      import com.azure.core.util.Context;
      
      KeyVaultSecret newSecret = new KeyVaultSecret("secretName", "secretValue")
          .setProperties(new SecretProperties().setExpiresOn(OffsetDateTime.now().plusDays(60)));
      
      KeyVaultSecret secret = secretClient.setSecretWithResponse(newSecret, new Context("key1", "value1"))
          .getValue();
      System.out.printf("Secret created with name %s%n", secret.getName());
      ```
      
      ## Getting Secrets
      
      ### Get Current Version
      
      ```java
      KeyVaultSecret secret = secretClient.getSecret("secretName");
      System.out.printf("Secret returned with name %s and value %s%n",
          secret.getName(), secret.getValue());
      ```
      
      ### Get Specific Version
      
      ```java
      String secretVersion = "6A385B124DEF4096AF1361A85B16C204";
      KeyVaultSecret secretWithVersion = secretClient.getSecret("secretName", secretVersion);
      System.out.printf("Secret returned with name %s and value %s%n",
          secretWithVersion.getName(), secretWithVersion.getValue());
      ```
      
      ### Get with Response
      
      ```java
      import com.azure.core.util.Context;
      
      String secretVersion = "6A385B124DEF4096AF1361A85B16C204";
      KeyVaultSecret secret = secretClient.getSecretWithResponse(
          "secretName", 
          secretVersion,
          new Context("key1", "value1")
      ).getValue();
      System.out.printf("Secret returned with name %s%n", secret.getName());
      ```
      
      ## Listing Secrets
      
      ### List All Secrets
      
      ```java
      import com.azure.security.keyvault.secrets.models.SecretProperties;
      
      // Note: List operations don't return secret values - call getSecret for each
      for (SecretProperties secretProps : secretClient.listPropertiesOfSecrets()) {
          KeyVaultSecret secretWithValue = secretClient.getSecret(
              secretProps.getName(), 
              secretProps.getVersion()
          );
          System.out.printf("Secret: %s = %s%n", 
              secretWithValue.getName(), 
              secretWithValue.getValue());
      }
      ```
      
      ### List with Pagination
      
      ```java
      secretClient.listPropertiesOfSecrets().iterableByPage().forEach(page -> {
          System.out.printf("Status code: %d, URL: %s%n", 
              page.getStatusCode(), 
              page.getRequest().getUrl());
          
          page.getItems().forEach(secretProps -> {
              KeyVaultSecret secret = secretClient.getSecret(
                  secretProps.getName(), 
                  secretProps.getVersion()
              );
              System.out.printf("Secret: %s%n", secret.getName());
          });
      });
      ```
      
      ### List Secret Versions
      
      ```java
      for (SecretProperties secretProps : secretClient.listPropertiesOfSecretVersions("secretName")) {
          KeyVaultSecret secret = secretClient.getSecret(
              secretProps.getName(), 
              secretProps.getVersion()
          );
          System.out.printf("Version: %s, Value: %s%n", 
              secretProps.getVersion(), 
              secret.getValue());
      }
      ```
      
      ## Updating Secret Properties
      
      ```java
      // Get the secret first
      SecretProperties secretProperties = secretClient.getSecret("secretName").getProperties();
      
      // Update the expiry time
      secretProperties.setExpiresOn(OffsetDateTime.now().plusDays(60));
      SecretProperties updatedProperties = secretClient.updateSecretProperties(secretProperties);
      
      // Get the updated secret
      KeyVaultSecret updatedSecret = secretClient.getSecret(updatedProperties.getName());
      System.out.printf("Updated secret expires: %s%n", 
          updatedSecret.getProperties().getExpiresOn());
      ```
      
      **Note**: `updateSecretProperties()` cannot change the secret value - only metadata like expiration, enabled status, tags, etc. To change the value, call `setSecret()` which creates a new version.
      
      ## Deleting and Recovering Secrets
      
      ### Delete Secret (with Polling)
      
      ```java
      import com.azure.core.util.polling.PollResponse;
      import com.azure.core.util.polling.SyncPoller;
      import com.azure.security.keyvault.secrets.models.DeletedSecret;
      
      SyncPoller<DeletedSecret, Void> deleteSecretPoller = secretClient.beginDeleteSecret("secretName");
      
      // Deleted Secret is accessible as soon as polling begins
      PollResponse<DeletedSecret> pollResponse = deleteSecretPoller.poll();
      
      // Deletion date only works for SoftDelete-enabled Key Vault
      System.out.printf("Deleted Date: %s%n", pollResponse.getValue().getDeletedOn());
      System.out.printf("Recovery Id: %s%n", pollResponse.getValue().getRecoveryId());
      
      // Wait for deletion to complete on server
      deleteSecretPoller.waitForCompletion();
      ```
      
      ### Get Deleted Secret
      
      ```java
      DeletedSecret deletedSecret = secretClient.getDeletedSecret("secretName");
      System.out.printf("Recovery Id: %s%n", deletedSecret.getRecoveryId());
      ```
      
      ### List Deleted Secrets
      
      ```java
      for (DeletedSecret deletedSecret : secretClient.listDeletedSecrets()) {
          System.out.printf("Deleted secret: %s, Recovery Id: %s%n", 
              deletedSecret.getName(),
              deletedSecret.getRecoveryId());
      }
      ```
      
      ### Recover Deleted Secret
      
      ```java
      SyncPoller<KeyVaultSecret, Void> recoverPoller = 
          secretClient.beginRecoverDeletedSecret("deletedSecretName");
      
      // Recovered secret accessible as soon as polling begins
      PollResponse<KeyVaultSecret> pollResponse = recoverPoller.poll();
      System.out.printf("Recovered secret: %s%n", pollResponse.getValue().getName());
      
      // Wait for recovery to complete on server
      recoverPoller.waitForCompletion();
      ```
      
      ## Purging Deleted Secrets
      
      ```java
      // Permanently delete (cannot be recovered after this)
      secretClient.purgeDeletedSecret("secretName");
      System.out.println("Secret purged permanently");
      ```
      
      ## Backup and Restore
      
      ### Backup Secret
      
      ```java
      byte[] secretBackup = secretClient.backupSecret("secretName");
      System.out.printf("Secret backup size: %d bytes%n", secretBackup.length);
      
      // Store the backup securely (e.g., to a file or blob storage)
      ```
      
      ### Restore Secret
      
      ```java
      // Restore from backup bytes
      KeyVaultSecret restoredSecret = secretClient.restoreSecretBackup(secretBackup);
      System.out.printf("Restored secret: %s%n", restoredSecret.getName());
      ```
      
      ## Async Client Patterns
      
      ### Set Secret Async
      
      ```java
      secretAsyncClient.setSecret("asyncSecretName", "asyncSecretValue")
          .subscribe(
              secret -> System.out.printf("Created secret: %s%n", secret.getName()),
              error -> System.err.println("Error: " + error.getMessage()),
              () -> System.out.println("Operation completed")
          );
      ```
      
      ### Get Secret Async
      
      ```java
      secretAsyncClient.getSecret("secretName")
          .subscribe(
              secret -> System.out.printf("Secret value: %s%n", secret.getValue()),
              error -> System.err.println("Error: " + error.getMessage())
          );
      ```
      
      ### List Secrets Async
      
      ```java
      secretAsyncClient.listPropertiesOfSecrets()
          .flatMap(secretProps -> secretAsyncClient.getSecret(
              secretProps.getName(), 
              secretProps.getVersion()
          ))
          .subscribe(
              secret -> System.out.printf("Secret: %s%n", secret.getName()),
              error -> System.err.println("Error: " + error.getMessage())
          );
      ```
      
      ### Delete Secret Async
      
      ```java
      secretAsyncClient.beginDeleteSecret("secretName")
          .subscribe(pollResponse -> {
              System.out.printf("Delete status: %s%n", pollResponse.getStatus());
              System.out.printf("Deleted secret: %s%n", pollResponse.getValue().getName());
          });
      ```
      
      ### Chain Operations
      
      ```java
      secretAsyncClient.setSecret("mySecret", "myValue")
          .flatMap(created -> {
              System.out.printf("Created: %s%n", created.getName());
              return secretAsyncClient.getSecret(created.getName());
          })
          .flatMap(retrieved -> {
              System.out.printf("Retrieved: %s%n", retrieved.getValue());
              retrieved.getProperties().setExpiresOn(OffsetDateTime.now().plusDays(30));
              return secretAsyncClient.updateSecretProperties(retrieved.getProperties());
          })
          .subscribe(
              updated -> System.out.printf("Updated, expires: %s%n", updated.getExpiresOn()),
              error -> System.err.println("Error: " + error.getMessage())
          );
      ```
      
      ## Error Handling
      
      ### Sync Error Handling
      
      ```java
      import com.azure.core.exception.HttpResponseException;
      import com.azure.core.exception.ResourceNotFoundException;
      
      try {
          KeyVaultSecret secret = secretClient.getSecret("nonexistent-secret");
      } catch (ResourceNotFoundException e) {
          System.err.println("Secret not found: " + e.getMessage());
      } catch (HttpResponseException e) {
          System.err.println("HTTP error: " + e.getResponse().getStatusCode());
          System.err.println("Message: " + e.getMessage());
      } catch (Exception e) {
          System.err.println("Unexpected error: " + e.getMessage());
      }
      ```
      
      ### Async Error Handling
      
      ```java
      secretAsyncClient.getSecret("nonexistent-secret")
          .subscribe(
              secret -> System.out.println("Secret: " + secret.getName()),
              error -> {
                  if (error instanceof ResourceNotFoundException) {
                      System.err.println("Secret not found");
                  } else if (error instanceof HttpResponseException) {
                      HttpResponseException httpError = (HttpResponseException) error;
                      System.err.println("HTTP error: " + httpError.getResponse().getStatusCode());
                  } else {
                      System.err.println("Error: " + error.getMessage());
                  }
              }
          );
      ```
      
      ### Common Error Scenarios
      
      | Status Code | Exception | Cause |
      |-------------|-----------|-------|
      | 401 | ClientAuthenticationException | Invalid credentials |
      | 403 | HttpResponseException | Access denied (missing permissions) |
      | 404 | ResourceNotFoundException | Secret not found |
      | 409 | HttpResponseException | Conflict (secret already exists/deleted) |
      | 429 | HttpResponseException | Rate limited |
      
  • SKILL.md 11.9 KB
    ---
    name: azure-security-keyvault-secrets-java
    description: Azure Key Vault Secrets Java SDK for secret management. Use when storing, retrieving, or managing passwords, API keys, connection strings, or other sensitive configuration data.
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: com.azure:azure-security-keyvault-secrets
    ---
    
    # Azure Key Vault Secrets (Java)
    
    Securely store and manage secrets like passwords, API keys, and connection strings.
    
    ## Installation
    
    ```xml
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-security-keyvault-secrets</artifactId>
        <version>4.9.0</version>
    </dependency>
    ```
    
    ## Client Creation
    
    ```java
    import com.azure.core.credential.TokenCredential;
    import com.azure.identity.AzureIdentityEnvVars;
    import com.azure.identity.DefaultAzureCredentialBuilder;
    import com.azure.identity.ManagedIdentityCredentialBuilder;
    import com.azure.security.keyvault.secrets.SecretClient;
    import com.azure.security.keyvault.secrets.SecretClientBuilder;
    
    // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
    TokenCredential credential = new DefaultAzureCredentialBuilder()
        .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
        .build();
    // Or use a specific credential directly in production:
    // See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
    // TokenCredential credential = new ManagedIdentityCredentialBuilder().build();
    
    // Sync client
    SecretClient secretClient = new SecretClientBuilder()
        .vaultUrl("https://<vault-name>.vault.azure.net")
        .credential(credential)
        .buildClient();
    
    // Async client
    SecretAsyncClient secretAsyncClient = new SecretClientBuilder()
        .vaultUrl("https://<vault-name>.vault.azure.net")
        .credential(credential)
        .buildAsyncClient();
    ```
    
    ## Create/Set Secret
    
    ```java
    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 Secret
    
    ```java
    // Get latest version
    KeyVaultSecret secret = secretClient.getSecret("database-password");
    String value = secret.getValue();
    System.out.println("Secret value: " + value);
    
    // 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());
    ```
    
    ## Update Secret Properties
    
    ```java
    // 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());
    ```
    
    ## List Secrets
    
    ```java
    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());
            System.out.println("  Value: " + fullSecret.getValue().substring(0, 5) + "...");
        }
    }
    
    // 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());
    }
    ```
    
    ## Delete Secret
    
    ```java
    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();
    ```
    
    ## Recover Deleted Secret
    
    ```java
    // 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 = recoverPoller.getFinalResult();
    System.out.println("Recovered: " + recovered.getName());
    ```
    
    ## Purge Deleted Secret
    
    ```java
    // Permanently delete (cannot be recovered)
    secretClient.purgeDeletedSecret("old-secret");
    
    // Get deleted secret info first
    DeletedSecret deleted = secretClient.getDeletedSecret("old-secret");
    System.out.println("Will purge: " + deleted.getName());
    secretClient.purgeDeletedSecret("old-secret");
    ```
    
    ## Backup and Restore
    
    ```java
    // 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());
    ```
    
    ## Async Operations
    
    ```java
    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 -> System.out.println("Value: " + secret.getValue()));
    
    // List secrets async
    asyncClient.listPropertiesOfSecrets()
        .doOnNext(props -> System.out.println("Found: " + props.getName()))
        .subscribe();
    ```
    
    ## Configuration Patterns
    
    ### Load Multiple Secrets
    
    ```java
    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")
    );
    ```
    
    ### Secret Rotation Pattern
    
    ```java
    public void rotateSecret(String secretName, String newValue) {
        // Get current secret
        KeyVaultSecret current = secretClient.getSecret(secretName);
        
        // Disable old version
        current.getProperties().setEnabled(false);
        secretClient.updateSecretProperties(current.getProperties());
        
        // Create new version with new value
        KeyVaultSecret newSecret = secretClient.setSecret(secretName, newValue);
        System.out.println("Rotated to version: " + newSecret.getProperties().getVersion());
    }
    ```
    
    ## Error Handling
    
    ```java
    import com.azure.core.exception.HttpResponseException;
    import com.azure.core.exception.ResourceNotFoundException;
    
    try {
        KeyVaultSecret secret = secretClient.getSecret("my-secret");
        System.out.println("Value: " + secret.getValue());
    } 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);
        }
    }
    ```
    
    ## Secret Properties
    
    | Property | Description |
    |----------|-------------|
    | `name` | Secret name |
    | `value` | Secret value (string) |
    | `id` | Full identifier URL |
    | `contentType` | MIME type hint |
    | `enabled` | Whether secret can be retrieved |
    | `notBefore` | Activation time |
    | `expiresOn` | Expiration time |
    | `createdOn` | Creation timestamp |
    | `updatedOn` | Last update timestamp |
    | `recoveryLevel` | Soft-delete recovery level |
    | `tags` | User-defined metadata |
    
    ## Environment Variables
    
    ```bash
    AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net  # Required for vault URL
    AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production
    ```
    
    ## Best Practices
    
    1. **Enable Soft Delete** - Protects against accidental deletion
    2. **Use Tags** - Tag secrets with environment, service, owner
    3. **Set Expiration** - Use `setExpiresOn()` for credentials that should rotate
    4. **Content Type** - Set `contentType` to indicate format (e.g., `application/json`)
    5. **Version Management** - Don't delete old versions immediately during rotation
    6. **Access Logging** - Enable diagnostic logging on Key Vault
    7. **Least Privilege** - Use separate vaults for different environments
    
    ## Common Secret Types
    
    ```java
    // 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"))));
    ```
    
    ## Trigger Phrases
    
    - "Key Vault secrets Java", "secret management Java"
    - "store password", "store API key", "connection string"
    - "retrieve secret", "rotate secret"
    - "Azure secrets", "vault secrets"
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related