> For the complete documentation index, see [llms.txt](https://docs.xygeni.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xygeni.io/xygeni-products/api-security/api-security-scanner.md).

# API Security Scanner

## Table of Contents

1. [Purpose](#purpose)
2. [Installation](#installation)
3. [Quick Start](#quick_start)
4. [Scan Modes](#scan_modes)
5. [Inputs — Directory, Repository, Staged Files](#inputs)
6. [Hybrid Scanning — Specs & Live Probing](#hybrid)
7. [Output Formats](#outputs)
8. [Backend Upload](#upload)
9. [Framework Selection](#frameworks)
10. [CI / CD Integration](#cicd)
11. [Command Reference](#command_reference)
12. [Exit Codes](#exit_codes)

### Purpose <a href="#purpose" id="purpose"></a>

The **API Security Scanner** performs static API discovery and security analysis on a source-code project. It walks the project tree and any OpenAPI / Swagger descriptors, builds an inventory of services, modules, endpoints, parameters, and data objects, and then runs the OWASP API Security Top 10 (2023) detectors against the inventory to produce a list of flaws.

The scanner is invoked through the standard Xygeni CLI as the `apisecurity` subcommand. It produces the same metadata, evidence, and severity model as the other Xygeni scans, so its findings integrate uniformly into dashboards, gates, and compliance reports.

### Installation <a href="#installation" id="installation"></a>

The API Security scanner ships as part of the Xygeni Scanner — there is no separate binary or container. Install the Xygeni Scanner following the [Xygeni CLI Installation guide](/xygeni-scanner-cli/xygeni-cli-overview/xygeni-cli-installation.md), then verify the `apisecurity` subcommand is available:

```bash
xygeni apisecurity --help
```

### Quick Start <a href="#quick_start" id="quick_start"></a>

Scan a local checkout and write a JSON report:

```bash
xygeni apisecurity --dir /path/to/project -f json -o report.json
```

Inventory-only mode (no flaw detection):

```bash
xygeni apisecurity --dir /path/to/project --discovery-only -f json -o inventory.json
```

Scan and upload to the Xygeni backend:

```bash
xygeni apisecurity --dir /path/to/project --upload
```

### Scan Modes <a href="#scan_modes" id="scan_modes"></a>

Two modes selected by a single flag:

| Mode               | Flag               | What it does                                                                                                                                                                                                                                                                                                   |
| ------------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Full scan**      | (default)          | Discovery + flaw detection. The inventory plus all enabled OWASP API risk detectors run end to end.                                                                                                                                                                                                            |
| **Inventory-only** | `--discovery-only` | Discovery only. No flaw detection. Useful for feeding the inventory to SAST / DAST correlators, generating an API catalog, or comparing the implemented API against a documented spec without producing flaw findings. Sensitivity classification (PII / PCI / PHI / credential tags) still runs in this mode. |

### Inputs — Directory, Repository, Staged Files <a href="#inputs" id="inputs"></a>

Three input modes:

| Flag                            | Effect                                                                                                                        |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `--dir <path>` (default)        | Scan a local checkout.                                                                                                        |
| `-r, --repo <url>` `--branch …` | Clone the remote repository to a temporary directory, scan it, and remove the clone after the scan completes.                 |
| `--staged-files`                | Scan only files staged in the local git index — useful as a pre-commit gate. Requires `--dir` to point at a git working tree. |

`--include` and `--exclude` accept comma-separated glob patterns to narrow the file set further (for example, `--exclude '**/test/**,**/build/**'`).

### Hybrid Scanning — Specs & Live Probing <a href="#hybrid" id="hybrid"></a>

Beyond the source-code scan, two optional inputs let you enrich and confirm the analysis:

| Flag                   | Effect                                                                                                                                                                                                                                                                                                     |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--spec <path-or-url>` | Ingest one or more OpenAPI / Swagger specs — local files **or** `http(s)` URLs — in addition to anything auto-discovered under `--dir`. Repeatable or comma-separated. Endpoints from the spec are merged into the same inventory, which also powers the `zombie_endpoint` / `orphan_spec` drift detector. |
| `--base-url <url>`     | Deployed-app base URL that **enables opt-in live probing** (off unless provided). For detectors that support it, the scanner issues a request per candidate endpoint and reads the gateway's response to confirm or refute the static verdict.                                                             |

```bash
# Source scan + explicit specs (file and URL)
xygeni apisecurity --dir . --spec openapi.yaml,https://api.example.com/openapi.json

# Confirm "unauthenticated endpoint" findings against a live deployment
xygeni apisecurity --dir . --base-url https://api.dev.example.com
```

Live probing is **non-destructive**: it never removes findings, it annotates each probed flaw with a `liveProbe` property —

* `confirmed-<status>` — the endpoint answered without credentials (the static finding is corroborated),
* `refuted-401` / `refuted-403` — the deployed gateway enforces authentication the source did not show,
* `unreachable` — the endpoint could not be contacted (connection refused, timeout, TLS error).

Probes run concurrently with a bounded pool and a per-request timeout, and any network error is isolated — probing never aborts a scan. It is opt-in precisely because it makes outbound requests to the target you name; do not point `--base-url` at production without authorization.

### Output Formats <a href="#outputs" id="outputs"></a>

`-f` (repeatable) selects one or more output formats; `-o` selects the target file. When more than one format is requested, the file name is decorated with the format extension.

| Format           | Description                                                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `text` (default) | Human-readable summary on stdout. Best for ad-hoc scans and developer feedback.                                                            |
| `json`           | Full report shape — services, modules, endpoints, data objects, flaws, statistics, scanner metadata. The canonical machine-readable shape. |
| `xygeni-json`    | Xygeni backend wire format — internally used by `--upload` but also emittable for offline upload pipelines.                                |
| `csv`            | Flat, one-row-per-finding tabular export for spreadsheets and quick triage.                                                                |
| `markdown`       | Markdown summary, convenient for PR comments and CI job summaries.                                                                         |
| `sarif`          | SARIF 2.1.0 — for ingestion by GitHub Code Scanning, Azure DevOps, and other tools that consume SARIF.                                     |

The JSON shape mirrors the other Xygeni scans (`metadata`, `statistics`, top-level finding arrays, scanner properties, SCM information from the git working tree) so existing JSON consumers extend uniformly.

### Backend Upload <a href="#upload" id="upload"></a>

```bash
xygeni apisecurity --dir /path/to/project --upload
```

`--upload` uses the standard Xygeni backend ingest endpoint, the same one used by the SCA / SAST / Secrets / IaC scanners. The project is resolved by name (defaulting to the directory name; override with `-n <name>`), and the report is pushed under the same project's API Security scan history.

A scan that does *not* set `--upload` produces local output only — useful for CI gates and pre-commit hooks where backend persistence is not desired.

### Framework Selection <a href="#frameworks" id="frameworks"></a>

By default, **framework autodiscovery** is on: a lightweight pre-pass inspects the project's dependency manifests and loads only the detectors that match detected frameworks. This keeps scan time low and avoids cross-framework false positives.

Two flags override autodiscovery:

| Flag                       | Effect                                                                                                                  |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `--frameworks <list>`      | Pin the framework allowlist. Autodiscovery is **skipped** when this flag is set — user selection wins.                  |
| `--skip-frameworks <list>` | Add a framework denylist. Honored **after** autodiscovery, so the autodiscovered list is filtered against the denylist. |

Framework IDs follow the per-language naming used in [`xygeni.apisecurity.yml`](/xygeni-products/api-security/api-security-scanner/api-security-scanner-configuration.md) — for example, `spring-mvc`, `jax-rs`, `aspnet-core`, `fastapi`, `flask`, `django`, `express`, `nestjs`, `koa`, `fastify`, `hono`, `gin`, `laravel`, `openapi`.

### CI / CD Integration <a href="#cicd" id="cicd"></a>

The scanner is intended to be invoked from CI alongside the other Xygeni scans, typically against the project's `main` branch on each push and against the PR head on pull requests. Two common patterns:

```yaml
# Full scan on push to main — upload to backend
- name: API Security scan
  run: xygeni apisecurity --dir . --branch main --upload

# Pre-merge gate — fail the build on HIGH or above
- name: API Security gate
  run: xygeni apisecurity --dir . --fail-on high
```

`--fail-on <severity>` and `--never-fail` parallel the other Xygeni scans for gate behaviour. Most teams gate on HIGH for the first few weeks of adoption, then progressively tighten to MEDIUM as the noise floor settles.

### Command Reference <a href="#command_reference" id="command_reference"></a>

| Flag                       | Description                                                                                                  |
| -------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `--dir <path>`             | Local project directory to scan.                                                                             |
| `-r, --repo <url>`         | Clone a remote repository, scan it, and clean up after.                                                      |
| `--branch <name>`          | Branch to check out from the repository (used with `-r`) or to record on the report (used with `--dir`).     |
| `--staged-files`           | Scan only files in the git staging area.                                                                     |
| `-n, --name <name>`        | Project name (defaults to inferred from `--dir`).                                                            |
| `--discovery-only`         | Inventory-only mode — skip flaw detection.                                                                   |
| `--frameworks <list>`      | Comma-separated framework allowlist (skips autodiscovery).                                                   |
| `--skip-frameworks <list>` | Comma-separated framework denylist (applied after autodiscovery).                                            |
| `--include <patterns>`     | Comma-separated include globs.                                                                               |
| `--exclude <patterns>`     | Comma-separated exclude globs.                                                                               |
| `--spec <path-or-url>`     | OpenAPI / Swagger spec file(s) or URL(s) to ingest alongside the source scan (repeatable / comma-separated). |
| `--base-url <url>`         | Deployed-app base URL; enables opt-in live probing for detectors that support it (off unless set).           |
| `-c, --conf <file>`        | Override the bundled `xygeni.apisecurity.yml`.                                                               |
| `-f <fmt>` (repeatable)    | Output format(s) — `text`, `json`, `xygeni-json`, `csv`, `markdown`, `sarif`.                                |
| `-o, --output <path>`      | Output file (extension added when multiple formats are requested).                                           |
| `-u, --upload`             | Upload the report to the Xygeni backend.                                                                     |
| `--fail-on <severity>`     | Exit non-zero on findings of the given severity or above.                                                    |
| `--never-fail`             | Always exit `0`, regardless of findings.                                                                     |

### Exit Codes <a href="#exit_codes" id="exit_codes"></a>

These match the shared Xygeni exit-code convention used by the other scanners:

| Code  | Meaning                                                                                                                                          |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `0`   | Success — no findings, all findings below the `--fail-on` threshold, or `--never-fail` set.                                                      |
| `1`   | Invalid arguments.                                                                                                                               |
| `2`   | Scan setup / run error (e.g., directory not found, repository clone failed).                                                                     |
| `128` | At least one finding matched `--fail-on` — used when `--fail-on` is a **severity threshold** (or is given with no value, meaning "any finding"). |
| `129` | At least one finding matched a `--fail-on` **detector / expression** selector.                                                                   |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.xygeni.io/xygeni-products/api-security/api-security-scanner.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
