The API specification for the customer service lists 40 endpoints. Production answers 46. Nobody did anything wrong: one is a debug route a developer added during an incident, two are left from a version that was supposed to be retired, one is an export endpoint built for a partner integration, and two are internal admin calls that were never meant to be reachable from outside. Nobody reviewed them for authentication, because nobody knew they were there.

In short

  • You cannot secure an API you do not know exists. OWASP lists improper inventory management as one of the ten most important API risks for exactly this reason.
  • The specification describes intent, and production describes reality. Shadow endpoints live in the gap, and only something that observes the running application can see it.
  • The spec still matters. Read properly, it shows missing authentication, unbounded lists and mass-assignment risks before anything is deployed.
  • Testing a live application is an attack. It must be limited to targets a named person has confirmed the organisation owns, with the attestation on record.

The situation

This scenario is illustrative. APIs are now how most products expose data: to their own web and mobile front ends, to partners, and increasingly to AI agents. Each team publishes an OpenAPI specification, or means to, and the API gateway or load balancer routes traffic to whatever the service actually serves. Over time the two drift apart.

Industry
data

The OWASP API Security Top 10 (2023) includes API9, Improper Inventory Management: undocumented hosts and endpoints, and old versions left running. Several widely reported breaches have been attributed to API endpoints that were exposed without authentication, including the 2022 Optus breach in Australia, where public reporting pointed to an unauthenticated API endpoint.

Sources: OWASP API Security Top 10, 2023 edition; public reporting and Australian parliamentary inquiry material on the 2022 Optus breach.

Why existing tooling misses it

  • Static analysis reads the code it is given. It sees routes in the repository it scans, not the legacy service still deployed from an older branch.
  • A spec-driven API test only tests the spec. If the endpoint is not in the specification, the test never calls it.
  • Gateways log everything and judge nothing. The traffic for the shadow endpoint is in the access logs, but nothing compares it with what was documented.
  • Pen tests are snapshots. An annual test finds what existed that week.
TODAY The spec is the inventory

Security reviews what is documented. Anything added without a spec change, or left behind after a version was retired, is invisible until someone outside finds it.

OBSERVED INVENTORY The inventory is spec plus observation

Endpoints come from the specification, from dynamic scans of the running application and from gateway traffic. Anything served but not documented is a finding with an owner.

Three sources, one inventory

flowchart LR S["OpenAPI specs
in the repository"] --> INV["API inventory
per service"] D["DAST crawl
OWASP ZAP"] --> INV T["Gateway or access-log
traffic counts"] --> INV INV --> C{"Served but
in no spec?"} C -->|"Yes"| SH["Shadow API finding
OWASP API9"] C -->|"No"| OK["Documented
auth checked against spec"] INV --> A{"Spec says auth required
but 2xx without it?"} A -->|"Yes"| AU["Broken authentication
finding, OWASP API2"] style SH fill:#fef3c7,stroke:#f59e0b style AU fill:#fee2e2,stroke:#ef4444

Each source fills a different gap: the spec gives intent, the crawl gives reachability, traffic gives what is actually called.

1. The specification: what the team says it serves

Every OpenAPI specification in a scanned repository becomes inventory, and it is checked against the OWASP API Top 10 where a specification can show the problem: operations with no security requirement, HTTP Basic or API keys in the query string, servers declared over plain HTTP, list operations with no way to page them, write operations that accept a free-form object (the mass-assignment pattern), and operations marked deprecated. These are design findings, caught before deployment.

2. The dynamic scan: what the application answers

OWASP ZAP runs against web targets in three modes: baseline (a crawl plus passive checks), full (active testing) and api (driven by the specification). Every endpoint the crawl reaches is recorded as seen. After the scan, InsightFortify compares what the application answered with the specifications in the linked repository. Anything served that no specification describes becomes an undocumented endpoint finding, mapped to OWASP API9, with the method, the path and a clear remediation: document it and review its authentication, or retire it.

3. Traffic: what is really called

Request counts from an API gateway or access logs can be sent to InsightFortify on a schedule. Traffic marks endpoints as seen, so a shadow endpoint appears on the day someone starts calling it, and it raises two runtime findings: an endpoint the specification says requires authentication answering successfully to unauthenticated requests, and authentication failures concentrated on one endpoint, which is the shape of credential stuffing or object-id enumeration.

The APIs page: 28 endpoints across 2 services, a shadow count, 2 endpoints with no authentication in the spec, and each endpoint with its method, path, service, spec status, auth requirement, source and hits
API inventory. Endpoints from specifications, DAST crawls and traffic, with whether each is documented and whether its spec requires authentication. In the demo, 28 endpoints across two services, two of them open by declaration.

Scanning only what you own

A dynamic scan sends real attack traffic. Pointing one at a system you do not own is not a mistake a security product should make easy, so InsightFortify will not scan a web target until a security lead has verified it. Verification is a written attestation of how the person knows the target is the organisation’s to test, recorded in the audit trail with their name. By default, a full active scan of a target marked as production runs as a baseline scan unless the deployment explicitly allows otherwise. Credentials for authenticated scanning are stored as references to a secrets manager, never as values.

The web apps page listing Juice Shop (local demo) at localhost:3000, verified, environment local, baseline scan, 8 open findings and 23 endpoints seen
Web apps. Each target with its verification status, environment, scan mode, open findings and the endpoints the crawl has seen. The demo target is a local OWASP Juice Shop.

Who does what

sequenceDiagram autonumber participant SL as Security lead participant F as InsightFortify participant Z as OWASP ZAP participant GW as API gateway participant SA as Security analyst participant ST as Service team SL->>F: Add web target, link repository, attest ownership F->>Z: Baseline or API scan of the verified target Z-->>F: Alerts and every endpoint reached GW->>F: Daily request counts per endpoint F->>F: Compare served endpoints with the specs F-->>SA: Undocumented endpoint findings, API9 SA->>ST: Is this endpoint meant to exist ST->>ST: Document and add auth, or retire it ST->>F: Spec updated or route removed Z-->>F: Next scan F->>F: Finding closes - now documented or no longer served

The security lead’s attestation in step 1 is the gate: no attestation, no scan.

Working a shadow endpointThe question for each one: should it exist?
1
Verify and link the targetsecurity lead

Add the running application, link it to the repository that holds its specification, and record the ownership attestation. Without a spec to compare with, nothing is called shadow, because everything would be.

2
Scan and import trafficsecurity analyst

Run a baseline or API scan on a schedule, and send gateway traffic counts if you have them.

3
Ask the ownersecurity analyst + service team

For each undocumented endpoint: who built it, who calls it, and does it require authentication?

4
Document or retireservice team

If it should exist, add it to the specification with its security requirement, which also brings it under spec-based checks. If not, remove the route.

5
ConfirmInsightFortify

The next scan or traffic import closes the finding as “now documented, or no longer served”.

Rolling it out across a portfolio

Most organisations have dozens or hundreds of APIs, and not all of them deserve the same attention on day one. A sensible order follows exposure and data, the same factors that drive every other priority in InsightFortify.

WaveWhich APIsWhat to turn onWhy first
1Customer- and partner-facing APIs that handle personal or payment dataSpec checks, verified target, scheduled baseline scan, gateway trafficHighest exposure, highest impact, most likely to be targeted
2Other internet-facing APIs and mobile back endsSpec checks and scheduled scansExposed, but lower-value data
3Internal APIs that AI agents or integrations callSpec checks, traffic where availableAgents and integrations turn internal APIs into indirect external ones
4Everything elseSpec checks in CICheap, and catches design flaws early

The third wave deserves a word. As teams give AI agents tools that call internal APIs, an internal endpoint with weak authentication becomes reachable through the agent by anyone who can talk to it. An API inventory that knows which endpoints exist and which require authentication is the foundation for deciding what an agent should be allowed to call.

Finally, budget for the conversation, not just the scan. Each undocumented endpoint needs a human answer to “should this exist?”, and the people who know are usually on the service team. A short weekly review of new shadow findings, with the service owners in the room, clears them far faster than a ticket queue does.

What it means for each audience

For the CISO

API inventory is the API equivalent of an asset register, and regulators and auditors increasingly expect one. “Every externally reachable endpoint is documented and has an owner” is an assertion you can now support.

The shadow count is a good leading indicator of engineering discipline. If it keeps rising, the issue is process, not tooling.

For the AppSec lead

Spec findings catch design flaws before deployment. Shadow findings catch drift after it. You need both, and they land in the same queue with the same SLA as everything else.

Linking each web target to its repository is what makes the comparison possible. Do it when you add the target.

For the board

Ask how many endpoints customers and partners can reach, how many of them are documented, and how many accept requests without authentication. The last two numbers should be 100% and zero.

Undocumented, unauthenticated APIs feature in some of the most damaging data breaches of recent years.

Outcome metrics to track

Documented shareof endpoints seen by scans or traffic that appear in a specification
Shadow endpointsopen undocumented-endpoint findings. Trend to zero.
Open by declarationendpoints whose spec requires no authentication, each reviewed and justified
Verified targetsshare of customer-facing applications under scheduled dynamic scanning

Limits to know about

  • A crawl only finds what it can reach. Routes that need a specific token or a deep workflow may never be crawled. Traffic data closes much of that gap.
  • No spec, no comparison. A service with no OpenAPI specification gets dynamic findings and an endpoint list, but no shadow analysis. Getting a spec in place is step one.
  • Retired versions still need retiring. InsightFortify flags operations the spec marks deprecated, but it does not yet decide on its own that a documented endpoint has fallen out of use. Traffic counts show which ones nobody calls.

Your API specification is a statement of intent. Production is the truth.

Build the inventory from both, give every undocumented endpoint an owner, and make “document it or retire it” the only two ways to close one.

Keep reading