Metadata-Version: 2.4
Name: speculynx
Version: 0.1.5
Summary: Local-first OpenAPI 3.0/3.1 security audit CLI
Author: Sami-BUTRT
License-Expression: MIT
Project-URL: Homepage, https://github.com/Sami-BUTRT/speculynx-cli
Project-URL: Repository, https://github.com/Sami-BUTRT/speculynx-cli
Project-URL: Issues, https://github.com/Sami-BUTRT/speculynx-cli/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Testing
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer<1,>=0.12
Requires-Dist: PyYAML<7,>=6
Requires-Dist: httpx<1,>=0.27
Requires-Dist: fpdf2<3,>=2.7
Requires-Dist: keyring<26,>=25
Dynamic: license-file

# Speculynx CLI

Speculynx is a local-first Python/Typer CLI for auditing OpenAPI 3.0.x and
3.1.x files for API security risks. Swagger 2.0, GraphQL, gRPC, and SOAP are
outside the MVP scope.

OpenAPI files are analyzed locally. Speculynx does not send customer OpenAPI
documents to the backend. Free scans work without a license and without network
access.

## Install

### Recommended on Debian and Ubuntu

`pipx` installs Speculynx in an isolated Python environment without changing
the system Python packages:

```bash
sudo apt update
sudo apt install -y pipx
pipx ensurepath
pipx install speculynx
speculynx --help
```

You may need to reopen your terminal after running `pipx ensurepath`.
For an immediate one-session setup, you can also run:

```bash
export PATH="$PATH:$HOME/.local/bin"
```

The `export` command is not required for every user or shell. Once `pipx` is
already installed, the generic installation command is:

```bash
pipx install speculynx
```

### Windows PowerShell

```powershell
py -m pip install --user pipx
py -m pipx ensurepath
pipx install speculynx
speculynx --help
```

### macOS

When `pipx` is already available on macOS, use:

```bash
pipx install speculynx
speculynx --help
```

This page does not prescribe a macOS package manager setup.

### Update or uninstall

```bash
pipx upgrade speculynx
pipx uninstall speculynx
```

### Local source checkout

For contributors working from a local checkout, a virtual environment remains
the supported development workflow:

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e .
```

Verify the installation:

```powershell
speculynx --help
speculynx scan --file openapi.yaml
```

Free static scans work immediately without a license or backend connection.
For Pro features, run `speculynx login`: the command prompts interactively for
the license key with hidden input, verifies it with the licensing backend, and
stores a valid key in the operating-system credential store.

After a package build, install the wheel locally:

```powershell
python -m pip install dist\speculynx-0.1.5-py3-none-any.whl
```

## Commands

```powershell
speculynx --help
speculynx --version
speculynx scan --file path\to\openapi.yaml
speculynx login
speculynx info
speculynx logout
```

`login` verifies a Pro license key with:

```text
POST /v1/verify
Authorization: Bearer <license_key>
```

The key is stored with the operating-system credential store through `keyring`.
Legacy `~/.speculynx.json` files are ignored.
`login` exits with a nonzero status when verification or secure storage fails.

### Licensing backend for development and tests

Ordinary users do not need to configure the licensing backend. By default,
Speculynx verifies Pro licenses against the exact official origin
`https://api.speculynx.dev`.

Development and E2E environments can set `SPECULYNX_API_BASE_URL` only to the
exact official origin or to a local loopback backend. For example:

```powershell
$env:SPECULYNX_API_BASE_URL = "http://127.0.0.1:8000"
speculynx login
```

Only the exact hosts `localhost`, `127.0.0.1`, and `::1` are accepted as an
override, over HTTP or HTTPS. Third-party domains are refused even over HTTPS.
The value is a backend base URL: do not put a license key, credentials, query
string, fragment, or API path in it. Speculynx builds the canonical
`/v1/verify` endpoint, does not follow redirects, and does not store this
setting in `keyring` or a user configuration file. Never use a production
license key against a local development backend.

## Installation troubleshooting

- `speculynx` not found: activate the virtual environment or ensure its
  `Scripts` directory is in `PATH`; for a pipx install, reopen the terminal
  after `pipx ensurepath`.
- `pipx` not found on Debian/Ubuntu: install it with `sudo apt install -y pipx`,
  then run `pipx ensurepath`.
- Unsupported Python: install Python 3.10 through 3.13.
- File not found: verify the path passed to `--file`.
- Swagger 2.0 rejected: convert the document to OpenAPI 3.0 or 3.1.
- Pro feature refused: check the stored license with `speculynx info`, then use
  `speculynx login` again if needed.

## Free Scan

```powershell
speculynx scan --file path\to\openapi.yaml
```

Free rules include:

- `KEY-EXP-01`: keys or tokens exposed in query parameters.
- `HTTP-001`: insecure `http://` server URLs.
- `AUTH-001`: missing documented authentication.
- `KEY-EXP-02`: rotation or lifetime undocumented for an API key explicitly described as static or durable.

Free scans are explicitly partial: they run the four rules above and list the
Pro rules that were not executed. A Free scan with no finding reports an
indeterminate global verdict; it is not a validation that the API is secure.
OpenAPI files stay local. License verification sends no OpenAPI content to the
licensing service.

## JSON and CI/CD

Use `--json` for a single machine-readable JSON document on stdout:

```bash
speculynx scan --file openapi.yaml --json
```

Schema `1.0` includes the tool and input versions, scan mode, coverage,
executed, skipped, and non-evaluated rule IDs, per-control statuses, severity
counts, findings, and verdict. Per-control statuses are:

- `PASS`: the control ran and detected no matching signal;
- `FAIL`: the control ran and detected a risk signal;
- `NOT_EVALUATED`: the control could not produce a reliable result;
- `ERROR`: the command or control failed before producing a security result.

`NOT_EVALUATED` controls are not findings and are counted as neither `PASS`
nor `FAIL`. When a stored Pro license cannot be verified because the licensing
service is unavailable or its response is unusable, Free controls still run
locally while Pro controls are listed as `NOT_EVALUATED`. With no stored key,
or after a confirmed invalid or expired license, Pro controls remain skipped.
Fatal input or command errors can exit without emitting a JSON result.

These fields are additive within schema `1.0`; removing or renaming an existing
field requires a new schema version.

Use `--fail-on` with `critical`, `high`, `medium`, `low`, or `never` (the
backward-compatible default). A threshold blocks on that severity and higher:

```bash
speculynx scan --file openapi.yaml --json --fail-on high > speculynx-report.json
```

Minimal GitHub Actions step:

```yaml
- name: Audit OpenAPI
  run: |
    speculynx scan \
      --file openapi.yaml \
      --json \
      --fail-on high \
      > speculynx-report.json
```

Exit codes:

- `0`: scan completed and no finding reached the configured threshold;
- `1`: at least one finding reached the threshold;
- `2`: invalid argument, missing file, invalid JSON/YAML, or unsupported OpenAPI version;
- `3`: unexpected internal rule failure;
- `4`: a Pro-only operation was explicitly requested but unavailable.

Exit `0` for a partial Free scan means only that no executed Free finding met
the threshold. Coverage remains `partial` in both text and JSON.

## Pro Scan

With a valid Pro license, `scan` also runs heuristic checks for patterns such as
BOLA, BFLA, sensitive data exposure, likely secrets in examples, SSRF inputs,
missing rate-limit documentation, and unclear API inventory/versioning.

Pro findings are static analysis signals, not proof of runtime vulnerabilities.
They should be manually verified against backend authorization, gateway, and
infrastructure controls.

## PDF Export

PDF export is Pro-only:

```powershell
speculynx scan --file path\to\openapi.yaml --export report.pdf
```

In Free mode the export is refused.

## Live Scan / DAST

`scan-live` is Pro-only and can send real HTTP requests to a target API. It is
safe-by-default:

- only `GET` requests are sent by default;
- `POST`, `PUT`, `PATCH`, and `DELETE` require `--allow-unsafe-methods`;
- `--yes` does not unlock unsafe methods by itself;
- `--dry-run` prints planned requests without sending HTTP traffic;
- `--insecure` must be explicitly provided to disable TLS verification.

Examples:

```powershell
speculynx scan-live --file openapi.yaml --target https://api.example.com --dry-run
speculynx scan-live --file openapi.yaml --target https://api.example.com --yes
speculynx scan-live --file openapi.yaml --target https://api.example.com --yes --allow-unsafe-methods
```

Only run `scan-live` against systems you own or are explicitly authorized to
test.

## Development

```powershell
python -m unittest discover -s tests -v
python -m build
```
