What Actuator exposes before you touch anything
Two settings decide whether an endpoint is reachable, and reviewers often conflate them. An endpoint must be available, which most are by default (shutdown is the long-standing exception, and since Spring Boot 3.5 heapdump defaults to no access too), and it must be exposed over a transport. Over HTTP, current Spring Boot versions expose only health by default; info was removed from the default web exposure in 2.5. Everything else needs management.endpoints.web.exposure.include. JMX has its own separate exposure setting, so check that too.
So a service that leaks is almost always one where somebody wrote include: "*" while debugging and it reached production. The quotes there are required, because a bare * starts an alias in YAML. That one line is the first thing a security review should search for.
Exposure by audience
A useful answer splits the consumers of Actuator, because each one needs something different.
The orchestrator needs liveness and readiness, which are the health/liveness and health/readiness groups. It needs no detail, so show-details stays at its default of never or moves to when-authorized. Full health details reveal the database product, disk paths and downstream hostnames, which is reconnaissance material.
The metrics scraper needs one endpoint, usually prometheus. It is read-only and holds no secrets, though metric tags can carry user identifiers if someone tagged by them.
Human operators occasionally need loggers, threaddump, env, configprops and heapdump. Those belong behind authentication with a dedicated role, and ideally they are not exposed at all until an incident calls for them.
management:
server:
port: 8081
endpoints:
web:
exposure:
include: health,prometheus
endpoint:
health:
show-details: when-authorized
When Spring Security is present, secure the actuator paths in their own filter chain rather than relying on the port alone. EndpointRequest gives you matchers that follow the configured base path and port.
@Bean
SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint())
.authorizeHttpRequests(auth -> auth
.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
.anyRequest().hasRole("ACTUATOR"))
.httpBasic(Customizer.withDefaults());
return http.build();
}
Heapdump is the leak masking cannot reach
Reviewers usually fixate on env, because it obviously lists configuration. Since Spring Boot 3.0, though, env and configprops mask every value by default, and the show-values setting decides who may see them unmasked. Before 3.0, masking worked on key-name patterns, so a secret stored under an unremarkable name passed through. Either way, the protection lives in how the endpoint renders its response.
heapdump has no response to sanitise. It returns an HPROF snapshot of the heap, and the heap contains the Environment property sources with their real values, the decrypted datasource password, OAuth client secrets, signing keys, live session tokens, and whatever customer records were in flight. Anyone who downloads it can open it in a heap analyser and search for strings. It is also large, so it looks like a diagnostics feature rather than a data export, which is why it survives reviews that catch env.
Spring Boot 3.5 tightened the default so that heapdump needs explicit access as well as exposure, but every service still on an earlier version, or with that access granted, carries the full risk. The correct stance is that heapdump is never exposed in steady state. When a memory incident needs a dump, take it deliberately and treat the file as production customer data with the same handling rules.
Loggers is a write endpoint
loggers looks harmless because it mostly reads. It also accepts a POST that changes a logger's level at runtime. Raising an HTTP client or web package to DEBUG or TRACE can start logging request headers and bodies, bearer tokens included. Those lines then flow into a log platform that far more people can read than can reach Actuator. An unauthenticated loggers endpoint therefore lets an attacker turn secrets into log lines, which matters more than any information it returns directly.
The cost of a separate management port
management.server.port moves Actuator onto its own port, which keeps it off the public ingress and makes network policy simple. The cost falls on probes. A health check on the management port runs on a separate server, so it can pass while the main connector is wedged and refusing traffic. Spring Boot can additionally publish the probe groups on the main port with management.endpoint.health.probes.add-additional-paths=true, as /livez and /readyz. That keeps the sensitive endpoints separate while the probes test the server that actually serves requests.
Answer the review with an explicit list per audience: health for the platform, one metrics endpoint for the scraper, everything else authenticated or absent. Then name heapdump, because it is the one endpoint where masking protects nothing.
© 2026 Preptima. Originally published at preptima.com (opens in a new tab).