Skip to content

fix(security): require authentication for actuator endpoints other than health#124

Merged
epugh merged 1 commit into
apache:mainfrom
adityamparikh:fix/security-actuator-require-auth
May 8, 2026
Merged

fix(security): require authentication for actuator endpoints other than health#124
epugh merged 1 commit into
apache:mainfrom
adityamparikh:fix/security-actuator-require-auth

Conversation

@adityamparikh
Copy link
Copy Markdown
Contributor

Summary

The secured filter chain matched `/actuator` and `/actuator/*` with `permitAll`, which exposed the entire actuator surface anonymously even when `http.security.enabled=true`:

  • `/actuator/sbom` — full dependency tree (recon for known CVEs)
  • `/actuator/loggers` — logger-name list (effectively a package-tree map of the codebase). The write endpoint at `/actuator/loggers/{name}` is currently shielded by Spring's path-matcher (the `*` wildcard doesn't span segments), but relying on that for security is brittle.
  • `/actuator/prometheus` and `/actuator/metrics` — every `@McpTool` URI shows up as a metric label, plus JVM/Solr internals
  • `/actuator/info` — build/git info

Tighten the matchers:

  • `/actuator/health` stays anonymously reachable (load balancers and orchestrators need it)
  • Everything else under `/actuator` requires an authenticated principal

Operators who need a metrics scraper without tokens can configure scraper auth or move actuator to a separate management port (`management.server.port` + `management.server.address=127.0.0.1`) — neither is changed here.

Operator impact

Endpoint Before After
`/actuator/health` Anonymous ✓ Anonymous ✓
`/actuator/sbom` Anonymous Auth required
`/actuator/loggers` Anonymous Auth required
`/actuator/prometheus` Anonymous Auth required
`/actuator/metrics` Anonymous Auth required
`/actuator/info` Anonymous Auth required

Only relevant when `http.security.enabled=true` (currently opt-in, defaults to false). The `unsecured` filter chain is unchanged.

Test plan

  • `./gradlew spotlessApply` clean
  • `./gradlew build` passes (full test suite, 37s)

Note on PR ordering

Touches `HttpSecurityConfiguration.java`. Overlaps with #121 (CORS allowlist) and #123 (audience validation). Whichever lands later will need a small rebase.

References

🤖 Generated with Claude Code

…an health

The secured filter chain matched /actuator and /actuator/* with permitAll,
exposing the entire actuator surface anonymously even when
http.security.enabled=true (sbom, loggers, prometheus, metrics, info).

Tighten the matchers so /actuator/health stays anonymously reachable for
load balancers and orchestrators, while everything else under /actuator
requires an authenticated principal. Only relevant when
http.security.enabled=true; the unsecured filter chain is unchanged.

Signed-off-by: adityamparikh <aditya.m.parikh@gmail.com>
@adityamparikh adityamparikh force-pushed the fix/security-actuator-require-auth branch from f14e683 to 289fc0c Compare May 8, 2026 21:07
@epugh epugh merged commit 31a753b into apache:main May 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants