VardrRunner
The local automation runner for the VardrSec product family.
VardrRunner runs your security tooling on your machine and syncs the results to a VardrSec backend (today: VardrMap) over HTTP. It is a thin, fast, dependency-light client: it polls the backend for queued scan jobs, claims them atomically, executes the tool locally, streams live progress back, uploads results, and heartbeats so the backend always knows which machines are online.
Why local? Recon and scanning tools belong on the operator's box — their bandwidth, their IP, their tool versions. The backend orchestrates and stores; the runner does the work. The two are fully decoupled and only ever exchange JSON.
Features
- Job queue worker — poll, atomically claim, execute, and report scan jobs
- Daemon mode —
daemon startruns a continuous background worker (poll every 5 s, heartbeat every 60 s) with detached mode, PID file, and graceful shutdown - Tool runners —
httpx,subfinder,nuclei,nmap,dnsx,naabu,katana(crawler),gau(archived URLs), each capturing output into an atomically unique run directory, every run bounded by a timeout that terminates the complete child-process tree - Pinned, verified tool installs —
tools install --alldownloads exact versions of httpx, subfinder, nuclei, dnsx, naabu, katana, gau, ffuf and dalfox into one folder,~/.vardrmap/tools, after checking each against a SHA-256 pinned in this package. The runner re-checks every managed binary before use and refuses to run one that has changed - Recon pipelines — chain tools in one command:
recon(subfinder → httpx → nuclei),deep(adds dnsx resolution),ports(subfinder → dnsx → naabu),quick - VardrGate authorization tests —
vardrgate_api_testjobs drive the localvardrgatebinary over a CLI/JSON contract and attach the sanitized result to the job. Identity credentials may reference a secret (value_env/value_keychain) that is resolved on the runner at execution time, so the secret never reaches the backend - Importers — pull existing
nuclei/httpxoutput files into the backend - Real heartbeat — reports hostname, version, OS, and per-tool availability so the backend's Bridge shows live machine status
- Crash-safe queue execution — journals each backend job in local SQLite before claim, reconciles interrupted work, hashes artifacts, and writes portable run manifests
- Sanitized audit evidence —
audit list,audit show, and atomic JSON exports without raw targets, credentials, request bodies, or headers - Small-team operations — stable runner UUID/name, rotating JSON logs, strict production preflight, and native systemd/launchd/Windows Scheduled Task management
- AI agent integration (MCP) —
vardrrunner mcpserves the engagement to an MCP client (Claude Code, Claude Desktop): the agent reads scope, findings, assets, recon and jobs, and queues scans or drafts findings with your approval. No tool can edit scope or delete, so target-controlled output can't steer it. Optional extra:pip install 'vardrrunner[mcp]' - Reviewed authorization-case authoring —
test-cases draftturns observed API operations or an OpenAPI file into VardrGate drafts in a review file that is never overwritten;test-cases save --reviewedstores them. Drafts never contain credentials and never guess who should have access - Shared API playbooks and execution evidence — MCP reads Map's original versioned API guides and filtered job/case/identity evidence. Six instruction-only prompts guide the work without fetching data during expansion; they do not save reviewed cases or commit client deliverables
- Gate result binding — refuse a case changed between polling and claim, and retain a hash of the unresolved case with the result artifact. Map uses it to distinguish bound assessments from legacy or unknown results; a completed command does not certify a secure API
- Guided verified setup — one idempotent
initcommand for interactive onboarding or non-interactive host provisioning, ending in a doctor acceptance gate - Bounded execution — schema/capability negotiation, target and artifact ceilings, free-disk reserve, and optional parallelism that never overlaps one engagement
- Live job events — emits
started → targets_resolved → running → uploaded → done/failedso the backend Terminal shows real-time logs - Preflight (
doctor) — one command validates the whole machine (creds, URL, perms, auth, daemon, disk, tools, pipelines) and exits non-zero on actionable failures, for scripting unattended/VPS provisioning - Safe by default — missing tools fail the job loudly, targets are normalized before use, risky target classes can be denied locally, and the API key is stored locally with restrictive permissions
Requirements
- Python 3.10+
- The external tools you intend to run.
vardrrunner tools install --allinstalls verified builds ofhttpx,subfinder,nuclei,dnsx,naabu,katana,gau,ffufanddalfox;nmapcomes from your OS installer or package manager, andvardrgate(forvardrgate_api_testjobs) from its repository. Tools already on yourPATHstill work and are reported as unverified - For ffuf, supply a named wordlist in
~/.vardrmap/wordlists(for examplecommon.txtfor--wordlist common); none ship with the runner - A VardrSec backend URL and an API key (
vmap_…for VardrMap) - VardrMap ≥ v0.22.0 as the backend — the runner calls
/engagements/*(see CHANGELOG v0.27.0)
That is the baseline API requirement, not support for every newer feature. Shared
playbooks, evidence reads and bound assessments require the matching Map endpoints
and migration; deploy that backend first. These features ship in Runner 0.47.0.
Identity preflight additionally requires VardrGate v0.1.0 or newer.
Install its verified binary on your PATH before enabling preflight cases.
See API assessment guidance.
Install
pipx install vardrrunner
That's it — pipx puts vardrrunner on your PATH in its own
isolated environment, which is what you want for a CLI. pip install vardrrunner also
works if you're already inside a virtualenv you manage yourself.
No Python on the machine?
Common on a fresh VPS or a clean Windows box. uv is a single static binary that downloads its own CPython, so it needs nothing preinstalled:
# install uv itself
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Windows
uv tool install vardrrunner
uvx vardrrunner <command> runs it without installing at all — handy for a one-shot job on
a box you don't intend to keep.
Other options
From a GitHub Release — every tag ships a wheel, an sdist, a CycloneDX SBOM, and a build-provenance attestation. Use this when you need to verify the artifact before installing it:
pipx install ./vardrrunner-<version>-py3-none-any.whl
From source, for development:
git clone https://github.com/VardrSec/VardrRunner.git
cd VardrRunner
python -m venv venv
.\venv\Scripts\Activate.ps1 # Windows (macOS/Linux: source venv/bin/activate)
pip install -e ".[dev]"
Note that a clone alone does not give you the vardrrunner command — it has to be
installed into an environment on your PATH, which is what the pip install -e step
above does. Inside a venv you'll need it activated; pipx/uv avoid that entirely.
Homebrew / Scoop formulae are planned once there's demand.
Quick start
vardrrunner init # guided auth, runner name, optional service, and health gate
vardrrunner tools install --all # pinned, verified tools into ~/.vardrmap/tools
For an unattended host, use vardrrunner init --production --install-service. Existing
individual login, identity, doctor, and service commands remain available when you
want to control each step separately.
One-shot usage
vardrrunner engagements # list your engagements
vardrrunner scope <engagement-id> # show in/out-of-scope items
vardrrunner jobs list # show the backend queue
vardrrunner jobs run # claim + execute all pending jobs once
vardrrunner audit list # inspect durable local job evidence
vardrrunner identity set-name chicago-runner-1 # durable human label
vardrrunner update check # check; never auto-install
vardrrunner run subfinder --engagement <engagement-id> # run a single tool and upload results
vardrrunner import nuclei --engagement <engagement-id> -f out.jsonl
--engagement takes the engagement UUID; --program and -p are accepted as aliases.
See docs/cli.md for the full command reference.
Configuration
Desktop / dev: vardrrunner login stores your API key in the OS keychain (macOS
Keychain, Windows Credential Locker, Linux Secret Service), leaving only the backend URL in
~/.vardrmap/config.json. Where no keyring backend is available, login fails closed unless
you explicitly pass --allow-plaintext-credentials; on headless boxes and containers,
prefer VARDRMAP_API_KEY below. vardrrunner credentials reports which source is actually
in use, and vardrrunner logout removes the key from both.
CI / servers / containers: set credentials via environment variables (no keychain
needed). The key resolves in this order — VARDRMAP_API_KEY env → OS keychain → config
file:
| Variable | Purpose |
|---|---|
VARDRMAP_URL |
Backend base URL (must be https://, except localhost) |
VARDRMAP_API_KEY |
Your vmap_ API key |
VARDRRUNNER_TOOL_TIMEOUT |
Per-tool run timeout in seconds (default 1800); a hung tool is killed and the job marked failed |
VARDRRUNNER_ALLOW_INSECURE |
Set to 1 to permit a plain-HTTP backend URL (not recommended) |
VARDRUNNER_NAME |
Optional display/heartbeat label; does not replace the stable UUID |
VARDRUNNER_MAX_TARGETS |
Queue target ceiling (default 500; range 1–100000) |
VARDRUNNER_MAX_ARTIFACT_MB |
Artifact ceiling before upload (default 100 MiB; range 1–10240) |
VARDRUNNER_MAX_CONCURRENT_JOBS |
Parallel engagement groups (default 1; range 1–8) |
VARDRUNNER_MIN_FREE_DISK_MB |
Required free-space reserve (default 512 MiB; 0 disables) |
VARDRRUNNER_DENY_TARGETS |
Comma-separated target classes, literal hosts, or CIDRs to block locally; nothing is denied by default |
VARDRRUNNER_ALLOW_DENIED_TARGETS |
Set to 1 for an explicit, audited override of local deny rules |
The runner refuses to send your API key over plain HTTP to a non-local host, so a mistyped
http:// URL can't leak your key.
An installed service does not inherit arbitrary variables from the shell that installed
it. If credentials exist only in environment variables, Linux service setup requires an
operator-owned --env-file; macOS/Windows should use keychain/config credentials or an
existing supervisor. VardrRunner never creates, reads, or prints the env file's secrets.
Documentation
- docs/architecture.md — how the runner is structured and how it talks to the backend
- docs/development.md — local setup, testing, and contribution workflow
- docs/cli.md — complete command and flag reference
- docs/adr/ — Architecture Decision Records
- SECURITY.md — private vulnerability reporting and support policy
- CHANGELOG.md — version history
Development & testing
pip install -e ".[dev]" # editable install + dev tools (pytest, ruff, mypy)
ruff check vardrrunner tests # lint
ruff format --check vardrrunner tests # formatting
mypy vardrrunner # type check
pytest tests # scanner smoke tests skip unless explicitly enabled
CI runs ruff (lint + format), mypy, and a bandit security scan, then the test suite at a
95% coverage floor on Python 3.10–3.14 (Linux) plus Python 3.14 on Windows and macOS,
and a pip-audit dependency audit — on every push and PR to main.
Contributions follow the Engineering Charter in CLAUDE.md: clean code,
tests with behavior changes, documentation updated, and the relevant checks green.
Docs-only changes require a diff and Markdown-link check.
License
MIT © 2026 Jorge Aquino.
Part of the VardrSec product family — VardrMap · VardrRunner · VardrGate.
Metadata
Release files for vardrrunner 0.47.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vardrrunner-0.47.0.tar.gz | 252.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vardrrunner-0.47.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 409.9 kB
Release files / vardrrunner-0.47.0.tar.gz
| Download URL | vardrrunner-0.47.0.tar.gz |
|---|---|
| Size | 252.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
51439a56c31078a010054c5309eca3f86e54cd05641ca6ebb09cd8c3610366ff
|
|
BLAKE2b-256 checksum How to use checksums |
14df2977529d052a8593d5f5684b96df3f7f6cee64c5fdc21282d6b22a2c119c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / vardrrunner-0.47.0-py3-none-any.whl
| Download URL | vardrrunner-0.47.0-py3-none-any.whl |
|---|---|
| Size | 158.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9422f3f19f4c4e84c95c0d4d75cefe0c4c117f85c5675317ee7df4cc9ba58f8e
|
|
BLAKE2b-256 checksum How to use checksums |
8f318044d31a8541a1e1d77c18f1c47df685734cb135076eb2c1c85e5bec05e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log