-
Notifications
You must be signed in to change notification settings - Fork 345
Description
Is your feature request related to a problem? Please describe.
Spring Boot has support for sanitizing sensitive values when management.endpoint.env.show-values is set to anything other than the default value of never. Currently any secrets loaded from Secret Manager are visible in plain text in the output of actuator endpoints when management.endpoint.env.show-values is set to always or when-authorized, which is a security problem in those scenarios.
To guarantee that secrets are never shown in plain text in the output of actuator endpoints, an appropriate SanitizingFunction should be provided.
Describe the solution you'd like
It would be great if Spring Cloud GCP Secret Manager would auto-configure a SanitizingFunction bean to sanitize secrets loaded from Secret Manager, so that secrets are always protected from leaking via actuator endpoints, even when management.endpoint.env.show-values is set to any value other than never.
The question is how to identify data is being loaded from Secret Manager. The best I've come up with so far is checking the property source for the unresolved value and seeing if this contains a reference which uses one of the supported Secret Manager prefixes.
Here's a sketch of what such a sanitizing function could look like:
import com.google.cloud.spring.secretmanager.SecretManagerSyntaxUtils;
import org.springframework.boot.actuate.endpoint.SanitizableData;
import org.springframework.boot.actuate.endpoint.SanitizingFunction;
import org.springframework.core.env.PropertySource;
/**
* Sanitize data with secrets from GCP Secret Manager.
*/
class SecretManagerSanitizingFunction implements SanitizingFunction {
@Override
public SanitizableData apply(SanitizableData data) {
PropertySource<?> propertySource = data.getPropertySource();
if (propertySource == null) {
return data.withValue(SanitizableData.SANITIZED_VALUE);
}
String unresolvedValue = String.valueOf(propertySource.getProperty(data.getKey()));
for (String secretManagerPrefix : SecretManagerSyntaxUtils.PREFIXES) {
if (unresolvedValue.contains("${" + secretManagerPrefix)) {
// Sanitize data by replacing the resolved value which contains secret
// with the unresolved value which just contains the reference to the secret
return data.withValue(unresolvedValue);
}
}
return data;
}
}This should for instance replace a value of https://username:secret123@hostname/path with an unresolved value like https://username:${sm@my-secret-password}@hostname/path.
Or maybe there is another way to determine that SanitizableData contains a secret loaded from Secret Manager?
Describe alternatives you've considered
The alternative is for users to implement such a SanitizingFunction bean themselves.