spring-vault
spring-vault copied to clipboard
Dynamically Configure Cipher Suites for Vault Communication
Hello,
I am using the CryptoConfiguration class, which extends AbstractVaultConfiguration, to provide a custom SslConfiguration for Vault communication. This configuration is currently set statically.
`
@Configuration
public class CryptoConfiguration extends AbstractVaultConfiguration {
private static final String ROOT_CERT = "/tmp/cacertbundle.jks";
@Override
public ClientAuthentication clientAuthentication() {
KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder().role("key-role")
.build();
return new KubernetesAuthentication(options, restOperations());
}
@Override
public VaultEndpoint vaultEndpoint() {
VaultEndpoint endpoint = VaultEndpoint.create(key-management, 8200);
endpoint.setScheme("https");
return endpoint;
}
@Override
@Bean
public ClientFactoryWrapper clientHttpRequestFactoryWrapper() {
char[] password = {};
SslConfiguration sslConfig = SslConfiguration.forTrustStore(new FileSystemResource(ROOT_CERT),
password);
return new ClientFactoryWrapper(ClientHttpRequestFactoryFactory.create(clientOptions(), sslConfig));
}
}
`
`
public class CryptoAgent implements CryptoAgentInterface {
private static final String CRYPTO_KEY_NAME = "cm-key-v1";
private static final Retrier retrier = new Retrier();
private VaultTemplate vaultTemplate;
private VaultTransitOperations transitOps;
private AnnotationConfigApplicationContext ctx;
/**
* CryptoConfiguration is used as configuration for vault agent.
*/
public CryptoAgent() {
ctx = new AnnotationConfigApplicationContext();
ctx.register(CryptoConfiguration.class);
ctx.refresh();
this.vaultTemplate = ctx.getBean(VaultTemplate.class);
this.transitOps = vaultTemplate.opsForTransit();
}
@Override
public String encrypt(String input) {
return retrier.runtimeRetry("encrypt", () -> {
return transitOps.encrypt(CRYPTO_KEY_NAME, Plaintext.of(input)).getCiphertext();
}, "Failed to encrypt");
}
@Override
public String decrypt(String input) {
return retrier.runtimeRetry("decrypt", () -> {
return transitOps.decrypt(CRYPTO_KEY_NAME, Ciphertext.of(input)).asString();
}, "Failed to decrypt");
}
}
`
Could you please advise on the recommended approach to achieve dynamic cipher suite configuration(using SslConfiguration) for Vault communication within the current setup ?
VaultTemplate is bound to RestOperations. You can implement your own ClientHttpRequestFactory that applies different client settings/clients per request/endpoint.
SSL settings are propagated into the HTTP client so there is no on-demand reconfiguration.
Hello @mp911de
I am considering to recreate the ClientFactoryWrapper by creating a new SslConfiguration with the desired cipher suites during runtime, particularly when there's a need to update cipher suites, which may occur infrequently, perhaps once or twice during the application's lifespan.
May I know your opinion on whether this approach seems viable and if there are any potential concerns or considerations I should be aware of ?
Regards, Venkat
Occasional updates are fine. Either a proxied ClientHttpRequestFactory or a custom ClientHttpRequestFactory implementation that delegates to the currently active ClientHttpRequestFactory (holding the configured client) ist the best approach as VaultTemplate operates on top of RestTemplate. ClientFactoryWrapper is a Spring Vault-specific type that isn't wired directly into RestTemplate.