KeyVault JCA: lazy-load certificate material and add alias regex filtering#49774
KeyVault JCA: lazy-load certificate material and add alias regex filtering#49774rujche wants to merge 30 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances azure-security-keyvault-jca to reduce unnecessary Key Vault reads by (1) allowing users to configure a subset of certificate aliases to consider and (2) lazily loading certificate details only when a specific alias is requested—addressing the scenario described in #39487 (iterating/fetching all aliases when only one is configured).
Changes:
- Added
azure.keyvault.jca.certificatessystem property support to filter Key Vault certificate aliases to a configured subset. - Implemented lazy loading of Key Vault certificate key/certificate/chain data per alias (instead of eagerly loading all details on refresh).
- Updated tests and documentation (README + CHANGELOG) to cover and describe the new behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java | Wires configured alias filtering into keystore initialization and routes Key Vault lookups through lazy-loading accessors. |
| sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/implementation/certificates/KeyVaultCertificates.java | Implements configured-alias filtering and lazy loading of certificate details per alias. |
| sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/KeyVaultKeyStoreUnitTest.java | Adds unit coverage for parsing configured aliases and verifying they are passed into KeyVaultCertificates. |
| sdk/keyvault/azure-security-keyvault-jca/src/test/java/com/azure/security/keyvault/jca/implementation/certificates/KeyVaultCertificatesTest.java | Adds unit coverage ensuring alias listing is not eager and that only requested/configured aliases trigger Key Vault reads. |
| sdk/keyvault/azure-security-keyvault-jca/README.md | Documents the new azure.keyvault.jca.certificates configuration option. |
| sdk/keyvault/azure-security-keyvault-jca/CHANGELOG.md | Records the new filtering + lazy-loading features for the upcoming release. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/KeyVaultKeyStore.java:291
- With the new lazy Key Vault loading,
engineGetCertificate(candidateAlias)can legitimately returnnulleven for aliases returned bygetAllAliases()(e.g., transient failure / permission issue).engineGetCertificateAliascurrently callscertificate.equals(cert)without a null check, which can throw aNullPointerExceptionduring alias lookup.
certificate = keyVaultCertificates.getCertificate(alias);
}
return certificate;
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
sdk/keyvault/azure-security-keyvault-jca/src/main/java/com/azure/security/keyvault/jca/implementation/certificates/KeyVaultCertificates.java:300
- The inline comment says this outer check avoids acquiring the lock, but certificatesNeedRefresh() is synchronized and always acquires the instance monitor. This is misleading when reasoning about contention; either adjust the comment or change the locking strategy.
private void refreshCertificatesIfNeeded() {
if (certificatesNeedRefresh()) { // Avoid acquiring the lock as much as possible.
synchronized (this) {
if (certificatesNeedRefresh()) { // After obtaining the lock, avoid doing too many operations.
refreshCertificates();
}
| private Pattern compileRegexPattern(String regexPattern) { | ||
| try { | ||
| return Pattern.compile(regexPattern); | ||
| } catch (PatternSyntaxException exception) { | ||
| throw new IllegalArgumentException("Invalid certificate filter regex pattern: " + regexPattern, exception); | ||
| } |
| this.refreshInterval = refreshInterval; | ||
| this.certificateFilterPatterns | ||
| = new HashSet<>(Optional.ofNullable(certificateFilterPatterns).orElse(Collections.emptySet())); | ||
| this.includeAliasPatterns = getAliasPatterns(this.certificateFilterPatterns, false); | ||
| this.excludeAliasPatterns = getAliasPatterns(this.certificateFilterPatterns, true); |
| public KeyVaultCertificates(long refreshInterval, KeyVaultClient keyVaultClient, | ||
| Set<String> certificateFilterPatterns) { | ||
| this.refreshInterval = refreshInterval; | ||
| setKeyVaultClient(keyVaultClient); | ||
| this.certificateFilterPatterns | ||
| = new HashSet<>(Optional.ofNullable(certificateFilterPatterns).orElse(Collections.emptySet())); | ||
| this.includeAliasPatterns = getAliasPatterns(this.certificateFilterPatterns, false); | ||
| this.excludeAliasPatterns = getAliasPatterns(this.certificateFilterPatterns, true); | ||
| } |
Description
This PR completes #39487 in
azure-security-keyvault-jcaand also finalizes the follow-up lazy-loading/thread-safety refinements requested during review.What changed
KeyVaultCertificatesfor certificate, key, and certificate chain by alias.azure.keyvault.jca.certificate-alias-filter-patterns!.KeyVaultCertificates:KeyVaultKeyStorelookup pathing and filter-pattern parsing.README.md,CHANGELOG.md).KeyVaultKeyStoreUnitTestKeyVaultCertificatesTestValidation
mvn -f sdk/keyvault/azure-security-keyvault-jca/pom.xml -Dtest=KeyVaultKeyStoreUnitTest,com.azure.security.keyvault.jca.implementation.certificates.KeyVaultCertificatesTest testNotes
azure.keyvault.jca.certificate-alias-filter-patternsfor clearer semantics.All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines