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.3

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.3
File Size Uploaded Provenance Actions
tainted_cli-0.1.3.tar.gz 26.6 kB With provenance Details for tainted_cli-0.1.3.tar.gz

Built distribution (wheel)

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

Total release size: 47.2 kB

Release files / tainted_cli-0.1.3.tar.gz

Download URL tainted_cli-0.1.3.tar.gz
Size 26.6 kB
Tags Source
SHA-256 checksum
How to use checksums
eb382773e6397f688fb5ae90b2d69a0d60c0f5499b584cda078c0a79d8e81f34
BLAKE2b-256 checksum
How to use checksums
4ef2e7bc4b923126c73d8db256505d25fedc3191993b328f0987edbbeb2590af
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.3-py3-none-any.whl

Download URL tainted_cli-0.1.3-py3-none-any.whl
Size 20.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
22d25662265725a09c6b78f57a0fbd6d9d6d822e6a45d3ab6a69ec7a1610305b
BLAKE2b-256 checksum
How to use checksums
1beca744046bfe3900fb03f3f592ea7ca192c7ccb125d4173077cbd3d0f1fe4c
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.3

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.3.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