Skip to main content
valvur

Offline security scanning for AI-generated code.
Seven open-source scanners and AI-specific checks, in one command and one ranked report.

PyPI Python 3.11+ CI OpenSSF Scorecard Licence: Apache-2.0
Scorecard's Code-Review, Branch-Protection and Contributors checks need a second maintainer; valvur has one (MAINTAINERS.md).

Status: 1.5.1, the version this tree declares; the PyPI badge above shows what pip install valvur serves, and the CHANGELOG what each version changed.

In Claude Code: /plugin marketplace add MaverickHQ/valvur, then /plugin install valvur@valvur, and ask it to scan the project.
From a terminal, with Docker or Podman running: uvx valvur scan.

valvur scans a project whose lockfile pins a package published as malicious, and lists the findings

Why valvur

  • Seven scanners, one report. Gitleaks, Trivy, OSV-Scanner, Opengrep, Checkov, zizmor and Syft, pinned, installed and run for you in one container, beside valvur's own checks for AI-written code. A vulnerability two of them report is one finding, not two, and everything is ranked together.
  • Nothing leaves your machine, provably. No account, no API key, no telemetry. The Scanners run in one container with no network interface, and your source is copied in, never mounted. Every fetch of public data is recorded in run.json, beside what left the machine: nothing. One command checks it.
  • Built for how AI-generated code breaks. Models invent package names that attackers then register; agent instruction files carry injected directives and hidden Unicode; agent settings leak tokens. valvur checks for each, offline, beside the classic secrets, vulnerable dependencies and misconfigurations.
  • Ten findings that matter, not four hundred. Findings are ranked by whether attackers are exploiting them, from CISA KEV and FIRST EPSS rather than CVSS alone, grouped by rule and directory, with development-only dependencies demoted.
  • You stay in charge. valvur proposes fixes and never applies them. An agent told to reach zero findings can delete code or write suppressions instead, and the finding disappeared is not the vulnerability is fixed.

What it finds

area what valvur reports found by
Hallucinated packages dependencies that do not exist, or sit one edit from a popular name, checked offline against every name on PyPI, npm, RubyGems, Packagist and crates.io valvur's dependency-reality Check
Malicious packages dependencies published as malicious, from OpenSSF's malicious-packages OSV-Scanner, and the same Check
Agent configuration injected directives, hidden Unicode, unpinned MCP servers, blanket approval, hooks that run a command, settings that would leak valvur's ai-artifact Check
Vulnerable dependencies known CVEs from lockfiles, ranked by exploitation, with the direct package to bump Trivy, OSV-Scanner
Secrets credentials in the files and in git history Gitleaks
Code injection, path traversal, SSRF, open redirects, XXE and insecure cookies, and model output reaching eval, a shell, a query or the DOM Opengrep, with valvur's rules
Infrastructure Terraform, CloudFormation, Kubernetes and Dockerfile misconfiguration Checkov
CI workflows unpinned actions, write permissions, template injection zizmor
Licences and SBOM a missing or contradictory project licence; a CycloneDX SBOM when asked for valvur's licence-file Check, Syft

What it checks, rule by rule, and what it cannot see: how valvur works.

How it works

  1. A small host shim decides what a scan reads (the files git would publish, plus .env* files and agent configuration), fetches the public data it needs, and records each fetch.
  2. One Scan Container, with no network interface, runs every Scanner over a copy of those files fed on stdin. Nothing in it can change your source.
  3. One findings model normalises and ranks what they report, and the shim writes the Results Folder into your project:
.security-scan/          ← ignores itself in git, so it is never committed
├── SUMMARY.md           ← start here: the verdict, anything that failed, the top groups
├── REMEDIATION.md       ← a ranked proposal: you choose what to apply
├── findings.json        ← every finding, normalised, secrets redacted
├── results.sarif        ← SARIF 2.1.0, for code scanning and IDEs
└── run.json             ← what ran, what was fetched, and what left the machine: nothing

A scan ends findings, clean or inconclusive. It never says clean when stale data, an uninspected ecosystem or a Scanner that did not finish cannot support it, and it says why.

Measured, not claimed

How much of what valvur claims it finds is measured as the Score: eight tracks scored by the OWASP Benchmark's formula, with a ratchet that no change may fall more than two points under. It is 73.4 out of 100, the same on Linux and on macOS.

track what it holds score
sast-python the OWASP Benchmark for Python 40.9
sast-js valvur's JavaScript twins: ten weaknesses, vulnerable and fixed 55.0
secrets ten formats, in files and in history 100.0
dependencies lockfiles pinned to vulnerable versions; known-malicious packages 100.0
package-reality nonexistent, near-miss and malicious names 100.0
agent-configuration planted directives and hidden Unicode, against real files 94.3
infrastructure Terraform, Kubernetes, Dockerfile and Actions faults 95.0
real-code-precision 48 maintained projects, every finding labelled by hand 2.3

Track 8 is precision on maintained code, where almost nothing is a vulnerability: 3 of its 171 findings are real. Each rule's precision is in docs/RULES.md, and the method, the gates and what valvur does not claim are in docs/EVALUATING.md. Read that one sceptically.

Use it

In an AI coding agent

The Claude Code plugin brings the MCP server, a skill that runs the workflow, and a hook that asks you before the agent installs a package valvur flags. Kiro takes it as a power. Any MCP client runs the server with uvx --from valvur valvur-mcp. The agents' guide has the configuration for eleven clients, the seven tools, and the permissions a don't ask mode needs.

From the command line

The Scanners run in a container, so the machine needs Docker or Podman; valvur doctor says what is missing.

pip install valvur          # or: uv tool install valvur
valvur scan                 # offline by default; --profile full adds the registries' answers
valvur check npm left-pad   # before an install: real, a near-miss, or malicious?
valvur gate . --fail-on high --no-inconclusive

The command-line guide has every command, what a first scan fetches, the Results Folder, and the settings files.

In CI

- uses: MaverickHQ/valvur-action@16b19e275f843419887873ed536a71f872607e24 # v0.2
  with: { fail-on: high, no-inconclusive: "true" }

The action scans, uploads results.sarif to code scanning and gates the job. The CI guide covers the gate, the image as a step of its own, and GitLab.

Built on open-source scanners

valvur builds no detection engine. Seven open-source Scanners do that and deserve the credit; valvur adds one File Set, one findings model, exploit-aware ranking, and three Checks of its own. All of them run in one container, fed a copy of the files. run.json records the version of each that ran, and raw/ keeps what each said.

Scanner Licence Reads Runs
Gitleaks MIT Secrets in the files scanned and in git history, the newest 5,000 commits or 200 MB always
Trivy Apache-2.0 Known vulnerabilities in dependencies, from lockfiles, against its database in the host cache always
OSV-Scanner Apache-2.0 Lockfiles against OSV's data, which carries the known-malicious MAL- packages nothing else here reports. On offline, OSV's offline database for each ecosystem present, fetched into the host cache; on full, OSV.dev's API, which receives lockfile names and versions always
Opengrep LGPL-2.1 Static analysis: pinning rules, a sink inventory at INFO, taint rules from a model call to a sink, and taint rules from request data always
Checkov Apache-2.0 Infrastructure misconfiguration: Terraform, CloudFormation, Kubernetes, Dockerfiles, other CI systems where there is infrastructure other than GitHub workflows
zizmor MIT GitHub Actions workflows: unpinned actions, write permissions, template injection where there are workflows
Syft Apache-2.0 The SBOM, and the dependency licences read from it when asked for: scan --sbom, or sbom = true under [scan]
Check Reads
ai-artifact Agent configuration: injected directives, hidden Unicode, unpinned MCP servers, blanket approval, hooks that run a command, and local settings that would leak
dependency-reality Every declared dependency against the Name Index: does it exist, and on full, how old and how adopted is it. Every declared or locked one against the known-malicious list, built daily from OpenSSF's malicious-packages
licence-file The project's own licence: missing, or contradicting what the manifest declares

Exploit intelligence comes from CISA KEV and FIRST EPSS: public primary sources, auditable and mirrorable. No proprietary database, and nothing to lock you in.

What it does not do

  • No reachability analysis. We do not prove a vulnerable function is called.
  • No autonomous fixing. You choose the fixes.
  • No penetration testing. No DAST, no exploitation, no scanning of deployed systems.
  • No code-quality analysis. Security only.
  • We will not out-detect commercial SAST. We win on trust, breadth in one artifact, and prioritisation, not on engine depth.

Platforms

platform support
Linux, Docker and Podman Supported. Every commit runs the e2e suite against Docker and Podman on amd64, and against Docker on arm64, and a scan with the published image on both; the acceptance set runs nightly on GitHub's Linux runner
macOS, Docker Desktop or Podman Supported, and tested by hand on an Apple-silicon Mac through Docker Desktop at every phase's exit: the acceptance set and the e2e suite against the image built from that commit (docs/acceptance/). Not on every commit: a container runtime needs nested virtualisation, which GitHub's macOS runners do not offer
linux/amd64 and linux/arm64 Both: one image index, signed, with an SBOM for each
Windows via WSL2 Supported: inside WSL valvur is running on Linux
Native Windows Not claimed. Untested, and valvur says so at startup
SELinux-enforcing hosts (RHEL, Fedora) Supported. Your source is copied into the scan and never mounted, so its SELinux label does not matter; valvur labels its own cache mounts

Air-gapped? The database, the Name Index and its malicious list, KEV, EPSS and OSV's databases all live outside the image, and each has a mirror setting. See docs/AIR-GAPPED.md.

Privacy

valvur collects nothing: no account, no API key, no telemetry, and no part of it reports on you or your code. The results stay in .security-scan/, which ignores itself in git. What the host fetches is public data, each fetch recorded in run.json. python3 scripts/verify-offline.py checks it, and on Linux unshare -rn valvur scan proves it (how).

Documentation

guide for
How it works the offline proof, every check, and the ranking
AI coding agents the plugin, the power, eleven MCP clients and the seven tools
Command line the commands, the Results Folder and the settings
CI the gate, the GitHub Action and the image in a pipeline
Evaluating valvur the audit: the Score, the gates and the limits
Rules each static-analysis rule's measured precision
Air-gapped use mirrors for every data source
Every document the protocol, the decisions, releasing and the records

Community and support

  • Questions and ideas: Discussions.
  • Bugs, and findings valvur missed: https://github.com/MaverickHQ/valvur/issues, with the tarball valvur doctor --bundle writes: versions and the last run.json, never your source, raw output or findings.
  • Security: a suspected vulnerability in valvur, a false clean included, goes privately by SECURITY.md.
  • Contributing: CONTRIBUTING.md has the setup and the short list of what is refused on principle. MAINTAINERS.md says who maintains valvur, one person today, and what you can rely on. There is no paid tier and no support contract.

Licence

Apache-2.0, see LICENSE; chosen over MIT for the explicit patent grant. Bundled Scanners keep their own licences, listed above and in NOTICE. valvur adds no GPL or AGPL component; the Alpine base carries GPL userland as every Linux container does, and the published SBOM discloses all of it (ADR-0005).

Metadata

Release files for valvur 1.5.1

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

Source distribution (sdist)

Source distribution for valvur 1.5.1
File Size Uploaded
valvur-1.5.1.tar.gz 1.6 MB Details

Built distribution (wheel)

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

Total release size: 2.0 MB

Release files / valvur-1.5.1.tar.gz

Download URL valvur-1.5.1.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
363c61c7883d9a24ceb435c24dbe2398e1bd019f7a0c9ef49b0701c8fc1d840b
BLAKE2b-256 checksum
How to use checksums
127fd6322c34bcfadf274cef6dea4a48475f86cf6633a6908af6e702e122fc12
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 9, 2026.

Transparency log

Release files / valvur-1.5.1-py3-none-any.whl

Download URL valvur-1.5.1-py3-none-any.whl
Size 430.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
494e9353f41c662a4a825533c99d06b357b2a7a407db029184ac2ae7cb05f26a
BLAKE2b-256 checksum
How to use checksums
073ff59908eeee56db11147bf0191874533f1c42dbdacd9e6987ab7f80e50753
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 9, 2026.

Transparency log

Release history Release notifications | RSS feed

1.5.3

2 release files

1.5.2

2 release files

This release

1.5.1 This release

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

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