Metadata-Version: 2.4
Name: vulgpt
Version: 0.2.0
Summary: Evidence-first AI-assisted security testing for explicitly authorized web targets.
Author: VULGPT contributors
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: authorized-testing,cli,pentest,recon,security
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Requires-Python: >=3.11
Requires-Dist: cryptography==49.0.0
Requires-Dist: keyring==25.7.0
Provides-Extra: dev
Requires-Dist: build==1.5.0; extra == 'dev'
Requires-Dist: pytest-cov==7.1.0; extra == 'dev'
Requires-Dist: pytest==9.1.1; extra == 'dev'
Requires-Dist: ruff==0.15.22; extra == 'dev'
Description-Content-Type: text/markdown

# VULGPT

VULGPT is a CLI-first, evidence-first assistant for assessing web targets you are explicitly
authorized to test. It accepts plain-language goals, executes a bounded set of real HTTP checks,
records immutable evidence, distinguishes observation from inference, and produces clean Markdown
and JSON reports with constrained Python proofs for confirmed findings.

It includes three interfaces over the same guarded engine:

- **CLI** for automation, CI, and repeatable runs.
- **Local Web workspace** for a Codex-like task, evidence, finding, and history experience.
- **Terminal workspace** for interactive use without leaving the terminal.

> **Authorization is mandatory.** VULGPT records your attestation; it cannot independently prove
> that you own a target or have permission to test it. Use it only where you have clear written
> authorization and an agreed scope.

## Install VULGPT

VULGPT requires Python 3.11 or newer. The recommended installation method is `pipx`: it installs
the CLI in its own environment and makes the `vulgpt` command available without affecting other
Python projects.

### Recommended: install with pipx

**Windows (Command Prompt or PowerShell):**

```powershell
py -m ensurepip --upgrade
py -m pip install --upgrade pip
py -m pip install --user pipx
py -m pipx ensurepath
```

Close the terminal, open a new one, then install and start VULGPT:

```powershell
pipx install vulgpt
vulgpt --version
vulgpt
```

**macOS or Linux:**

```bash
python3 -m pip install --upgrade pip
python3 -m pip install --user pipx
python3 -m pipx ensurepath
pipx install vulgpt
vulgpt
```

### Alternative: install with pip

```powershell
py -m pip install --upgrade pip
py -m pip install --user vulgpt
```

Then open a new terminal and run `vulgpt`. Prefer `pipx` if you have it available.

### If installation does not work

| Problem | Check or fix |
| --- | --- |
| `No module named pip` | Run `py -m ensurepip --upgrade`. If `ensurepip` is unavailable, repair or reinstall Python and select the **pip** optional feature. |
| `vulgpt is not recognized` | Run `py -m pipx ensurepath`, close every terminal window, then open a new one. You can also run `py -m pipx install vulgpt`. |
| An old package is installed | Run `pipx upgrade vulgpt`, or `py -m pip install --upgrade --user vulgpt`. |
| You need to confirm the installed package | Run `vulgpt --version` and `py -m pip show vulgpt`. |

## Configure OpenRouter (optional AI features)

VULGPT releases never include, share, or download an OpenRouter API key. Each person who wants to
use model-assisted planning or finding summaries must create and use their **own** OpenRouter key.
Do not put a key in this repository, a release asset, source code, a README, or a screenshot.

### Recommended: store your key with VULGPT

```powershell
vulgpt config set-key openrouter
```

VULGPT prompts for the key without displaying it and stores it using the operating system's
protected secret store. Check the configuration safely with:

```powershell
vulgpt config show
```

The output reports only `has_key: true` or `false`; it never prints your key.

### Manual Windows option: environment variable

If you prefer not to use the CLI key prompt, open **Edit environment variables for your account**
in Windows. Under **User variables**, create:

```text
Name:  OPENROUTER_API_KEY
Value: your OpenRouter API key
```

Close and reopen your terminal after saving it. This variable belongs only to your Windows account;
it is not packaged into VULGPT and is not shared with other users.

### Choose the Qwen 32B model

```powershell
vulgpt config provider openrouter --base-url https://openrouter.ai/api/v1 --model qwen/qwen3-32b
vulgpt config use openrouter
```

`qwen/qwen3-32b` is a paid OpenRouter model. `openrouter/auto` is not a free-only setting, so check
your OpenRouter Activity page and credit balance before running model-assisted work.

### CLI commands

#### Start here: one command for a standard assessment

For most authorized website assessments, use one command:

```powershell
vulgpt assess https://app.example.com --authorize `
  --authorized-by "Jane Doe, project owner" `
  --scope-note "Owner-authorized security test; no destructive actions."
```

`assess` runs the standard bounded sequence for you: reconnaissance, passive deterministic checks,
and a saved Markdown/JSON report. It does not enable benign verification automatically; add
`--safe-poc` only when that extra, allowlisted phase is appropriate for the authorized scope.

Use `vulgpt --help` for current argument details and `vulgpt <command> --help` for a specific
command. The focused commands below are available when you need them.

#### Assessment commands

| Command | Purpose |
| --- | --- |
| `vulgpt assess <target>` | **Recommended:** run one bounded assessment with reconnaissance, passive checks, and a report. |
| `vulgpt preflight <target>` | Preview scope, authorization, phases, and limits without contacting a target. |
| `vulgpt recon <target>` | Run only bounded reconnaissance for an authorized target. |
| `vulgpt scan <target>` | Run only passive deterministic checks for an authorized target. |
| `vulgpt full <target>` | Advanced equivalent of the full assessment flow, with optional benign verification. |
| `vulgpt run ...` | Compile and run an authorized plain-language assessment goal. |
| `vulgpt continuous <target>` | Schedule sequential full-run epochs. |

#### Results and workspace

| Command | Purpose |
| --- | --- |
| `vulgpt` | Open the interactive command guide and display the VULGPT banner. |
| `vulgpt prompt ...` / `vulgpt ask ...` | Convert a plain-language request into a safe command suggestion. |
| `vulgpt workspace` / `vulgpt web --open` | Open the terminal workspace or loopback-only Web workspace. |
| `vulgpt history [list]` / `vulgpt history show <session-id>` | List or inspect saved sessions. |
| `vulgpt report <session-id>` | Print a saved Markdown or JSON report path. |

#### Setup and authorization

| Command | Purpose |
| --- | --- |
| `vulgpt doctor` | Check Python, storage, TLS, SQLite, and provider readiness. |
| `vulgpt config show\|provider\|use\|set-key\|delete-key` | Manage redacted provider configuration and protected keys. |
| `vulgpt scope add\|list\|remove\|add-workspace` | Manage saved URL and local-workspace authorizations. |
| `vulgpt approval list\|decide` | Inspect or answer scoped approval requests. |
| `vulgpt admin status\|authorize-tool\|list\|revoke` | Record or revoke short-lived external-tool approvals; never executes a tool itself. |
| `vulgpt identity show` / `vulgpt ledger verify\|list` | Inspect the device identity and verify the authorization ledger. |

#### Advanced safety inspection

| Command | Purpose |
| --- | --- |
| `vulgpt tools list\|evaluate` | Inspect dry-run tool packs and policy decisions. |
| `vulgpt safety verify-host\|requirements` | Inspect host-execution safety boundaries. |
| `vulgpt isolation verify-profile\|show-profile\|verify-runtime` | Inspect the pinned, non-running isolation profile. |
| `vulgpt audit run <tool> <workspace>` | Run one explicitly approved isolated code-audit adapter. |
| `vulgpt --version` / `vulgpt --json` | Show the installed version or request machine-readable output. |

## What the MVP does

- Compiles requests such as `test https://app.example.com` into a deterministic goal.
- Runs the standard `assess` flow (reconnaissance, passive checks, and report), focused recon or
  scan phases, advanced full runs, or sequential continuous epochs.
- Uses a same-scope crawler with request, response-size, depth, redirect, and rate limits.
- Resolves and validates every destination, rejects mixed public/private DNS answers, fixes the
  address set for the run, and pins the selected address for the actual TCP/TLS connection.
- Observes headers, cookies, forms, mixed content, directory indexes, security metadata, robots,
  and sitemap behavior.
- Optionally performs allowlisted benign CORS and open-redirect verifiers.
- Records a bounded OpenRouter model planning suggestion and can summarize verified findings.
  Dependency-safe deterministic phase order remains authoritative; the model never receives raw page
  bodies, executes tools, expands scope, or confirms a finding.
- Stores redacted session history in SQLite. Raw response bodies and provider keys are not stored in
  the session database.
- Generates reports in Markdown and JSON and bounded Python PoCs from audited templates.

The MVP deliberately does **not** brute force, submit forms, upload files, bypass authentication,
run arbitrary shell commands, execute payloads, exploit SQL/command injection, stress services,
follow cross-scope redirects, or automatically execute generated PoCs.

## Install from a checkout

VULGPT requires Python 3.11 or newer and has no required runtime dependencies.

```powershell
py -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e .
vulgpt doctor
```

On macOS or Linux, activate with `source .venv/bin/activate`.

### Python SDK

The repository also includes a local Python SDK in `packages/python-sdk`. It keeps the same
authorization and target-scope controls as the CLI; it does not expose an unsafe raw transport.

```python
from vulgpt_sdk import AssessmentRequest, AuthorizationAttestation, VulgptClient

client = VulgptClient()
request = AssessmentRequest(
    target="https://app.example.com",
    authorization=AuthorizationAttestation(
        authorized_by="Jane Doe",
        scope_note="Customer approval SEC-2041",
    ),
)
result = client.run(request)
```

Install it from a checkout with `python -m pip install ./packages/python-sdk`. Once the SDK is
published separately, the installation command will be `pip install vulgpt-sdk`.

## Start with the CLI

Every one-time run needs `--authorize` unless the exact target has a saved active scope.
Start from a query-free base URL; VULGPT refuses to persist signed or credential-bearing target
URLs.

### Authorization command syntax

`--authorize` is an option of an assessment command; it is **not** a standalone VULGPT command.
Put it after `assess`, `run`, `preflight`, `recon`, `scan`, `full`, or `continuous`, together with the target.
For example, this is valid:

```powershell
vulgpt assess https://app.example.com --authorize `
  --authorized-by "Jane Doe, project owner" `
  --scope-note "Owner-authorized security test; no destructive actions."
```

This is not valid:

```powershell
vulgpt --authorize
```

`--authorized-by` records the person or team providing the attestation. `--scope-note` is a short
reference to written permission, such as a ticket number, contract/SOW number, bug-bounty scope, or
an owner-approval note. It is an audit record only; it does not create permission. Never include
API keys, passwords, private URLs, or full contract text in a scope note.

```powershell
vulgpt assess https://app.example.com `
  --authorize `
  --scope-note "Customer approval SEC-2041"

# Focused or automation-friendly alternatives
vulgpt recon https://app.example.com --authorize
vulgpt scan https://app.example.com --authorize
vulgpt full https://app.example.com --authorize --safe-poc
```

### Preview before a run

Use `preflight` when you want to confirm the canonical URL, authorization source, deterministic
phases, and active network limits before an assessment session exists. It never resolves or contacts
the target, creates a session, or calls a model provider.

```powershell
vulgpt preflight https://app.example.com `
  --mode full `
  --authorize `
  --scope-note "Customer approval SEC-2041"
```

`--safe-poc` is a separate capability. It enables only the allowlisted benign verifier phase and
PoC export; goal text such as “exploit this” cannot enable it.

For an authorized local lab, both authorization and the explicit network override are required:

```powershell
vulgpt full http://127.0.0.1:8080 `
  --authorize `
  --allow-private `
  --scope-note "Local training lab"
```

Cloud metadata, link-local, multicast, unspecified, and reserved destinations remain blocked.

### Save an authorization scope

```powershell
vulgpt scope add https://app.example.com `
  --authorized-by "Security Team" `
  --note "Signed SOW 2026-Q3" `
  --expires-at "2026-09-30T18:00:00+05:30"

vulgpt scope list
```

Saved scopes match the exact canonical URL. At run time, that URL and its descendant path subtree are
in scope; discovered hosts, sibling paths outside a non-root subtree, and model output cannot widen it.
Scope notes are descriptive audit records, not an exclusion-rule language.

### Continuous testing

Continuous mode schedules finite, non-overlapping full runs. Each epoch receives a fresh budget and
its own report. Only successfully completed epochs advance the comparison baseline; incomplete or
rate-limited epochs never mark prior findings resolved.

```powershell
vulgpt continuous https://app.example.com `
  --authorize `
  --interval 300 `
  --max-runs 4
```

Use `--max-runs 0` to continue until Ctrl+C. The default minimum interval is 60 seconds.

## Open the Codex-like local workspace

```powershell
vulgpt web --open
```

The Web UI binds only to `127.0.0.1` on a random unused port by default. Each launch prints an
unguessable capability URL that mints an
HttpOnly, SameSite session cookie; API requests without it are rejected. The server also rejects
unrecognized Host headers, checks Origin and an ephemeral CSRF token on every mutation, sends no
permissive CORS headers, and applies a restrictive Content Security Policy. It is a local
interface—not a remotely deployable multi-user service.

The workspace provides:

- a plain-language run composer with explicit mode and authorization controls;
- a live phase timeline and run status;
- operator cancellation that waits for the current bounded network step to unwind safely;
- evidence-linked findings and downloadable reports;
- keyset-paginated, server-searchable session history; and
- provider, model, base URL, and protected key settings.

### Production-grade local behavior

The local workspace is designed to remain predictable as history and evidence grow:

- HTTP request handling has a fixed worker ceiling, while assessment jobs retain their separate
  two-run limit and exact-target deduplication.
- Finished job handles are removed immediately instead of accumulating for the life of the process.
- History uses stable `(created_at, session_id)` keyset cursors rather than increasingly expensive
  offsets. Search is bounded and parameterized in SQLite.
- Long evidence, finding, and history collections render in small browser-idle batches. Skeletons
  preserve layout while data loads, and finding proof details stay collapsed until requested.
- Static assets use content-hash ETags with private revalidation; API responses, reports, workspace
  HTML, and secrets remain `no-store`. Stable asset paths therefore cannot remain stale after a
  same-port restart.
- The interface uses semantic OKLCH design tokens, WCAG-oriented contrast, visible focus states,
  reduced-motion fallbacks, and responsive layouts down to 320 px.

These guarantees make the current release production-grade for its documented **single-user,
loopback-only** deployment model. A remotely hosted multi-user service would require a separate
identity, tenant-isolation, secrets-vault, worker-sandbox, and audit architecture and is intentionally
not implied by this release.

## Use the terminal workspace

```powershell
vulgpt workspace
```

This is an assessment workspace, not an operating-system shell. Useful commands include `run`,
`recon`, `scan`, `full`, `history`, `show`, `providers`, and `doctor`.

## Ask for the right command

When you do not remember the CLI syntax, start the interactive guide:

```powershell
vulgpt
```

Or request a one-shot suggestion:

```powershell
vulgpt prompt "recon the authorized target https://staging.example.com"
vulgpt ask "show my previous sessions"
```

The guide emits a copyable VULGPT command or short workflow and never executes it. Assessment
suggestions contain visible authorization placeholders; prompt text never grants permission. Requests
for Kali, credential, social-delivery, or other third-party tools remain execution-locked.

For a specifically named external capability, the guide may suggest an approval-only command:

```powershell
vulgpt admin authorize-tool nmap https://lab.example.test --note ENGAGEMENT_TICKET
```

The command requires VULGPT to already be running under a genuinely elevated operating-system
token: an elevated Windows administrator token or a POSIX root token. It requires an existing saved
scope for the same canonical target and creates a short-lived record only (30 minutes by default, at
most 120). It does not self-elevate, install, or execute the tool. Check the current token with:

```powershell
vulgpt admin status
```

On Windows, relaunch PowerShell or Windows Terminal with **Run as administrator** before creating or
revoking an approval. OS elevation still does not prove legal authority; the exact written scope and
engagement record remain mandatory.

## Authorization ledger and device identity

Initialize or inspect the non-secret local identity, then verify the HMAC-chained ledger:

```powershell
vulgpt identity show
vulgpt ledger verify
vulgpt ledger list --limit 20
```

The identity comes from a random 256-bit key protected by Windows DPAPI for the current OS user. The
ledger records scope grants/revocations and tool approvals/revocations before the mutable config is
changed. Each record binds its sequence, prior HMAC, device ID, exact target, subject ID, and bounded
metadata. Invalid chains fail closed and cannot receive new records. This provides local tamper
evidence; it is not hardware attestation, a remote signature, or legal proof.

## Tool packs and policy broker

```powershell
vulgpt tools list
vulgpt tools list --pack recon
vulgpt tools list --pack web-safe
vulgpt tools list --pack code-audit
vulgpt tools evaluate lab-active nmap https://lab.example.test
```

The broker is evaluation-only and deliberately has no process method. A separate reviewed runner can
start only the offline code-audit adapters for Semgrep, Gitleaks, and Trivy. Each image is pinned by
immutable digest, each binary path and SHA-256 is checked before use, and the workspace is mounted
read-only with network disabled. Lab-active adapters remain disabled even after an approval record.

`vulgpt doctor` detects WSL/Kali/container markers without launching a distribution, container, or
security tool. `vulgpt isolation verify-profile` validates the reviewed runtime controls, while
`vulgpt isolation verify-runtime` runs fixed clean-room checks against the local Docker or Podman
boundary. Detection alone is never treated as isolation, so lab-active execution remains locked.

### Offline code audit

Code audit uses a three-step, permission-first workflow. Run the approval and audit steps from an
elevated operating-system session:

```powershell
vulgpt scope add-workspace D:\Work\AuthorizedProject `
  --authorized-by "Security Team" `
  --note "Internal review SEC-310"

vulgpt admin authorize-tool gitleaks D:\Work\AuthorizedProject `
  --note "Internal review SEC-310"

vulgpt audit run gitleaks D:\Work\AuthorizedProject `
  --confirm-execution gitleaks
```

Replace `gitleaks` with `semgrep` or `trivy` after granting a matching per-tool approval. Semgrep uses
the bundled hash-bound local rules. Gitleaks and Trivy perform offline secret detection; Trivy is
pinned to Aqua's known-safe 0.69.2 release after the March 2026 supply-chain incident. Scanner network
access is always disabled. Raw scanner output and discovered secret values are withheld; the CLI emits
sanitized finding metadata and an output digest. Images may be downloaded by Docker on first approved
use, but a mutable tag is never accepted.

## Host-PC safety boundary

```powershell
vulgpt safety verify-host
vulgpt safety requirements
vulgpt isolation verify-runtime
```

VULGPT 0.1 keeps the host/lab-active execution circuit breaker disabled. The broker exposes no
launch/execute/run/dispatch method. A separate code-audit runner can invoke only Docker or Podman at
an exact hashed path and can run only reviewed digest-pinned manifests. Regression tests reject any
enabled lab-active adapter or process-launch API in the broker path.

VULGPT cannot launch Kali or third-party security binaries directly on the host PC. Approved code
audits run as a non-root container with a read-only root, no network, all capabilities dropped, no
host devices or Docker socket, and CPU/memory/PID/time/output limits. The CLI and Docker still consume
bounded host resources, and VULGPT cannot control a tool the user launches manually outside the app.

Any future external runner must be a separately verified rootless, ephemeral environment with a
read-only root filesystem, no Docker socket, no host devices or host networking, dropped capabilities,
resource limits, immutable image digest, dedicated workspace, target-only egress, and automatic
process-tree termination. Detection of WSL or Docker alone never satisfies these requirements.

## Release verification

VULGPT release artifacts are built as a wheel and sdist, then checked for matching package metadata,
safe archive paths, forbidden local-data paths, and wheel `RECORD` hashes before signing. Run:

```powershell
python -m build --wheel --sdist --outdir release-artifacts
python tool/release_verify.py --artifact-dir release-artifacts --write-manifest
```

See [the release checklist](docs/release/RELEASE_CHECKLIST.md) for protected-key signing and publishing
requirements.

## Configure OpenRouter

OpenRouter is the built-in model gateway. VULGPT uses its portable Chat Completions shape:

```text
POST {base_url}/chat/completions
```

The default profile is already bound to `https://openrouter.ai/api/v1` and uses `openrouter/auto`.
Store an OpenRouter key without placing it in shell history:

```powershell
vulgpt config set-key openrouter
vulgpt config show
```

Alternatively, set `OPENROUTER_API_KEY` in the environment. To pin an exact OpenRouter model instead
of using its automatic router, update the existing profile's model while keeping its immutable endpoint
and key source:

```powershell
vulgpt config provider openrouter `
  --base-url https://openrouter.ai/api/v1 `
  --model anthropic/claude-sonnet-4.5 `
  --api-key-env OPENROUTER_API_KEY
```

Keys are never accepted as command-line arguments. Environment variables take precedence. On
Windows, `config set-key` and the Web UI store keys encrypted for the current user with DPAPI. On
other platforms, set the profile's environment variable; persistent app-managed key storage fails
closed until an OS keyring adapter is installed.

A provider name cannot later be rebound to a different base URL or key environment variable. Create
a new provider profile name when either binding changes, then explicitly configure its key.

Local model servers require an explicit provider-level private-network opt-in, separate from target
scope:

```powershell
vulgpt config provider local `
  --base-url http://127.0.0.1:11434/v1 `
  --model my-local-model `
  --allow-private
```

Provider output can only influence a small, typed phase plan and a clearly labeled non-evidence
summary. Deterministic built-in validators alone can create `confirmed` findings.

## Reports and PoCs

Use `vulgpt history` and `vulgpt report <session-id>` to find prior output. Reports include:

- the authorization attestation and exact scope;
- stop reason and run budget;
- confirmed versus suspected status;
- validator and evidence IDs for every confirmed finding;
- redacted request/response metadata, artifact hashes, and evidence-integrity hashes;
- remediation and reproduction guidance; and
- coverage limitations.

When safe proof mode is authorized, confirmed supported findings receive a small Python file. It
embeds a data-only manifest, reuses VULGPT's guarded transport, stays on the recorded target, caps
requests and bytes, and requires an explicit runtime attestation:

```powershell
python path\to\poc_finding_....py --i-am-authorized
```

PoCs are never imported or executed during generation.

## Architecture

```mermaid
flowchart LR
  CLI["CLI"] --> Service["Shared command service"]
  TUI["Terminal workspace"] --> Service
  Web["Loopback Web UI"] --> Service
  Service --> Goal["Goal compiler"]
  Goal --> Policy["Authorization + scope policy"]
  Policy --> Broker["Registered tool broker"]
  Broker --> Transport["DNS-pinned safe HTTP transport"]
  Transport --> Ledger["Redacted evidence ledger"]
  Ledger --> Validators["Deterministic validators"]
  Validators --> Reports["Reports + bounded PoCs"]
  Model["Optional compatible model"] -. plan / summary only .-> Service
```

The public interface and supported workflows are documented in this README.

The goal loop stops when its deterministic completion checklist is satisfied, the operator cancels,
a hard budget is exhausted, an authorization or policy check fails, or no registered useful action
remains. “No confirmed findings observed” never becomes “the target is secure.”

## Data location

Set `VULGPT_HOME` to choose a data directory. Otherwise VULGPT uses `%LOCALAPPDATA%\VULGPT`
on Windows or `$XDG_DATA_HOME/vulgpt` / `~/.local/share/vulgpt` elsewhere.

The directory contains:

- `config.json` — provider profiles, network budgets, and saved scope attestations;
- `secrets.json` — Windows DPAPI ciphertext only, when used;
- `sessions.sqlite3` — redacted session history; and
- `reports/<session-id>/` — report and optional PoC files.

## Development

```powershell
python -m unittest discover -s tests -v
python -m compileall -q src
node --check src/vulgpt/web_assets/app.js
```

Optional development tooling is available with `pip install -e .[dev]`.

Implementation choices were checked against the current official
[Python packaging specification](https://packaging.python.org/en/latest/specifications/pyproject-toml/)
and the official [OpenRouter API reference](https://openrouter.ai/docs/api/reference/overview).
The default profile uses [OpenRouter Auto](https://openrouter.ai/docs/guides/routing/routers/auto-router),
which selects a model for each bounded planning or summary request. Pin an exact namespaced model in
the provider profile when stable model selection is preferred.

## Security

Read [SECURITY.md](SECURITY.md) before extending the tool registry or transport. In particular, do
not add a third-party scanner that performs its own DNS resolution until its egress can be constrained
by the same destination policy.
