ASVS 5.0 V13.4.5 is a Level 2 requirement. Documentation pages such as Swagger UI or GraphQL explorers, and monitoring endpoints such as metrics and health detail, must not be reachable in production unless you deliberately decided they should be.
The word "intended" carries the weight. Public API docs for customers are fine. Internal ones that came along with the framework are not.
Why it matters
API documentation is a map. It lists every route, parameter and data shape, including admin and unreleased routes. Monitoring endpoints go further: they can show environment values, dependency versions, thread dumps and internal host names. An attacker who finds /actuator/env or /metrics saves days of reconnaissance.
How to implement it
Decide per endpoint who the audience is, then enforce it.
FastAPI, disabling docs outside development:
import os
from fastapi import FastAPI
dev = os.environ.get("APP_ENV") == "development"
app = FastAPI(
docs_url="/docs" if dev else None,
redoc_url=None,
openapi_url="/openapi.json" if dev else None,
)
Spring Boot Actuator, expose only what you need:
management.endpoints.web.exposure.include=health
management.endpoint.health.show-details=never
management.server.port=9091
Putting the management port on an internal interface that only the monitoring system can reach is stronger than relying on authentication alone.
Prometheus style metrics: bind them to an internal listener or require a network policy, and do not route them through the public ingress.
location /metrics { allow 10.0.0.0/8; deny all; }
How to test it
Probe production from outside your network:
for p in docs swagger-ui.html openapi.json v3/api-docs graphql actuator actuator/env metrics debug/vars healthz; do
printf "%s " "$p"; curl -s -o /dev/null -w "%{http_code}\n" "https://example.com/$p"
done
Anything that returns 200 should map to a documented, intentional decision. An API scanner can also compare the routes it discovers with your published spec, as in the API security scan demo.
Click through it at your own pace, or open it full screen.
Common mistakes
- Protecting
/docsbut leaving/openapi.jsonopen, which carries the same information. - Exposing the health endpoint with full details, including database host names.
- Assuming an internal route is private because it is not linked anywhere.
- Different ingress rules for each environment, so staging is locked down and production is not.
Quick check
Can public API docs satisfy this requirement?
Yes, if exposing them is a conscious decision and they describe only the public surface.