What This Skill Does
The Azure Key Vault Secrets SDK for Java provides secure storage and management of secrets like passwords, API keys, connection strings, and certificates. This skill enables agents to store sensitive configuration securely, retrieve secrets at runtime, manage secret lifecycles with expiration and activation dates, and maintain audit trails of secret access.
Unlike storing secrets in environment variables, configuration files, or code, Key Vault provides encryption at rest, access auditing, soft-delete protection, and centralized management. Secrets can have expiration dates, activation dates, and tags for organization. Multiple versions of each secret enable rotation without downtime.
The SDK's integration with Azure managed identities means applications can retrieve secrets without storing credentials - the application's identity itself grants access. This eliminates the "secret zero" problem where you need credentials to get credentials.
Getting Started
Add the Maven dependency:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-secrets</artifactId>
<version>4.9.0</version>
</dependency>
Create a client with DefaultAzureCredential:
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;
SecretClient secretClient = new SecretClientBuilder()
.vaultUrl("https://<vault-name>.vault.azure.net")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
Key Features
Secure Secret Storage: Store sensitive values encrypted at rest with FIPS 140-2 Level 2 validated HSMs (Hardware Security Modules). Secrets never leave Azure unencrypted.
Versioning: Every secret update creates a new version while preserving old versions. Enable zero-downtime rotation by deploying applications with old versions before disabling them.
Lifecycle Management: Set activation dates (notBefore) and expiration dates (expiresOn) for secrets. Implement automated rotation policies and compliance requirements.
Soft Delete: Deleted secrets remain recoverable for a retention period (7-90 days). Protects against accidental deletion and enables recovery.
Access Control: Fine-grained RBAC (Role-Based Access Control) determines who can read, write, or manage secrets. Separate permissions for secret values versus metadata.
Audit Logging: Diagnostic logging captures all secret operations (read, write, delete) with timestamps, caller identity, and IP addresses. Essential for compliance and security investigations.
Tags and Metadata: Attach tags to secrets for categorization, ownership tracking, or environment identification. Query secrets by tag for bulk operations.
Read-Only Mode: Lock secrets to prevent modification or deletion. Critical for production secrets that should only change through formal change management.
Usage Examples
Basic secret operations:
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
import com.azure.security.keyvault.secrets.models.SecretProperties;
// Create secret
KeyVaultSecret secret = secretClient.setSecret("database-password", "P@ssw0rd123!");
// Get secret
KeyVaultSecret retrieved = secretClient.getSecret("database-password");
String password = retrieved.getValue();
System.out.println("Using password: " + password.substring(0, 3) + "***");
// Get specific version
KeyVaultSecret version = secretClient.getSecret("database-password", "<version-id>");
// Delete secret (soft delete)
secretClient.beginDeleteSecret("old-api-key").waitForCompletion();
Secret with lifecycle properties:
KeyVaultSecret secretWithOptions = secretClient.setSecret(
new KeyVaultSecret("api-key", "sk_live_abc123xyz")
.setProperties(new SecretProperties()
.setContentType("text/plain")
.setExpiresOn(OffsetDateTime.now().plusYears(1))
.setNotBefore(OffsetDateTime.now())
.setEnabled(true)
.setTags(Map.of(
"environment", "production",
"service", "payment-api",
"owner", "platform-team"
))
)
);
List and filter secrets:
// List all secrets (properties only, no values)
for (SecretProperties props : secretClient.listPropertiesOfSecrets()) {
System.out.println("Secret: " + props.getName());
System.out.println(" Enabled: " + props.isEnabled());
System.out.println(" Expires: " + props.getExpiresOn());
if (props.getTags().containsKey("environment") &&
props.getTags().get("environment").equals("production")) {
// Production secret - handle carefully
}
}
// List versions of a secret
for (SecretProperties version : secretClient.listPropertiesOfSecretVersions("api-key")) {
System.out.println("Version: " + version.getVersion());
System.out.println("Created: " + version.getCreatedOn());
}
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());
// Old version remains accessible for rollback if needed
}
Backup and restore:
// Backup secret (all versions)
byte[] backup = secretClient.backupSecret("critical-secret");
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);
Best Practices
Enable soft delete on vaults. Soft delete is now mandatory for new vaults and protects against accidental deletion. Set appropriate retention periods (7-90 days).
Use tags for organization and automation:
secretProps.setTags(Map.of(
"environment", "prod",
"rotation-days", "90",
"owner", "platform-team",
"cost-center", "engineering"
));
Set expiration dates for rotating secrets. Implement monitoring to alert before expiration:
secretProps.setExpiresOn(OffsetDateTime.now().plusDays(90));
Don't delete old versions immediately after rotation. Keep at least one previous version for rollback in case new secret causes issues.
Use DefaultAzureCredential, never embedded keys:
// Good - uses managed identity in Azure
new DefaultAzureCredentialBuilder().build()
// Bad - hard-coded credentials
new ClientSecretCredential(tenantId, clientId, clientSecret)
Set read-only for critical production secrets:
import com.azure.security.keyvault.secrets.models.SecretProperties;
SecretProperties props = secretClient.getSecret("production-db").getProperties();
props.setRecoveryLevel("Purgeable"); // or "Recoverable+ProtectedSubscription"
secretClient.updateSecretProperties(props);
Use async client for high-throughput scenarios:
import com.azure.security.keyvault.secrets.SecretAsyncClient;
SecretAsyncClient asyncClient = new SecretClientBuilder()
.vaultUrl(vaultUrl)
.credential(new DefaultAzureCredentialBuilder().build())
.buildAsyncClient();
asyncClient.getSecret("api-key")
.subscribe(secret -> useSecret(secret.getValue()));
Handle errors appropriately:
import com.azure.core.exception.ResourceNotFoundException;
try {
KeyVaultSecret secret = secretClient.getSecret("may-not-exist");
} catch (ResourceNotFoundException e) {
System.err.println("Secret not found - using default");
} catch (HttpResponseException e) {
if (e.getResponse().getStatusCode() == 403) {
System.err.println("Access denied - check permissions");
}
}
When to Use This Skill
Use Azure Key Vault Secrets for storing application passwords, API keys, connection strings, encryption keys, or any sensitive configuration that shouldn't be in code or environment variables.
This skill excels at centralizing secrets for microservices architectures. Multiple services can reference the same secrets without duplication, and rotation happens in one place.
Choose this skill when compliance requires audit trails of secret access. Key Vault logs all operations with caller identity and timestamp.
It's perfect for CI/CD pipelines needing secrets. Use managed identities or service principals to grant pipelines access without storing credentials in pipeline definitions.
Use it when secrets need lifecycle management. Implement expiration dates, rotation policies, and version management without custom code.
When NOT to Use This Skill
Avoid Key Vault for high-frequency secret access (thousands per second). Cache secrets locally and refresh periodically rather than fetching on every request. API call latency makes it unsuitable for hot paths.
Don't use it for non-secret configuration. Regular application settings belong in App Configuration, not Key Vault. Use Key Vault for passwords, keys, and connection strings only.
Skip Key Vault for client-side applications accessing secrets directly. End-user devices shouldn't have Key Vault access - fetch secrets server-side.
Avoid storing large binary data. Key Vault is optimized for small secrets (up to 25KB). For large files, use Azure Storage with access keys stored in Key Vault.
Don't use it as a general-purpose database. Key Vault stores secrets, not application data.
Related Skills
- azure-appconfiguration-java - Reference Key Vault secrets from App Configuration
- azure-identity - Managed identity authentication for Key Vault access
- azure-security-keyvault-keys - Manage cryptographic keys (separate from secrets)
Source
Official SDK: azure-sdk-for-java/sdk/keyvault/azure-security-keyvault-secrets
API Documentation: Azure Key Vault