Skip to main content

Tainted CLI

The local developer loop. One surface, three ways to run analyze (static, fast, no target or credentials needed):

  • on demand — tainted analyze <repo>
  • on save — tainted watch <repo> (re-runs analyze on every file change)
  • on commit — the pre-commit hook (tainted-gate), which blocks the commit on a high-severity possible hole

It also runs the interactive fix and can prove against a running target.

Install

pip install tainted-cli            # the engine comes with it, pinned to this version
export GEMINI_API_KEY=...          # optional: turns on the LLM "meaning" register

prove additionally needs the browser the engine's dynamic extra carries. A package cannot request an extra of its own dependency, so that is a second command rather than a flag:

pip install "tainted[dynamic]" && playwright install chromium

From a checkout instead — the core is a sibling directory, not a release:

pip install -e .                 # the core engine (repo root)
pip install -e surfaces/cli      # this surface

Use

tainted analyze ./my-app                         # ranked possible holes in the terminal
tainted analyze ./my-app --only bola,rls --json  # narrow the checks + machine-readable output
tainted watch ./my-app                           # re-analyze on every save
tainted fix ./my-app --finding-id 1db5cbc5 --apply  # write the fix to disk
tainted prove ./my-app \                          # drive a running target
  --url http://localhost:54321 --anon-key "$ANON" \
  --login-a a@x.com:pw --login-b b@x.com:pw --seed invoices:<id>

tainted tutorial walks through all of this from inside the terminal: run it with no argument to list the lessons, or tainted tutorial proving-it to read one.

tainted tutorial                 # first-scan, reading-a-report, on-save, on-commit, proving-it, fixing-it
tainted tutorial first-scan      # one lesson, with the commands to run and what to expect back

prove runs real attacks inside a Docker sandbox, and is refused outright for anything but a localhost or 127.0.0.1 target: the CLI proves against an app running on this machine, so a remote target is not something a token can unlock — point it at a local app, or use the website surface, which has its own ownership check for a repository picked from GitHub.

Which hole is fix fixing?

analyze prints a # and an ID for every row, and fix takes either:

tainted fix ./my-app --finding-id 1db5cbc5350811b5   # the hole itself; survives a re-run
tainted fix ./my-app --index 0                        # the row number from that one run

Prefer the id. # is a position in the report that run drew, and both the code and the model's ranking move underneath it.

Pre-commit

The hook manifest is .pre-commit-hooks.yaml at the repository root — pre-commit reads it from there and nowhere else — and it is a language: system hook, so it runs the tainted-gate you installed above rather than building an environment of its own. (It cannot build one: a language: python hook installs this repo's root package, which is the engine, and the engine has no tainted-gate script and none of this surface's dependencies.)

So: install Tainted, then add this to the project's .pre-commit-config.yaml:

-   repo: https://github.com/OWNER/tainted
    rev: v0.1.1
    hooks:
      - id: tainted

Or skip the clone entirely and run the command already on your PATH:

-   repo: local
    hooks:
      - id: tainted
        name: Tainted security gate
        entry: tainted-gate
        language: system
        pass_filenames: false
        always_run: true

tainted analyze exits 0 or 1. prove exits 1 when a high-severity finding is proven, and 2 when the ownership check fails — both usable directly in scripts.

Metadata

Release files for tainted-cli 0.1.2

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

Source distribution (sdist)

Source distribution for tainted-cli 0.1.2
File Size Uploaded Provenance Actions
tainted_cli-0.1.2.tar.gz 25.6 kB With provenance Details for tainted_cli-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tainted-cli 0.1.2
File Interpreter ABI Platform Actions
tainted_cli-0.1.2-py3-none-any.whl Python 3 none any Details for tainted_cli-0.1.2-py3-none-any.whl

Total release size: 45.6 kB

Release files / tainted_cli-0.1.2.tar.gz

Download URL tainted_cli-0.1.2.tar.gz
Size 25.6 kB
Tags Source
SHA-256 checksum
How to use checksums
04f316bb5a2c0334a8d6ca65e13c80e5bebd1a9f65d0c97fa77165af01d99732
BLAKE2b-256 checksum
How to use checksums
04c3db4622cbbdbd5dd2437f2c36d2601cab9855f9670a5b18c3fe3d609529e9
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 Sep 21, 2026.

Transparency log

Release files / tainted_cli-0.1.2-py3-none-any.whl

Download URL tainted_cli-0.1.2-py3-none-any.whl
Size 20.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6fbd352527fcf8971477bc447ad622b380d2065911f12e1ee90fbab6bcf564b6
BLAKE2b-256 checksum
How to use checksums
eaf852b3cfcf531b0c137f5b5865851ba2fbc5a0914a801dc6a0dcd43f74b045
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 Sep 21, 2026.

Transparency log

Security for tainted-cli 0.1.2

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 tainted_cli-0.1.2.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 Sep 21, 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.

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