Join our Newsletter — 33% off our NHI Course
Home› Guides› Shadow APIs vs Zombie APIs: Finding Undocumented and…
Guide Web & API Security

Shadow APIs vs Zombie APIs: Finding Undocumented and Abandoned Endpoints

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 14 November 2026 17 min read
On this page

A shadow API is an endpoint that is running but was never declared to the people who secure it; a zombie API is an endpoint that was declared, then replaced or deprecated, and kept answering requests anyway. Both sit outside normal review and leave behind credentials that nobody rotates. This guide covers how each is born, the non-human identities bound to it, discovery signals and a decommissioning playbook, for API security and platform teams closing gaps in an existing inventory. For the inventory risk itself, see the OWASP API Top 10 API9 Improper Inventory Management Guide; for the wider discipline, see the API Security Guide.

Key takeaways

  • Short answer: shadow is a birth problem, zombie is a death problem. Shadow APIs were never registered; zombie APIs were registered and never removed. Shadow is fixed at the point of deployment, zombie at the point of retirement.
  • NIST names both. SP 800-228 describes rogue or shadow APIs as internal endpoints that often bypass standard security review, and zombie or deprecated APIs as superseded endpoints that fall behind current security policies and protections.
  • Discovery means reconciling three sources. Declared specifications, gateway and runtime traffic, and source code each see a different slice. An endpoint in traffic but not in the spec is shadow; an endpoint marked deprecated in the spec but still serving traffic is zombie.
  • The credentials outlive the endpoint. API keys, client secrets, service accounts and database logins bound to these endpoints are rarely rotated, because nobody knows they are in use. Decommissioning an API without retiring its identities leaves the door unlocked.
  • Retirement needs a dated, signalled process. Use the Deprecation (RFC 9745) and Sunset (RFC 8594) HTTP header fields, watch caller traffic fall to zero, then remove routes, code, DNS and credentials in that order.

What each one is, and how it is born

Define both by lifecycle state, not by how dangerous the endpoint looks.

Shadow APIs: never declared

NIST SP 800-228 (June 2025; the March 2026 update added appendices) lists "rogue or shadow APIs" as APIs defined for internal use, such as debugging, testing or ad hoc fixes, which may be poorly documented and often bypass standard security review practices. In practice shadow endpoints arrive through a handful of routes:

  • Debug and admin routes: health, metrics, actuator-style or internal admin paths shipped in the same build as the public API and exposed by a permissive ingress rule.
  • Parallel hosts: beta, staging or partner hostnames running the same code with different middleware. OWASP's API9 scenario describes a beta host that ran the production password reset flow without the rate limiting enforced in front of the main host.
  • Framework auto-routing: frameworks that expose every controller method or data model as a route, so new endpoints appear without anyone writing a spec entry.
  • Team-owned gateways and direct exposure: services published through a team's own load balancer or serverless URL instead of the central gateway, so central policy and logging never see them.

Zombie APIs: declared, deprecated, still alive

The same NIST text lists "zombie or deprecated APIs": endpoints replaced or superseded by newer systems that remain because callers have not migrated or no team owns them, and which risk falling behind the latest security policies and protections. Typical origins:

  • Version sprawl: /v1 kept alongside /v2 "for one big customer", then forgotten after that customer moved.
  • Migrations that stopped at the gateway: the route was removed from the public gateway but the backend still listens on an internal address or a second ingress.
  • Security fixes not backported: OWASP API9 advises a risk analysis whenever a newer version includes security improvements, to decide whether to backport them or force clients off the old version. When that analysis is skipped, the old version becomes the easiest way in.

Two related terms help with triage. An orphan API (named alongside shadow and zombie in SP 800-228's discovery recommendation) is one that may be documented but has no current owner; it can be either shadow or zombie.

Side-by-side comparison

DimensionShadow APIZombie API
Lifecycle stateRunning, never registered in the inventory or specificationRegistered, deprecated or superseded, still serving requests
Typical ownerUsually known (the team that shipped it) but unaware it is exposedOften unknown after team changes
DocumentationNone, or only in codeExists but stale, often marked deprecated
Security controlsNever reviewed, may skip gateway authentication, rate limits, schema validationControls frozen at the time of deprecation, missing later fixes
Data exposureOften connected to production data for convenienceOWASP notes different versions may share the same database with real data
Credentials bound to itHard-coded keys, shared service accounts, debug tokensLegacy API keys, long-lived client secrets, old signing keys
Best discovery signalTraffic or code that has no matching specification entrySpecification entry marked deprecated that still receives traffic
Root-cause fixDeployment gate: no spec, no routeRetirement process: dated deprecation, sunset and removal

Shadow APIs in depth: threat model, architecture and failure modes

Threat model: an external attacker or a curious partner finds the endpoint through DNS enumeration, certificate transparency, internet search engines or client-side code, which OWASP API9 notes is often enough to discover targets. Inside the network, a compromised workload probes internal hostnames. The attacker's goal is a path that skips the controls the main API enforces: authentication at the gateway, object-level authorisation, rate limits or schema validation. This maps to ATT&CK T1190 Exploit Public-Facing Application for initial access.

Architecture in words: a central gateway fronts the declared API, with authentication, logging and rate limiting attached to declared routes. The shadow endpoint is reachable by a second path: another hostname, a cloud function URL, a node port, or a path the gateway forwards with a wildcard rule. Because the gateway either never sees the call or forwards it without a matching policy, the security stack has no record that the endpoint exists.

Failure modes:

  • Wildcard gateway routes (for example /api/*) forward undeclared paths to the backend, so "behind the gateway" gives false comfort.
  • Non-production hosts use production data, which OWASP advises against or, if unavoidable, says must get the same security treatment as production.

Controls: make the specification the deployment contract. NIST SP 800-228 recommends that every API has a specification describing its endpoints, written in a well-defined interface definition language such as OpenAPI or protobuf, with request and response schemas. Generate the specification from code in CI, as OWASP API9 recommends, fail the build when a route has no spec entry, and configure the gateway to reject undeclared paths instead of forwarding them. See the OpenAPI Specification Security Guide for spec-level controls.

Zombie APIs in depth: threat model, architecture and failure modes

Threat model: an attacker who knows or guesses older version paths (/v1, /legacy, /api-old) calls them directly, or uses a deprecated endpoint that still exposes administrative functions or a known, unpatched weakness, both of which OWASP API9 lists as impacts. Old versions often still accept static API keys where the current version requires OAuth tokens.

Architecture in words: the current version runs behind the gateway with current policy. The deprecated version still runs, either on the same backend behind a route nobody removed, or as a separate deployment that was scaled down but not deleted. It reads the same database and often authenticates to it with the same or an older service account.

Failure modes:

  • Deprecation announced in documentation only, with no runtime signal, so callers never learn and the provider never sees who is still calling.
  • Gateway route removed while the backend listener, DNS record or internal ingress remains.
  • Security fixes applied to v2 only, leaving v1 vulnerable to the issue the fix addressed.
  • Legacy credentials kept "just in case" a caller returns, never rotated and never revoked.

Controls: NIST SP 800-228 recommends strategies for API versioning, deprecation and sunsetting with a focus on secure migration paths. Concretely: mark the operation deprecated in the OpenAPI document (the Operation Object's deprecated field, which defaults to false and tells consumers they should refrain from using it), send runtime signals, track remaining callers by credential, keep the old version under the same monitoring and protection as the current one until it is removed (OWASP API9 asks for protection on all exposed versions, not just production), and set a removal date that is enforced.

Where identity fits: the credentials each leaves behind

Every API call carries at least two identities: the calling software and, often, an end user. SP 800-228 notes it is common to use an API key to identify the calling software, and lists SPIFFE SVIDs, JSON Web Tokens and API keys as service authentication mechanisms. Shadow and zombie endpoints concentrate the weakest of these.

Identity or secretShadow API patternZombie API patternAction
Inbound API keys (callers)Shared test key issued informally to a few consumersLegacy keys issued for v1, still valid after v2 moved to OAuthInventory keys per endpoint, attribute each to a caller, revoke at sunset
OAuth clients and client secretsClient registered by a developer outside the identity teamClient for the old version left enabled with broad scopesDisable clients with no tokens issued in 90 days; remove at decommission
Outbound service account (API to database or cloud)Reuses a production service account for convenienceOld service account with permissions the new version no longer needsGive each API its own workload identity; delete the old one after removal
Signing keys and certificatesSelf-signed or developer certificatesOld JWT signing keys still trusted by the old versionRemove from trust stores when the version is removed
Hard-coded secrets in codeCommon in debug and prototype routesLeft in legacy branches and imagesSecret scanning on all branches and images, then rotate

The pattern to watch is a credential that is still valid but whose consumer is unknown. That is the same problem as an orphaned service account, and the same processes apply. See NHI Offboarding and Decommissioning Guide, API Key Management Guide and Orphaned and Dormant Accounts.

Discovery: traffic, gateways and code

SP 800-228 recommends API discovery tools and scheduled automated scans to detect all running APIs, and runtime reconciliation of declared specifications against live traffic to find shadow, orphan and zombie endpoints. Each source has blind spots, so use all three.

SourceWhat it findsBlind spotsShadow signalZombie signal
Gateway and load balancer access logsEvery call through the managed edge, with route, status, client and credentialAnything that bypasses the gatewayRequests matched only by a wildcard or default routeNon-zero traffic on routes marked deprecated
Runtime traffic sensors (mirroring, service mesh telemetry, eBPF)East-west and direct-to-service callsEncrypted traffic without a termination point; coverage gaps between clustersPaths and hosts absent from any specificationOld version paths still called service to service
Source code and build artefactsRoutes defined in code, including ones never deployedDoes not prove the route is reachableRoute handlers with no spec entryHandlers for versions the spec marks removed
Cloud and DNS inventoryHostnames, function URLs, load balancers, certificatesPath-level detailHosts with no owner tag or no gateway in frontHosts for retired products still resolving
External attack surface scanningWhat an outsider seesInternal APIsPublic endpoints not in the inventoryOld versions reachable from the internet

Reconciliation is a join on host, method and path template. Classify each row: declared and observed (healthy), observed but undeclared (shadow), declared deprecated and observed (zombie), declared and never observed (candidate for removal or a stale spec). The SP 800-228 guidance on inventory entries (specification, ownership, and runtime information such as instances, traffic volume and policy enforcement status) is a good schema for the result. The API Inventory Template gives a starting format, and Attack Surface Management Guide covers the outside-in view.

Decommissioning playbook for zombie APIs

  1. Confirm ownership and scope. Name an owner, list every host, path and version in scope, and record the backing data stores and identities.
  2. Measure who still calls it. Group the last 30 to 90 days of gateway and runtime logs by credential and client. Unattributed callers are a finding in their own right.
  3. Announce with runtime signals. Add the Deprecation header (RFC 9745, Standards Track, March 2025), whose value is a structured date that may be in the future, and the Sunset header (RFC 8594, Informational, May 2019), an HTTP-date after which the resource is expected to stop responding. RFC 9745 requires the Sunset time to be no earlier than the Deprecation date. Add Link headers with the deprecation and sunset relations pointing to migration notes. Both RFCs say clients should treat these as hints, so keep direct notice to named consumers too.
  4. Freeze and protect. No new credentials for the old version; keep it under full policy, monitoring and patching until removal.
  5. Brown-out test. Return errors for short, announced windows to flush out silent callers, and confirm the current version handles their traffic.
  6. Remove in order. Gateway route, then backend listener and deployment, then internal ingress and DNS records, then code and images. After the sunset date return a clear error (for example 410 Gone) for a period rather than leaving the route undefined, so remaining callers fail visibly.
  7. Retire the identities. Revoke inbound API keys and OAuth clients, delete the API's outbound service accounts and database logins, and remove signing keys and certificates from trust stores.
  8. Roll back safely. Keep the deployment artefact and configuration for a defined period so a critical missed caller can be restored, with new, scoped credentials rather than the old ones.
  9. Close the record. Mark the entry removed and confirm with an external scan that the endpoint no longer answers.

For shadow APIs the playbook is shorter: decide within a fixed period whether the endpoint should exist. If yes, write the specification, route it through the gateway and give it its own identity. If no, remove it and its credentials using steps 6 to 9. The Server and Application Decommissioning Checklist covers the infrastructure side.

Decision guidance

  • Lead with shadow if teams deploy independently, you run several gateways or serverless platforms, or code generation and AI-assisted development are adding routes faster than specs. The fix is a deployment gate.
  • Lead with zombie if you have a long-lived public or partner API with several versions, a history of migrations, or reorganisations that left services without owners. The fix is a retirement process with dates.
  • Small organisations: one gateway with deny-by-default routing and spec generation in CI removes most shadow risk; a written version policy with Deprecation and Sunset headers handles zombies. Dedicated discovery tooling is often unnecessary.
  • Large organisations: multiple edges and clusters make runtime discovery necessary. Fund reconciliation as a recurring job with owners for each finding class, not a one-off scan.
  • Trade-off: deny-by-default gateways break undocumented but legitimate integrations. Run log-only first, register what you find, then enforce.

Worked scenario

A payments company runs /v2 of its merchant API behind a central gateway with OAuth client credentials. Reconciliation of 60 days of logs against the OpenAPI documents finds two problems. First, 4% of calls hit /v1/merchants, marked deprecated two years earlier: zombie. They come from three API keys, two attributed to merchants who never migrated and one with no owner. Second, mesh telemetry shows a reporting service calling /internal/export on the merchant backend directly, a path in no specification: shadow. It authenticates with the production database service account.

The team treats them differently. For /v1 it sends Deprecation and Sunset headers with a date 90 days out, contacts the two known merchants, revokes the unowned key after a brown-out shows no business caller, then removes the route, listener and v1 service account. For /internal/export it confirms the reporting team needs it, writes a specification, gives the reporting service its own workload identity with read-only access to the reporting tables, routes the call through the internal gateway, and adds a CI rule that fails builds containing undeclared routes.

Detection and measurement

Log route, version, client identity, credential ID and response size at the gateway, and tag runtime telemetry with the API being called, as SP 800-228 recommends for logs, metrics and traces. Alert on traffic to deprecated routes after the sunset date, on any call matched only by a default route, and on unusual per-client data volumes. The T-Mobile API breach shows why per-client volume matters: abuse of a single API ran for about six weeks before it was detected.

  • Undeclared endpoint rate: observed endpoints with no specification entry as a share of all observed endpoints. Target: trending to zero.
  • Deprecated traffic share: requests to deprecated versions as a share of total. Should fall steadily to zero by the sunset date.
  • Time to classify: median days from first sighting of an undeclared endpoint to a register or remove decision.
  • Credential attribution: share of active API keys and clients mapped to a named consumer and endpoint.
  • Post-sunset residue: credentials, DNS records or listeners still present 30 days after a version's removal date.

Framework mapping

FrameworkReferenceShadowZombie
OWASP API Security Top 10 2023API9:2023 Improper Inventory Management (documentation and data flow blindspots)YesYes
NIST SP 800-228API inventory, discovery and reconciliation; versioning, deprecation and sunsettingYesYes
NIST CSF 2.0ID.AM-02 inventories of software, services and systems; ID.AM-08 life cycle managementID.AM-02ID.AM-08
NIST SP 800-53 Rev 5CM-8 System Component Inventory; CM-7 Least Functionality; SA-22 Unsupported System ComponentsCM-8, CM-7SA-22, CM-8
CIS Controls v8.1Control 2 Inventory and Control of Software Assets; Control 16 Application Software Security2, 162, 16
ISO/IEC 27001:2022 Annex AA.5.9 Inventory of information and other associated assets; A.8.32 Change managementA.5.9A.5.9, A.8.32
MITRE ATT&CK v20T1190 Exploit Public-Facing ApplicationYesYes
CWECWE-1059 Incomplete Documentation (referenced by OWASP API9)YesYes

Common failure patterns

  • Counting the spec as the inventory: a specification repository lists what teams declared, which by definition excludes shadow APIs. Reconcile against traffic.
  • Removing the gateway route and calling it done: the backend, its internal ingress and its service account remain, and an internal attacker can still reach the zombie.
  • Deprecating in documentation only: without Deprecation and Sunset headers and per-credential traffic data, nobody knows who will break, so the date slips forever.
  • Leaving credentials valid after retirement: the endpoint is gone but the API key or client secret still works against a sibling service that shares the same validation.
  • Non-production with production data: beta and staging hosts that read real data but lack production controls, the exact pattern in OWASP's API9 scenario.

Practitioner checklist

  • Reconcile specifications, gateway logs, runtime telemetry and code at least monthly, and classify every endpoint as healthy, shadow, zombie or stale spec.
  • Generate OpenAPI or protobuf definitions from code in CI and fail builds with undeclared routes.
  • Configure gateways to reject undeclared paths; replace wildcard forwarding rules with explicit routes.
  • Record owner, environment, exposure, version and backing data store for every endpoint.
  • Map every API key, OAuth client and service account to the endpoint and consumer that uses it.
  • Publish a version policy with minimum notice periods and use Deprecation and Sunset headers on every deprecated operation.
  • Keep deprecated versions under full monitoring and patching until removal day.
  • Decommission in order (route, backend, ingress and DNS, code) and then revoke the identities.

Standards and references

Related NHI Mgmt Group resources: API Gateway Security Guide, API Management vs API Security, NHI Inventory Reconciliation, Cloud Account and Resource Decommissioning.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 14 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org