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.cominto 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.
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.
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.
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.
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:
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
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.
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
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
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:
vulgpt
Or request a one-shot suggestion:
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:
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:
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:
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
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:
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
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:
python -m build --wheel --sdist --outdir release-artifacts
python tool/release_verify.py --artifact-dir release-artifacts --write-manifest
See the release checklist for protected-key signing and publishing requirements.
Configure OpenRouter
OpenRouter is the built-in model gateway. VULGPT uses its portable Chat Completions shape:
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:
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:
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:
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:
python path\to\poc_finding_....py --i-am-authorized
PoCs are never imported or executed during generation.
Architecture
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; andreports/<session-id>/— report and optional PoC files.
Development
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 and the official OpenRouter API reference. The default profile uses OpenRouter Auto, 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 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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vulgpt-0.1.0.tar.gz.
File metadata
- Download URL: vulgpt-0.1.0.tar.gz
- Upload date:
- Size: 216.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f59d0d66765589eca04b7bf106c52f3814061b9f03856ed2687bb0d17f58c76f
|
|
| MD5 |
a73773e49906259737affe15f9f9570c
|
|
| BLAKE2b-256 |
d11718cb1bfd831b0147b34a9cb6c20ff6cf0a99d16cc3a3d0fec844d5d3c16a
|
Provenance
The following attestation bundles were made for vulgpt-0.1.0.tar.gz:
Publisher:
release.yml on painjanevivek/VulGPT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vulgpt-0.1.0.tar.gz -
Subject digest:
f59d0d66765589eca04b7bf106c52f3814061b9f03856ed2687bb0d17f58c76f - Sigstore transparency entry: 2231473240
- Sigstore integration time:
-
Permalink:
painjanevivek/VulGPT@c2059c02673330600ca08b862861c6b84c30ecae -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/painjanevivek
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c2059c02673330600ca08b862861c6b84c30ecae -
Trigger Event:
release
-
Statement type:
File details
Details for the file vulgpt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: vulgpt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 198.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c46b1f0135c861427433dc2d330e79eb1e95e86f30ea246c8341b382a02316b
|
|
| MD5 |
1775c6852e44386afaa7f6b11f33ee7b
|
|
| BLAKE2b-256 |
0f07ba0381f8d6d2f3b5de6bd891f43b13299a4b442424a00e08ac92af0ceef2
|
Provenance
The following attestation bundles were made for vulgpt-0.1.0-py3-none-any.whl:
Publisher:
release.yml on painjanevivek/VulGPT
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vulgpt-0.1.0-py3-none-any.whl -
Subject digest:
6c46b1f0135c861427433dc2d330e79eb1e95e86f30ea246c8341b382a02316b - Sigstore transparency entry: 2231473839
- Sigstore integration time:
-
Permalink:
painjanevivek/VulGPT@c2059c02673330600ca08b862861c6b84c30ecae -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/painjanevivek
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c2059c02673330600ca08b862861c6b84c30ecae -
Trigger Event:
release
-
Statement type: