Dynamic secrets
Application considerations for dynamic credentials
Applications will need to be aware of password rotation in certain cases, especially for long-running jobs and applications.
For example, in the case of Spring Boot applications, you would do the following:
- Configure Spring Cloud Vault: Set up Spring Cloud Vault in your application.properties or application.yml file, specifying the necessary configurations to connect to Vault and access the dynamic secrets.
- Enable refresh scope: For any beans that should be refreshed when the configuration changes, use the @RefreshScope annotation. This might include your DataSource bean or any configuration properties class that holds your database credentials.
- Enable Actuator refresh endpoint: Make sure the Actuator's refresh endpoint is enabled and exposed. In Spring Boot 2.x, this might involve setting properties in your application.properties or application.yml, like \ management.endpoints.web.exposure.include: refresh
- Create a refresh mechanism: Implement a mechanism to call the /actuator/refresh endpoint whenever the credentials in Vault are rotated. This could be a scheduled task within your application, an external script, or a webhook triggered by Vault (if Vault is configured to send notifications on credential rotation).
- Secure the Actuator endpoints: Ensure that your Actuator endpoints, including the /refresh endpoint, are secured to prevent unauthorized access. Use Spring Security to restrict access to these endpoints.
- Refresh DataSource credentials: Ensure your DataSource or the component that manages the database connection is designed to handle configuration changes dynamically. This might involve using a DataSource proxy or custom logic to reinitialize the DataSource with new credentials upon refresh. Here is a simplified example demonstrating how you might configure a DataSource bean to use dynamic credentials that can be refreshed via Actuator:
@Configuration
public class DataSourceConfig {
@Bean
@RefreshScope
public DataSource dataSource(
@Value("${spring.datasource.url}") String url,
@Value("${spring.datasource.username}") String username, @Value("${spring.datasource.password}") String password) {
return DataSourceBuilder.create()
.url(url)
.username(username)
.password(password)
.build();
}
}