slopaudit
Check AI-written code before you trust it. slopaudit is an open-source command-line tool for Python that finds the problems AI assistants and LLM-powered apps tend to introduce, and that general scanners were not built to look for.
- Is it safe? Does model output reach
eval, a shell or a SQL query? Does untrusted input end up in a system prompt? Does an agent tool hand the model a shell? - Is it real? Does that imported package exist, or is it invented (or one typo from a popular one)?
- Is it finished? Stubs, "rest of code here" comments, swallowed errors, truncated files.
- Is it what you asked for? Does the code meet each requirement in your spec, and did the change delete or weaken tests to get there?
It runs on your machine, never executes the code it scans, needs no account or API key, and has no telemetry.
Install
You need Python 3.10 or newer. Pick one:
pipx install slopaudit # recommended: an isolated command-line tool
uv tool install slopaudit # same idea, if you use uv
python3 -m pip install slopaudit # inside a virtual environment
Then check it works:
slopaudit --version
Just try it, without installing anything:
pipx run slopaudit scan . # or: uvx slopaudit scan .
Don't have pipx, upgrading, uninstalling, or installing from source
| I want to | Run |
|---|---|
| Get pipx on macOS | brew install pipx && pipx ensurepath |
| Get pipx elsewhere | python3 -m pip install --user pipx && python3 -m pipx ensurepath |
| Upgrade | pipx upgrade slopaudit, or python3 -m pip install --upgrade slopaudit |
| Uninstall | pipx uninstall slopaudit, or python3 -m pip uninstall slopaudit |
| Install a specific version | pipx install slopaudit==1.0.0 |
| Install the latest unreleased code | pipx install git+https://github.com/patsypppe/slopaudit |
| Hack on it | git clone https://github.com/patsypppe/slopaudit && cd slopaudit && make install (or open it in Codespaces) |
On macOS and most Linux systems the command is python3; python: command not found only means that.
On Windows use py instead of python3.
In CI, no install step is needed. Use the GitHub Action:
# .github/workflows/slopaudit.yml
name: slopaudit
on: [pull_request]
permissions: { contents: read, security-events: write }
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: patsypppe/slopaudit@v1.0.0
Before every commit, with pre-commit:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/patsypppe/slopaudit
rev: v1.0.0
hooks:
- id: slopaudit
See it work
$ slopaudit scan examples/vulnerable_agent
vulnerable_agent/app.py
16 HIGH LLM-08 Tool `run_command` passes a model-chosen argument to subprocess.run() (shell)
↳ line 14: tool argument `command` is chosen by the model
↳ line 16: passed to subprocess.run()
21 HIGH LLM-01 Untrusted input reaches the system prompt of client.messages.create()
↳ line 20: untrusted input request.args
↳ line 20: stored in `topic`
↳ line 21: placed in the system prompt of client.messages.create()
27 CRITICAL LLM-02 Model output reaches eval() without validation
↳ line 21: model output from client.messages.create()
↳ line 21: stored in `reply`
↳ line 27: passed to eval()
30 MEDIUM INC-02 `parse_invoice` has no implementation (pass)
34 CRITICAL SEC-01 Hardcoded credential assignment (q9X$…(21 chars))
1 files scanned: 2 critical, 2 high, 1 medium
Every flow finding shows the path the data took, so you can judge it in seconds. Each finding also has a
fix: line and a longer explanation: slopaudit explain LLM-02. No model is involved: slopaudit reads the
code's structure and follows values from where they come from to where they are used
(how it works).
Quickstart
slopaudit scan . # scan the current folder
slopaudit scan . --no-network # skip the PyPI package check
slopaudit scan --staged # only what you are about to commit
slopaudit scan . --format sarif -o out.sarif # for GitHub code scanning
slopaudit scan src --spec SPEC.md # check the code against a requirements file
slopaudit explain LLM-02 # why a rule exists, and how to fix it
From Python, for example to check an assistant's answer before saving it:
import slopaudit
blockers = [f for f in slopaudit.scan_source(answer) if f.severity >= slopaudit.Severity.HIGH]
New to it? The getting-started guide takes five minutes, and has a ten-line test file that shows every kind of finding. Adopting on a big codebase? Start with a baseline so only new problems fail.
What it checks
| Family | Rules | Catches |
|---|---|---|
| LLM-app security | LLM-01 to LLM-06, LLM-08, LLM-09, LLM-12 | Prompt-injection paths, model output reaching eval, shell, SQL, file paths and URLs, over-permissive agent tools, destructive tools with no confirmation, unbounded model calls |
| Secrets | SEC-01 | Hardcoded API keys, tokens and private keys (masked in all output) |
| Hallucinated packages | HAL-01 to HAL-04 | Imports that do not exist on PyPI, brand-new packages, typosquats, undeclared dependencies |
| Unfinished code | INC-01, INC-02, INC-04, INC-05, INC-06, INC-08 | Placeholder comments, stubs, swallowed exceptions, chat text pasted into files, many TODOs, truncated files |
| Intent and consistency | SPC-02, DRF-01 to DRF-03, REG-01, REG-02 | Unmet requirements, style drift from the rest of the repo, deleted or skipped tests |
The full list, with severity and fix advice for each rule, is the rules reference.
Beyond scanning, there are optional model-assisted commands: gen-tests
and fix (a dry run unless you pass --apply).
How well does it work?
Three checks, each reproducible from this repository. None is a guarantee; the caveats matter.
1. Labelled corpus (slopaudit bench, 34 files). Every rule scores 1.00 precision; recall is 0.91,
with two labelled misses (a value that crosses a function boundary, or goes through self). The corpus is
small and was used to tune the rules, so treat it as a regression gate.
2. Other scanners on that corpus (full report): files flagged at medium severity or higher, run as external programs.
| Tool | LLM-app security (15) | Secrets (1) | Incomplete code (4) | Hallucinated packages (1) | False alarms on 13 safe files |
|---|---|---|---|---|---|
| slopaudit | 12 | 1 | 3 | 1 | 0 |
| Bandit | 6 | 0 | 0 | 0 | 1 |
| Semgrep, public python rules | 8 | 0 | 2 | 0 | 2 |
| Semgrep, public ai rules | 12 | 0 | 0 | 0 | 6 |
| vibechck | 0 | 0 | 2 | 0 | 1 |
The corpus targets what slopaudit was built for, so it flatters slopaudit. Bandit and Semgrep are broader
tools not designed for these cases, and Semgrep's ai rules are SDK best-practice lints. Semgrep also
catches the two cross-function cases slopaudit misses, because it flags any dynamic eval.
3. Mature packages as a false-positive control (report): 1.5 million lines across twelve well-reviewed packages, including the OpenAI, Anthropic, LangChain and LiteLLM SDKs. 0 critical or high findings after tuning. The first run had 122 critical findings and about 900 medium ones; fixing them is in the changelog. About 25 medium and a few hundred low findings remain. This measures noise only: those packages are not AI-generated.
Honest limits
- A clean scan is not proof of safety. The flow rules follow values inside one function. They miss a
value returned from a helper and
eval-ed elsewhere, and values stored onself(how it works). - Without a model, the spec check compares names and words. It can show code exists, not that it behaves correctly. In the demo it reports a requirement as met while the code does the opposite.
- Experimental parts.
scan --spec --llm,gen-tests,fixand the Docker sandbox are tested against local stand-ins, not live services, so they are outside the 1.0 stability promise (what 1.0 promises). - Python only. JavaScript and TypeScript files are skipped, and the scan says so when it finds nothing to read.
- Linux CI only. Installing and running on macOS has been checked by hand; Windows is untested (#6).
Documentation
| Getting started | Install, first scan, reading output |
| Configuration | Every slopaudit.toml setting |
| CI integration | GitHub Action, pre-commit, GitLab |
| Suppressing findings | Comments, baselines, ignores |
| Beyond scanning | Spec checks, generated tests, drift, regression, repair |
| Python API | Use it from your own code or agent |
| Privacy and safety | What runs, what is sent, the sandbox |
| How it works | Pipeline and taint tracking |
| FAQ and troubleshooting | Common questions and fixes |
| All docs | The full index |
Contributing
Contributions are welcome: rules, false-positive reports, docs and tests. The most valuable thing you can do is report a false positive or a miss with the smallest code that shows it; every confirmed report becomes a regression test.
Looking for something to work on? The contributor roadmap lists every open issue by area and difficulty. Each one says why it matters, which files to change, and when it is done:
| Start here | |
|---|---|
| Good first issues | Small and well-defined: aliases, output formats, docs, test samples |
| Help wanted | New rules and integrations |
| Advanced | The flow tracker and bigger design questions; discuss before coding |
Comment on an issue before you start so nobody duplicates work. Setup takes one click in
Codespaces, or make install locally. Start with CONTRIBUTING.md and
writing a rule, and please follow the code of conduct.
Questions go in Discussions or issues; security problems in
SECURITY.md.
License
MIT. slopaudit is independent work: it takes no code, rules, messages or structure from other tools. The clean-room record explains how, and why other scanners are only ever run, never copied. Thanks to the authors of Bandit, Semgrep and vibechck for the prior art that made the comparison possible.
Metadata
Release files for slopaudit 1.0.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 | Provenance | Actions |
|---|---|---|---|---|
| slopaudit-1.0.0.tar.gz | 130.6 kB | With provenance | Details for slopaudit-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| slopaudit-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for slopaudit-1.0.0-py3-none-any.whl |
Total release size: 209.4 kB
Release files / slopaudit-1.0.0.tar.gz
| Download URL | slopaudit-1.0.0.tar.gz |
|---|---|
| Size | 130.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
65768310a26a5dc7f749d70a9d2f685ef3e1b3c679ba108ae12f27c70e3b42cf
|
|
BLAKE2b-256 checksum How to use checksums |
b7c0b069fb1874d3dbb34e2bd0b2be7ffce9439b2fa896220d1a448713c079cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 4, 2026.
Transparency logRelease files / slopaudit-1.0.0-py3-none-any.whl
| Download URL | slopaudit-1.0.0-py3-none-any.whl |
|---|---|
| Size | 78.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a124bd1f21873e2e755de07f78e2818e5d586d0ac1e44b6358ef3f0b502a2374
|
|
BLAKE2b-256 checksum How to use checksums |
eaeeb23b251dde1444330ed6eb9b624fb942124a7217c1e897fd78f30a83d082
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 4, 2026.
Transparency logSecurity for slopaudit 1.0.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
Both files in this release have been uploaded with provenance metadata.
Attestation for slopaudit-1.0.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 Nov 4, 2026.
Transparency logA 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.