From f340568c1323b405a17cb2771ca0d6d6fc52db31 Mon Sep 17 00:00:00 2001 From: Vedant Jaiswal Date: Wed, 4 Mar 2026 13:25:32 -0800 Subject: [PATCH 1/5] Add Post-Quantum TLS support --- README.md | 16 +++++++++ pom.xml | 5 +++ .../secretsmanager/caching/SecretCache.java | 18 ++++++++-- .../caching/SecretCacheConfiguration.java | 36 ++++++++++++++++++- .../caching/SecretCacheTest.java | 26 ++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 03745d9..90c8211 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,22 @@ public class SampleClass implements RequestHandler { } ``` +### Enabling Post-Quantum TLS + +To enable Post-Quantum TLS for enhanced security: + +```java +import com.amazonaws.secretsmanager.caching.SecretCache; +import com.amazonaws.secretsmanager.caching.SecretCacheConfiguration; + +SecretCache cache = new SecretCache( + new SecretCacheConfiguration() + .withPostQuantumTlsEnabled(true) +); + +String secret = cache.getSecretString("my-secret-id"); +``` + ## License This library is licensed under the Apache 2.0 License. diff --git a/pom.xml b/pom.xml index 34c71b2..9565d34 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,11 @@ secretsmanager 2.41.3 + + software.amazon.awssdk + aws-crt-client + 2.41.3 + org.testng testng diff --git a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java index d0c2672..0731468 100644 --- a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java +++ b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java @@ -23,6 +23,7 @@ import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder; import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse; +import software.amazon.awssdk.http.crt.AwsCrtHttpClient; /** * Provides the primary entry-point to the AWS Secrets Manager client cache SDK. @@ -101,8 +102,21 @@ public SecretCache(SecretCacheConfiguration config) { this.config = config; ClientOverrideConfiguration defaultOverride = ClientOverrideConfiguration.builder() .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, VersionInfo.USER_AGENT).build(); - this.client = config.getClient() != null ? config.getClient() - : SecretsManagerClient.builder().overrideConfiguration(defaultOverride).build(); + + if (config.getClient() != null) { + this.client = config.getClient(); + } else if (config.isPostQuantumTlsEnabled()) { + this.client = SecretsManagerClient.builder() + .httpClient(AwsCrtHttpClient.builder() + .postQuantumTlsEnabled(true) + .build()) + .overrideConfiguration(defaultOverride) + .build(); + } else { + this.client = SecretsManagerClient.builder() + .overrideConfiguration(defaultOverride) + .build(); + } } /** diff --git a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java index 744ebbd..5a072ae 100644 --- a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java +++ b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java @@ -18,7 +18,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; - /** * Cache configuration options such as max cache size, ttl for cached items, etc. * @@ -73,6 +72,11 @@ public class SecretCacheConfiguration { */ private long forceRefreshJitterMillis = DEFAULT_FORCE_REFRESH_JITTER; + /** + * Whether to enable Post-Quantum TLS. + * */ + private boolean postQuantumTlsEnabled = false; + /** * Default constructor for the SecretCacheConfiguration object. * @@ -291,4 +295,34 @@ public SecretCacheConfiguration withForceRefreshJitterMillis(long forceRefreshJi return this; } + /** + * Returns whether Post-Quantum TLS is enabled. + * + * @return true if Post-Quantum TLS is enabled, false otherwise. + */ + public boolean isPostQuantumTlsEnabled() { + return this.postQuantumTlsEnabled; + } + + /** + * Sets whether to enable Post-Quantum TLS. + * + * @param postQuantumTlsEnabled + * Whether to enable Post-Quantum TLS. + */ + public void setPostQuantumTlsEnabled(boolean postQuantumTlsEnabled) { + this.postQuantumTlsEnabled = postQuantumTlsEnabled; + } + + /** + * Sets whether to enable Post-Quantum TLS. + * + * @param postQuantumTlsEnabled + * Whether to enable Post-Quantum TLS. + * @return The updated SecretCacheConfiguration object with the new PQTLS setting. + */ + public SecretCacheConfiguration withPostQuantumTlsEnabled(boolean postQuantumTlsEnabled) { + this.setPostQuantumTlsEnabled(postQuantumTlsEnabled); + return this; + } } diff --git a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java index 4f4e93b..4e19f17 100644 --- a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java @@ -482,4 +482,30 @@ public void basicSecretCacheVersionWithNullStageTest() { sc.close(); } + @Test + public void testPostQuantumTlsConfiguration() { + // Test default is false + SecretCacheConfiguration config = new SecretCacheConfiguration(); + Assert.assertFalse(config.isPostQuantumTlsEnabled()); + + // Test setter + config.setPostQuantumTlsEnabled(true); + Assert.assertTrue(config.isPostQuantumTlsEnabled()); + + // Test fluent method + SecretCacheConfiguration config2 = new SecretCacheConfiguration() + .withPostQuantumTlsEnabled(true); + Assert.assertTrue(config2.isPostQuantumTlsEnabled()); + } + + @Test + public void testSecretCacheWithPQTLSEnabled() { + // Verify cache can be created with PQTLS enabled without errors + SecretCacheConfiguration config = new SecretCacheConfiguration() + .withPostQuantumTlsEnabled(true); + + SecretCache cache = new SecretCache(config); + Assert.assertNotNull(cache); + cache.close(); + } } From 5b3f8c965c8e462e7773989a2c19c9a41bfc4372 Mon Sep 17 00:00:00 2001 From: Vedant Jaiswal Date: Wed, 4 Mar 2026 14:27:49 -0800 Subject: [PATCH 2/5] Fix PQTLS test to use mock client --- .../com/amazonaws/secretsmanager/caching/SecretCacheTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java index 4e19f17..fa4b259 100644 --- a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java @@ -502,6 +502,7 @@ public void testPostQuantumTlsConfiguration() { public void testSecretCacheWithPQTLSEnabled() { // Verify cache can be created with PQTLS enabled without errors SecretCacheConfiguration config = new SecretCacheConfiguration() + .withClient(asm) .withPostQuantumTlsEnabled(true); SecretCache cache = new SecretCache(config); From 4fe8da56499abd00dbd686e7a03150af944df176 Mon Sep 17 00:00:00 2001 From: Vedant Jaiswal Date: Wed, 4 Mar 2026 15:30:15 -0800 Subject: [PATCH 3/5] Add test coverage for Post-Quantum TLS code path --- .../caching/SecretCacheTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java index fa4b259..b2e6738 100644 --- a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java @@ -509,4 +509,23 @@ public void testSecretCacheWithPQTLSEnabled() { Assert.assertNotNull(cache); cache.close(); } + + @Test + public void testSecretCacheWithPQTLSEnabledNoClient() { + String originalRegion = System.getProperty("aws.region"); + try { + System.setProperty("aws.region", "us-east-1"); + SecretCacheConfiguration config = new SecretCacheConfiguration() + .withPostQuantumTlsEnabled(true); // No .withClient() call + SecretCache cache = new SecretCache(config); + Assert.assertNotNull(cache); + cache.close(); + } finally { + if (originalRegion != null) { + System.setProperty("aws.region", originalRegion); + } else { + System.clearProperty("aws.region"); + } + } + } } From c7d0e480339eaf71c7dc9c989d02f3d7cd7de7f6 Mon Sep 17 00:00:00 2001 From: Vedant Jaiswal Date: Tue, 10 Mar 2026 14:04:18 -0700 Subject: [PATCH 4/5] Add validation and SpotBugs suppressions for PQTLS feature - Add validation to prevent conflicting configuration (custom client + PQTLS flag) - Throw IllegalArgumentException when both settings are provided - Add @SuppressFBWarnings annotations to suppress CT_CONSTRUCTOR_THROW warnings - Validation occurs before field initialization, making it safe - Update test to verify exception is thrown for invalid configuration --- .../secretsmanager/caching/SecretCache.java | 16 ++++++++++++++++ .../caching/SecretCacheConfiguration.java | 10 +++++++++- .../secretsmanager/caching/SecretCacheTest.java | 8 +++----- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java index 0731468..bda070e 100644 --- a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java +++ b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java @@ -18,6 +18,7 @@ import com.amazonaws.secretsmanager.caching.cache.SecretCacheItem; import com.amazonaws.secretsmanager.caching.cache.internal.VersionInfo; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; @@ -70,6 +71,8 @@ public SecretCache() { * @param builder The builder to use for creating the AWS Secrets Manager * client. */ + @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", + justification = "Delegates to constructor that validates before field initialization") public SecretCache(SecretsManagerClientBuilder builder) { this(new SecretCacheConfiguration().withClient(builder .overrideConfiguration( @@ -85,6 +88,8 @@ public SecretCache(SecretsManagerClientBuilder builder) { * @param client The AWS Secrets Manager client to use for requesting secret * values. */ + @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", + justification = "Delegates to constructor that validates before field initialization") public SecretCache(SecretsManagerClient client) { this(new SecretCacheConfiguration().withClient(client)); } @@ -93,11 +98,22 @@ public SecretCache(SecretsManagerClient client) { * Constructs a new secret cache using the provided cache configuration. * * @param config The secret cache configuration. + * @throws IllegalArgumentException if both a custom client and postQuantumTlsEnabled + * are specified in the configuration. */ + @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", + justification = "Validation occurs before any field initialization") public SecretCache(SecretCacheConfiguration config) { if (null == config) { config = new SecretCacheConfiguration(); } + + if (config.getClient() != null && config.isPostQuantumTlsEnabled()) { + throw new IllegalArgumentException( + "Cannot specify both a custom client and postQuantumTlsEnabled. " + + "To use PQTLS, omit the custom client or configure your client with PQTLS support."); + } + this.cache = new LRUCache(config.getMaxCacheSize()); this.config = config; ClientOverrideConfiguration defaultOverride = ClientOverrideConfiguration.builder() diff --git a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java index 5a072ae..325be90 100644 --- a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java +++ b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java @@ -307,6 +307,10 @@ public boolean isPostQuantumTlsEnabled() { /** * Sets whether to enable Post-Quantum TLS. * + *

Note: This setting is mutually exclusive with providing a custom client via + * {@link #withClient(SecretsManagerClient)}. If both are specified, an + * {@link IllegalArgumentException} will be thrown. + * * @param postQuantumTlsEnabled * Whether to enable Post-Quantum TLS. */ @@ -316,7 +320,11 @@ public void setPostQuantumTlsEnabled(boolean postQuantumTlsEnabled) { /** * Sets whether to enable Post-Quantum TLS. - * + * + *

Note: This setting is mutually exclusive with providing a custom client via + * {@link #withClient(SecretsManagerClient)}. If both are specified, an + * {@link IllegalArgumentException} will be thrown. + * * @param postQuantumTlsEnabled * Whether to enable Post-Quantum TLS. * @return The updated SecretCacheConfiguration object with the new PQTLS setting. diff --git a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java index b2e6738..3e96373 100644 --- a/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java +++ b/src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java @@ -498,16 +498,14 @@ public void testPostQuantumTlsConfiguration() { Assert.assertTrue(config2.isPostQuantumTlsEnabled()); } - @Test + @Test(expectedExceptions = { IllegalArgumentException.class }) public void testSecretCacheWithPQTLSEnabled() { - // Verify cache can be created with PQTLS enabled without errors + // Verify that providing both client and PQTLS flag throws exception SecretCacheConfiguration config = new SecretCacheConfiguration() .withClient(asm) .withPostQuantumTlsEnabled(true); - SecretCache cache = new SecretCache(config); - Assert.assertNotNull(cache); - cache.close(); + new SecretCache(config); } @Test From 6b17101976fb564f36ce5f81c33ff4e639999c33 Mon Sep 17 00:00:00 2001 From: Vedant Jaiswal Date: Wed, 11 Mar 2026 13:53:24 -0700 Subject: [PATCH 5/5] Refactor client creation to eliminate code duplication --- .../secretsmanager/caching/SecretCache.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java index bda070e..ad79122 100644 --- a/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java +++ b/src/main/java/com/amazonaws/secretsmanager/caching/SecretCache.java @@ -121,17 +121,16 @@ public SecretCache(SecretCacheConfiguration config) { if (config.getClient() != null) { this.client = config.getClient(); - } else if (config.isPostQuantumTlsEnabled()) { - this.client = SecretsManagerClient.builder() - .httpClient(AwsCrtHttpClient.builder() - .postQuantumTlsEnabled(true) - .build()) - .overrideConfiguration(defaultOverride) - .build(); } else { - this.client = SecretsManagerClient.builder() - .overrideConfiguration(defaultOverride) - .build(); + SecretsManagerClientBuilder builder = SecretsManagerClient.builder(); + + if (config.isPostQuantumTlsEnabled()) { + builder.httpClient(AwsCrtHttpClient.builder() + .postQuantumTlsEnabled(true) + .build()); + } + + this.client = builder.overrideConfiguration(defaultOverride).build(); } }