diff --git a/.github/workflows/pysentry.yml b/.github/workflows/pysentry.yml new file mode 100644 index 000000000..937abdba0 --- /dev/null +++ b/.github/workflows/pysentry.yml @@ -0,0 +1,23 @@ +# PySentry audits uv.lock natively and uploads findings to the Security tab. +# continue-on-error keeps it advisory: it never blocks a PR. +# Sources, fail-on threshold and per-group policy live in .pysentry.toml, +# which the pre-commit hook reads too, so CI and local scans stay identical. +name: pysentry + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + security-events: write + +jobs: + audit: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: PySentry audit + uses: nyudenkov/pysentry@d351b9969fc6b9287347295245bcf5b13447e634 # v0.5.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3cf06f6e3..980dafc4a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,3 +26,9 @@ repos: - id: flake8 args: ["--config=.flake8"] additional_dependencies: ['flake8-bugbear==23.9.16'] + - repo: https://github.com/pysentry/pysentry-pre-commit + rev: v0.5.0 + hooks: + - id: pysentry + # Resolves the full dependency tree, so run on push rather than every commit. + stages: [pre-push] diff --git a/.pysentry.toml b/.pysentry.toml new file mode 100644 index 000000000..af9b685c2 --- /dev/null +++ b/.pysentry.toml @@ -0,0 +1,26 @@ +# PySentry configuration — https://pysentry.com +# Single source of truth for BOTH the CI workflow (.github/workflows/pysentry.yml) +# and the pre-commit hook, so local and CI scans behave identically. +version = 1 + +[defaults] +# Block on high/critical; medium and below stay advisory. +fail_on = "high" + +[sources] +# Cross-check three advisory databases; findings are merged and de-duplicated. +enabled = ["pypa", "pypi", "osv"] + +# Dev- and doc-only tooling is still scanned, but only critical issues should fail. +# Anything ALSO reachable from production keeps the "high" floor set above — a group +# can loosen below global only for packages exclusive to that group. +[groups.dev] +fail_on = "critical" + +[groups.doc] +fail_on = "critical" + +# Mute individual advisories here once assessed, e.g.: +# [ignore] +# ids = ["GHSA-xxxx-xxxx-xxxx"] # accepted risk or false positive +# while_no_fix = ["PYSEC-2024-xxxx"] # mute only until an upstream fix ships