Explain the difference between an endpoint being enabled and being exposed. Why does an endpoint need both?
answer
- enabled = bean exists
- exposed = reachable over transport
- reachable = enabled AND exposed
- shutdown disabled by default
- `*` spans only enabled endpoints
basics
~20 sEnabled means the endpoint bean is active and can do its work; exposed means it's reachable over a technology (web/JMX). An endpoint must be both to be callable. Most are enabled by default; only health is web-exposed by default.
solid answer
~40 sActuator has two orthogonal gates. **Enablement** (`management.endpoint.<id>.enabled`, or global `management.endpoints.enabled-by-default`) decides whether the endpoint exists as an active bean at all. **Exposure** (`management.endpoints.web|jmx.exposure.include/exclude`) decides whether an enabled endpoint is reachable over that transport. An endpoint is invocable only when it is BOTH enabled AND exposed. Almost every built-in endpoint is enabled by default; `shutdown` is the exception (disabled). Exposure defaults are stingy: only `health` over the web. The practical consequence: `include=*` won't surface `shutdown` (it's disabled), and enabling `metrics` doesn't make it web-reachable unless it's also in the include set. Disabling an endpoint removes it entirely — its auto-configuration is skipped, which also frees resources; excluding it from exposure just hides that transport.
code
java · 9 lines// Lock everything down, then opt in explicitly:
management.endpoints.enabled-by-default=false // gate 1: nothing enabled
management.endpoint.health.enabled=true // enable health
management.endpoint.info.enabled=true // enable info
management.endpoints.web.exposure.include=health,info// gate 2: expose them over HTTP
// Enabling shutdown is required before '*' can ever expose it:
management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=* // now includes shutdown toogo deeper
May conflate the two switches; should at least recall both exist.
Must state the AND rule and the shutdown default clearly.
Uses enabled-by-default=false lock-down and reasons about cost vs transport separation.
Designs a defense-in-depth default (disabled+unexposed baseline) as a platform standard across services.
## Two independent gates Actuator reachability is an **AND** of two separate switches: ### 1. Enablement - Per-endpoint: `management.endpoint.<id>.enabled=true|false` (e.g. `management.endpoint.shutdown.enabled=true`). - Global default: `management.endpoints.enabled-by-default=true|false` sets the baseline for all endpoints; per-endpoint properties override it. - A **disabled** endpoint is not created — its bean and auto-configuration are skipped, so it consumes no resources and cannot be exposed by any technology, wildcard or not. - Default: **all built-in endpoints are enabled except `shutdown`.** ### 2. Exposure - Per technology: `management.endpoints.web.exposure.include/exclude` and `management.endpoints.jmx.exposure.include/exclude`. - Controls whether an already-**enabled** endpoint is reachable over web and/or JMX. - Default: **web exposes only `health`**; JMX is off by default in modern Spring Boot. ## The AND rule An endpoint is callable over a transport only when it is **enabled AND exposed** on that transport. Truth table for the web: | Enabled? | In web include (minus exclude)? | Reachable over HTTP? | |---|---|---| | yes | yes | ✅ | | yes | no | ❌ (404) | | no | yes | ❌ (not even created) | | no | no | ❌ | ## Why two switches? - **Enablement** is about *existence and cost* — turning off `heapdump` or `threaddump` removes capability entirely. Turning off everything except what you use (`enabled-by-default=false` + selectively enable) shrinks both attack surface and startup cost. - **Exposure** is about *transport reachability* — the same enabled endpoint can be JMX-only (for internal tooling) yet hidden from HTTP. ## Consequences and gotchas - `management.endpoints.web.exposure.include=*` does **not** expose `shutdown`, because `shutdown` is disabled by default and `*` only spans enabled endpoints. To expose it: `management.endpoint.shutdown.enabled=true` (then `*` covers it) — and be very careful, it stops the app. - Enabling an endpoint does not web-expose it; you still need it in the include set. - Disabling via `enabled=false` cannot be overridden by exposure — exposure never resurrects a disabled endpoint. - Locking down with `enabled-by-default=false` is the strongest posture: nothing exists unless explicitly re-enabled.
- How do you make `shutdown` callable over HTTP?Enable it (`management.endpoint.shutdown.enabled=true`) AND expose it (`...web.exposure.include=shutdown` or `*`). Both gates are required; enabling alone isn't enough.
- What's the tightest lock-down posture?`management.endpoints.enabled-by-default=false`, then selectively enable and expose only what you need — disabled endpoints aren't even created, so exposure can't surface them.
saying these in an interview costs you the question
- Thinking exposure can make a disabled endpoint reachable
- Believing enabling an endpoint automatically exposes it over HTTP
- Assuming `include=*` surfaces shutdown