Asset inventory
Shadow and zombie APIs: detection and cleanup
Find undocumented endpoints, deprecate safely, and keep your inventory tight.
Published: February 3, 2026 • Author: APISAST
Published: 3 February 2026 · Updated: 19 September 2026
Why they appear
Shadow APIs come from rogue teams or forgotten prototypes; zombie APIs linger after migrations. Both widen your attack surface and often skip auth and observability.
Discovery tactics
- Compare ingress logs against the official OpenAPI inventory.
- Scan source repos for router definitions that lack spec coverage.
- Use eBPF or service mesh telemetry to spot untracked services.
- Run external scanners and correlate findings with your spec.
Build a route inventory from real traffic
Start with gateway and ingress logs, service discovery, and deployed routing configuration. Record each route's hostname, method, environment, owner, authentication policy, and last observed traffic. Compare that list with published OpenAPI operations. A mismatch can mean an undocumented endpoint, an obsolete spec, or a route intentionally omitted from public docs. Investigate before labelling it a vulnerability.
Traffic alone is incomplete: a monthly batch job may not appear in a short observation window, and an abandoned endpoint may still be reachable without traffic. Combine logs with router definitions and deployment records. Keep the inventory current when a new service is released or an existing route moves behind another gateway. APISAST scans a supplied contract; it cannot discover a route that is absent from that file.
Triage an unknown or forgotten endpoint
For each mismatch, find the service owner and confirm whether the route is still deployed. Check what data it returns, which identities can call it, and whether rate limits and logging apply. If it belongs to a supported API, update its specification and tests. If it is an internal route, restrict exposure and document the reason it is excluded from public reference material. If nobody owns it, assign an incident or cleanup owner rather than leaving the entry unresolved.
Treat a zombie version differently from a shadow route. A zombie API may have known users and documented behaviour but should have been retired. Contact those consumers, measure traffic over a meaningful period, and publish a migration path. Removing it without notice can break critical integrations; leaving it indefinitely can preserve outdated authentication and dependencies.
Retire safely and confirm removal
Publish a deprecation notice, replacement endpoint, and target sunset date. Keep the old route authenticated and monitored during migration. When traffic is low and the agreed date arrives, remove routing and credentials, then verify from outside and inside the network that the endpoint is no longer reachable. A removed line in OpenAPI does not remove a deployed handler.
Retain a short record of the old route, owner, removal date, and replacement so future teams can understand an incoming support request. Update SDKs, examples, and links that still point to it. The versioning guide explains how to communicate the change before removal.
Make discovery routine
Automate a comparison of deployed route manifests with the API catalogue during release, then review traffic-based differences on a schedule. Alert on a new public route without an owner or documented authentication policy. Keep a human review in the loop because proxies, health checks, and internal paths can produce legitimate differences. A useful inventory process explains why a route exists, not merely that it exists.
Scan each known OpenAPI file with APISAST for design issues and combine those findings with the inventory comparison. This separates two questions: whether every deployed route is known, and whether the known contracts describe safe defaults. Neither question alone establishes that the running service is secure; use integration tests for access control and runtime monitoring for unexpected use.
Mitigation
Prioritise an undocumented internet-facing write route over a private health check, but investigate both. For a shadow route, the first safe action may be to restrict access while the owner documents its purpose. For a zombie route, communicate the replacement and measure remaining callers before removal. Keep a small exception record if a legacy client needs extra time. Review that exception regularly so a temporary accommodation does not become a permanent unowned exposure.
After each cleanup, confirm that the inventory, OpenAPI file, gateway configuration, and deployed service agree. A contract can be deleted while a route stays active, and a gateway route can disappear while generated docs still advertise it. Close the task only after checking both directions.
- Deprecate with timelines and clear RFC 7807 errors for retired routes.
- Disable or rate-limit legacy endpoints; add auth immediately.
- Compare deployed routes with the inventory, then use SAST testing for APIs on each documented contract.
- Assign ownership for every service and spec.