Skip to main content

refutescan

A two-LLM, refute-first agentic source-code vulnerability scanner.

Most LLM code scanners have the same problem: they hallucinate. Point a model at a repo and it will confidently report SQL injection in a parameterized query and SSRF behind an allowlist. The noise buries the real bugs.

refutescan splits the job across two models:

  1. Navigate (wide net). A fast tool-calling model explores the repo with read-only tools (list_dir / read_file / grep), traces untrusted input toward dangerous sinks, and records candidate findings. It's cheap and it over-reports on purpose.
  2. Refute (skeptic). A stronger model re-reads the actual code slice around each candidate from disk — ground truth, not the navigator's paraphrase — and is prompted to refute it. Sanitized? Parameterized? Gated by auth? Not reachable? It's culled, with the reason kept. Only what survives is reported.

You get the recall of an agentic scanner without the false-positive flood.

Every scan runs jailed in an ephemeral docker sandbox by default: git URLs are cloned inside a container (no host mounts), then audited in a second container with no network, read-only, no capabilities, non-root, and only the repo mounted. A hostile repo (malicious submodule, hook, symlink) touches neither your filesystem nor the network.

Install

pip install refutescan            # core kernel
pip install 'refutescan[openai]'  # + the OpenAI adapter for the CLI

For sandboxed scans (recommended), build the jail image once:

refutescan-build-sandbox

(Requires Docker. Without it, refutescan falls back to a guarded in-process scan.)

CLI

export OPENAI_API_KEY=sk-...
refutescan https://github.com/owner/repo
refutescan ./path/to/local/repo --judge-model gpt-4o --json

Exit code is non-zero when confirmed findings exist, so it drops straight into CI.

Library

from refutescan import scan, ScanConfig
from refutescan.adapters import openai_navigator_factory, openai_judge_factory

result = scan(
    "https://github.com/owner/repo",
    navigator_factory=openai_navigator_factory("gpt-4o-mini"),
    judge_factory=openai_judge_factory("gpt-4o"),
    config=ScanConfig(sandbox="docker"),       # auto | docker | inprocess
    progress=lambda phase: print(phase),
)

for f in result.findings:
    print(f["severity"], f["title"], f"{f['file']}:{f['line']}")
    print("  ", f["reasoning"])
    print("  fix:", f["recommendation"])

result.culled holds the refuted candidates with the reason each was rejected — useful for tuning and for trusting the tool.

Bring your own model

refutescan never imports a provider SDK in its core. Pass any LangChain-style chat model through two factories:

  • navigator_factory() -> chat_model — supports .bind_tools(...) + .invoke(...)
  • judge_factory() -> judge(prompt, schema) -> instance — one structured-output call

So a local model (vLLM/Ollama via the OpenAI shim, --base-url), Anthropic, Azure OpenAI, or a corporate gateway all work — wire the factory and go. See refutescan/providers.py.

What it is and isn't

  • Is: an agentic, read-only, false-positive-resistant first-pass auditor for the common web-app vuln classes (injection, authz/IDOR, SSRF, path traversal, unsafe deserialization, hardcoded secrets, weak crypto, XSS, auth flaws).
  • Isn't: a replacement for a full SAST suite, a proof of exploitability, or a patch generator. It finds and explains; a human confirms and fixes.

License

MIT.

Metadata

Release files for refutescan 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for refutescan 0.1.0
File Size Uploaded Provenance Actions
refutescan-0.1.0.tar.gz 29.7 kB With provenance Details for refutescan-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for refutescan 0.1.0
File Interpreter ABI Platform Actions
refutescan-0.1.0-py3-none-any.whl Python 3 none any Details for refutescan-0.1.0-py3-none-any.whl

Total release size: 62.1 kB

Release files / refutescan-0.1.0.tar.gz

Download URL refutescan-0.1.0.tar.gz
Size 29.7 kB
Tags Source
SHA-256 checksum
How to use checksums
255aa752429007c3f2704b77e4891a9dacf904f970a24cb70ae78838c82134c0
BLAKE2b-256 checksum
How to use checksums
f82f111671f5d92650751e68d5e93134d02116af1359da0e638924086af71b1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 26, 2026.

Transparency log

Release files / refutescan-0.1.0-py3-none-any.whl

Download URL refutescan-0.1.0-py3-none-any.whl
Size 32.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17de1e7504616656df3866e20adae3fdd7d4c0b1d8583a9d643f9164c46a6f24
BLAKE2b-256 checksum
How to use checksums
2d6d0192afff4bad893f063a610d1fcee48e7653631ecdda4ce2a6fb72df97ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 26, 2026.

Transparency log

Security for refutescan 0.1.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for refutescan-0.1.0.tar.gz

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 Jun 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page