Skip to content

Security audit

Security audit #5

Workflow file for this run

name: Security audit
# Monthly pip-audit run for an unattended project.
#
# Why a separate workflow instead of a step in tests.yml:
# - This repo isn't actively developed. Blocking PRs/pushes on every
# newly disclosed CVE means a typo-fix PR can fail months later.
# - Running monthly on a schedule keeps us informed without coupling
# to user activity. Findings are surfaced as a GitHub issue so
# they don't get lost in workflow logs.
on:
schedule:
# 06:00 UTC on the 1st of every month.
- cron: '0 6 1 * *'
workflow_dispatch: # allow manual runs from the Actions tab
permissions:
contents: read
issues: write
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install pip-audit
run: |
pip install --upgrade pip
pip install pip-audit
- name: Run pip-audit
id: audit
run: |
# Capture output and exit code without failing the workflow —
# a non-zero exit just means CVEs were found, which we want
# to report, not error on.
set +e
pip-audit -r docker/requirements.txt > audit.txt 2>&1
echo "status=$?" >> "$GITHUB_OUTPUT"
cat audit.txt
exit 0
- name: Ensure security-audit label exists
if: steps.audit.outputs.status != '0'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh label create security-audit \
--color "B60205" \
--description "Findings from the monthly pip-audit run" \
2>/dev/null || true
- name: Open or update audit issue
if: steps.audit.outputs.status != '0'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
today="$(date -u +'%Y-%m-%d')"
{
echo "Monthly \`pip-audit\` run on $today found vulnerable dependencies."
echo
echo "Workflow run: $run_url"
echo
echo '```'
cat audit.txt
echo '```'
echo
echo "_Bump the affected packages in \`docker/requirements.txt\` and close this issue once the next run is clean._"
} > body.md
existing="$(gh issue list --label security-audit --state open --json number --jq '.[0].number')"
if [ -n "$existing" ]; then
gh issue comment "$existing" --body-file body.md
else
gh issue create \
--title "Security audit: vulnerable dependencies detected" \
--label security-audit \
--body-file body.md
fi