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 demandtainted analyze <repo>
  • on savetainted 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 is gated by an ownership check: a localhost target needs nothing; a remote target needs --ownership-token (checked via a DNS TXT record or a /.well-known/tainted-verify file).

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

Release files for tainted-cli 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 tainted-cli 0.1.0
File Size Uploaded
tainted_cli-0.1.0.tar.gz 25.1 kB Details

Built distribution (wheel)

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

Total release size: 44.8 kB

Release files / tainted_cli-0.1.0.tar.gz

Download URL tainted_cli-0.1.0.tar.gz
Size 25.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9ce755bb9773bb73960ee4b988955a0908b8934d4093a58675b1752d7e0fce54
BLAKE2b-256 checksum
How to use checksums
fa277e2453d192f09d8d692f8182f908bd761e801d29e5e1e8037f9027029e8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

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

Download URL tainted_cli-0.1.0-py3-none-any.whl
Size 19.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff837cd8d31b7b1b6fbe4aed398f21d3a3f296e195d1cfc3fdae1f31554acaf2
BLAKE2b-256 checksum
How to use checksums
10536ce624954d6e9b6408846b95c6b3ff1d6a8fba6b2a9d33342c0a3ccf0a4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

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