Skip to main content

A pip-audit like tool for auditing Python packages in requirements files.

Project description

uv-audit

pip-audit like vulnerability scanning but fast

My example requirements.txt:

# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml -o runtime/requirements.txt
annotated-types==0.7.0
    # via pydantic
anyio==4.9.0
    # via starlette
cachetools==5.5.2
    # via google-auth
certifi==2025.4.26
    # via requests
charset-normalizer==3.4.2
    # via requests
click==8.2.1
    # via
    #   flask
    #   functions-framework
cloudevents==1.12.0
    # via functions-framework
deprecation==2.1.0
    # via cloudevents
fastapi==0.115.12
    # via availability-profile (pyproject.toml)
flask==2.2.5
    # via
    #   functions-framework
    #   vellox
functions-framework==3.8.3
    # via availability-profile (pyproject.toml)
google-api-core==2.25.0
    # via
    #   google-cloud-core
    #   google-cloud-firestore
google-auth==2.40.3
    # via
    #   google-api-core
    #   google-cloud-core
    #   google-cloud-firestore
google-cloud-core==2.4.3
    # via google-cloud-firestore
google-cloud-firestore==2.21.0
    # via availability-profile (pyproject.toml)
googleapis-common-protos==1.70.0
    # via
    #   google-api-core
    #   grpcio-status
grpcio==1.72.1
    # via
    #   google-api-core
    #   grpcio-status
grpcio-status==1.72.1
    # via google-api-core
gunicorn==23.0.0
    # via functions-framework
idna==3.10
    # via
    #   anyio
    #   requests
itsdangerous==2.2.0
    # via flask
jinja2==3.1.6
    # via flask
markupsafe==3.0.2
    # via
    #   jinja2
    #   werkzeug
packaging==25.0
    # via
    #   deprecation
    #   gunicorn
proto-plus==1.26.1
    # via
    #   google-api-core
    #   google-cloud-firestore
protobuf==6.31.1
    # via
    #   google-api-core
    #   google-cloud-firestore
    #   googleapis-common-protos
    #   grpcio-status
    #   proto-plus
pyasn1==0.6.1
    # via
    #   pyasn1-modules
    #   rsa
pyasn1-modules==0.4.2
    # via google-auth
pydantic==2.11.5
    # via fastapi
pydantic-core==2.33.2
    # via pydantic
requests==2.32.3
    # via google-api-core
rsa==4.9.1
    # via google-auth
sniffio==1.3.1
    # via anyio
starlette==0.46.2
    # via fastapi
typing-extensions==4.14.0
    # via
    #   fastapi
    #   pydantic
    #   pydantic-core
    #   typing-inspection
    #   vellox
typing-inspection==0.4.1
    # via pydantic
urllib3==2.4.0
    # via requests
vellox==0.1.3
    # via availability-profile (pyproject.toml)
watchdog==6.0.0
    # via functions-framework
werkzeug==3.1.3
    # via
    #   flask
    #   functions-framework

scanned once with pip-audit pip-audit

and once with uv-audit uv-audit

uv-audit needs 0.852s and pip-audit needs 4.617s total to scan the same requirements.txt file. I expect the time to diverge even more with larger requirements files or when using multiple requirements files.

Usage

Install:

uv pip install .

Audit a requirements file:

uv-audit -r requirements.txt

Audit a pyproject.toml (main dependencies only):

uv-audit -r pyproject.toml

Include specific dependency groups and/or extras:

uv-audit -r pyproject.toml --group dev --extra cli

Include everything (all groups + all extras):

uv-audit -r pyproject.toml --all

Shortcut for a project directory (uses its pyproject.toml):

uv-audit ./my-project --all-groups

Mix files in one run:

uv-audit -r requirements.txt -r ./svc/pyproject.toml --all-groups

Machine-readable output

Use --json to emit results as JSON on stdout (errors go to stderr). The payload lists every scanned input — including clean ones — along with the resolved groups/extras selection.

uv-audit -r pyproject.toml --all --json

Example output:

{
  "vulnerable": true,
  "inputs": [
    {
      "source": "/abs/path/to/pyproject.toml",
      "kind": "pyproject",
      "groups": ["dev"],
      "extras": ["cli"],
      "vulnerabilities": [
        {
          "package": "flask",
          "version": "1.1.2",
          "id": "GHSA-XYZ",
          "fix_versions": ["2.0.0"],
          "link": "https://example.com"
        }
      ]
    },
    {
      "source": "/abs/path/to/requirements.txt",
      "kind": "requirements",
      "groups": [],
      "extras": [],
      "vulnerabilities": []
    }
  ]
}

For requirements files the groups and extras arrays are always empty so the shape is identical across input kinds. Exit code is non-zero when any vulnerability is found.

Quick recipes with jq:

uv-audit -r pyproject.toml --all --json | jq '.vulnerable'
uv-audit -r pyproject.toml --all --json | jq '.inputs[] | select(.vulnerabilities | length > 0)'
uv-audit -r pyproject.toml --all --json | jq -r '.inputs[].vulnerabilities[].id'

Install as a uv tool

From PyPI (package name is uv-audit2, CLI command stays uv-audit):

uv tool install uv-audit2
uv-audit -r requirements.txt

Or directly from git:

uv tool install git+https://github.com/SpielerNogard/uv-audit.git@main
uv tool run uv-audit -r requirements.txt

GitHub Action

uv-audit is also packaged as a reusable GitHub Action. The action discovers pyproject.toml and requirements*.txt files in your repo, scans each for known vulnerabilities, posts a sticky comment on the PR with findings, and fails the build (configurable) when non-ignored vulnerabilities are present.

Quick start (single job)

name: audit
on: [pull_request]
permissions:
  contents: read
  pull-requests: write
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: SpielerNogard/uv-audit@0.2.0
        with:
          ignore_vulns: |
            PYSEC-2026-161

Inputs

Input Default Description
path . Root directory for discovery
include **/pyproject.toml, **/requirements*.txt Newline-separated glob patterns
exclude .venv, venv, .tox, node_modules, .git, dist, build, site-packages Path components or globs to skip
ignore_vulns (empty) Vulnerability IDs to suppress
fail_on_vuln true Exit non-zero when non-ignored vulns are found
pyproject_args --all Extra CLI args for pyproject scans
uv_audit_version matches action tag Version of uv-audit2 installed from PyPI
comment_on_pr true Create/update the sticky PR comment
github_token ${{ github.token }} Token used for the comment API

Outputs

Output Description
vulnerable 'true' or 'false'
vuln_count Number of non-ignored findings
ignored_count Number of ignored findings
report_json Aggregated JSON report

Private indexes

Composite actions inherit env: from the caller; pass any UV_* / PIP_* environment variable to authenticate against private PyPI mirrors:

- uses: SpielerNogard/uv-audit@0.2.0
  env:
    UV_INDEX_URL: https://pypi.example.com/simple
    UV_INDEX_USERNAME: ${{ secrets.PYPI_USER }}
    UV_INDEX_PASSWORD: ${{ secrets.PYPI_TOKEN }}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uv_audit2-0.3.3.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uv_audit2-0.3.3-py3-none-any.whl (21.2 kB view details)

Uploaded Python 3

File details

Details for the file uv_audit2-0.3.3.tar.gz.

File metadata

  • Download URL: uv_audit2-0.3.3.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for uv_audit2-0.3.3.tar.gz
Algorithm Hash digest
SHA256 0ce6f10fe12d25e24afcb51d522659be349cb8c8d448aa044a713e03bfe1650e
MD5 a4cf3474b092669e08c634bd7752b5a9
BLAKE2b-256 7c96e11ae844244dd1810f87955b8219ef80a0c640e9f36e06ed761fd85199fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_audit2-0.3.3.tar.gz:

Publisher: publish.yml on SpielerNogard/uv-audit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uv_audit2-0.3.3-py3-none-any.whl.

File metadata

  • Download URL: uv_audit2-0.3.3-py3-none-any.whl
  • Upload date:
  • Size: 21.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for uv_audit2-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ead4974fba0ecaa0451000fcaa57bfe7449130cc475901e0c638001ee4a7cd2d
MD5 732c0a59a15ddd9bd7b15fdbc334dc51
BLAKE2b-256 25355b998e72acbaa0db34cfd8e9de622999acb1c32af8634b5c686be59b6139

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_audit2-0.3.3-py3-none-any.whl:

Publisher: publish.yml on SpielerNogard/uv-audit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page