Spring boot version 2.7.3
I need to mask all the fields containing 'uri' string in actuator/env response.
According to documentation:
To take control over the sanitization, define a SanitizingFunction bean. The SanitizableData with which the function is called provides access to the key and value as well as the PropertySource from which they came. This allows you to, for example, sanitize every value that comes from a particular property source. Each SanitizingFunction is called in order until a function changes the value of the sanitizable data.
So i implemented class:
import org.springframework.boot.actuate.endpoint.SanitizingFunction;
@Component
public class ActuatorSanitizer implements SanitizingFunction {
...
during application startup debugging i can see my bean is initialized and even autowired to org.springframework.boot.actuate.endpoint.Sanitizer class
public Sanitizer(Iterable<SanitizingFunction> sanitizingFunctions, String... keysToSanitize) {
this.sanitizingFunctions = new ArrayList();
List var10001 = this.sanitizingFunctions;
sanitizingFunctions.forEach(var10001::add);
this.sanitizingFunctions.add(this.getDefaultSanitizingFunction());
this.setKeysToSanitize(keysToSanitize);
}
but then i see that Sanitizer constructor is invoked once again without my custom sanitizing function implementation injected and i see no effect in /actuator/env call response.
Is there a way to get more sanitizing control programatically or via config?
UPD: custom SanitizingFunction implementation works for /actuator/configprops request. This is why Sanitizer constructor is invoked twice.
Update for Spring Boot 2.7.3
For configuring sanitizing of env-endpoint in application.yml; replace keys-to-sanitize
with actual keys:
management:
endpoint:
env:
keys-to-sanitize:
- USERNAME
- HOMEBREW_REPOSITORY
For customizing env-endpoint programatically, add a custom EnvironmentEndpoint
bean. SanitizingFunction
is the same as in the original answer.
import org.springframework.boot.actuate.env.EnvironmentEndpoint;
import org.springframework.boot.actuate.endpoint.SanitizingFunction;
import org.springframework.core.env.Environment;
@Bean
public EnvironmentEndpoint customEnvironmentEndpoint(
Environment environment,
SanitizingFunction sanitizingFunction) {
return new EnvironmentEndpoint(
environment,
Collections.singletonList(sanitizingFunction));
}
Update #2
OP experienced this error during app start:
nested exception is java.lang.IllegalStateException: Found two endpoints with the id 'env': 'writableEnvironmentEndpoint' and 'customEnvironmentEndpoint'
OP later reported that using these suggestions from me fixed the issue:
management.endpoint.env.enabled=false
and
@SpringBootApplication(exclude = EnvironmentEndpointAutoConfiguration.class)
For Spring Boot 3.4
Step 1: Configure actuator
Add this to .authorizeHttpRequests(authorize -> authorize
in SecurityFilterChain
// for testing only, enable each actuator endpoint separately
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
Add this to application.yml
management:
endpoints:
web:
exposure:
include:
- env
- configprops
endpoint:
env:
show-values: always
configprops:
show-values: always
Verify that both http://localhost:8080/actuator/env and http://localhost:8080/actuator/configprops works.
Step 2: Add SanitizingFunction
Put this bean into any @Configuration-annotated class
@Bean
public SanitizingFunction customSanitizingFunction() {
return data -> data.getKey().contains("uri")
? data.withValue("TESTING") // replace with e.g. ****
: data;
}
Verify that "TESTING" appears in both endpoints.