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.2.tar.gz (21.0 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.2-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: uv_audit2-0.3.2.tar.gz
  • Upload date:
  • Size: 21.0 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.2.tar.gz
Algorithm Hash digest
SHA256 4a7830fe81dce399606e59f2476008b5761bb23183a13e0404ef95dc3312cdcc
MD5 4a62e344188308b23faf7dec066d995b
BLAKE2b-256 3ed09aafe72827c1065b24655eef47cec2d67f8a7cbdbdb4eaf9531004b7edb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_audit2-0.3.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: uv_audit2-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 20.8 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0de01d45a60cfe833c9e5dd65b0c7b53934b322c407e314292a666f692d012e0
MD5 bc2be90f3535da2ef7f68e3afe776b98
BLAKE2b-256 58936c861d60aeeda8b4125f81e61614cb16e69d29fa86dfb713e4e393ecb1cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_audit2-0.3.2-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