Metadata-Version: 2.4
Name: vulgpt
Version: 0.1.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.

## What the MVP does

- Compiles requests such as `test https://app.example.com` into a deterministic goal.
- Runs recon-only, scan-only, full, 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

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.

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

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.
