Files
Northern-Thailand-Ping-Rive…/.gitea/workflows/security.yml
T
grabowski 0ec675e9c5
CI / Format & lint (push) Successful in 10s
Security / Dependency vulnerabilities (push) Successful in 53s
Security / Static analysis (push) Successful in 10s
CI / Test suite (push) Successful in 20s
Security / License report (push) Successful in 50s
ci: license report from a clean venv, not the runner's site-packages
2026-09-11 23:54:44 +02:00

110 lines
3.6 KiB
YAML

name: Security
# Two gates that can actually fail, plus one report:
# - pip-audit against requirements.txt: any known vulnerability in a runtime
# dependency fails the job (dev-only tools are reported, not gated)
# - bandit on src/: HIGH severity findings fail; medium/low are listed.
# B104 (bind 0.0.0.0) is skipped: the service is meant to listen on all
# interfaces behind Cloudflare/Caddy.
# - pip-licenses report as an artifact (informational; the project is MIT
# and its runtime deps are MIT/BSD/Apache/PSF)
# The old file ran safety/bandit/semgrep with `|| true` and could not go red.
on:
schedule:
- cron: "0 3 * * 1" # weekly, Monday 03:00 UTC
workflow_dispatch:
push:
paths:
- "requirements*.txt"
- "pyproject.toml"
- "uv.lock"
- "src/**/*.py"
- ".gitea/workflows/security.yml"
pull_request:
paths:
- "requirements*.txt"
- "pyproject.toml"
- "src/**/*.py"
env:
PYTHON_VERSION: "3.11"
jobs:
dependencies:
name: Dependency vulnerabilities
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install pip-audit
run: |
python -m pip install --upgrade pip --root-user-action=ignore
pip install --root-user-action=ignore pip-audit
- name: Runtime dependencies (gate)
run: pip-audit -r requirements.txt --strict --desc on
- name: Dev dependencies (report only)
run: pip-audit -r requirements-dev.txt --desc on || echo "::warning::dev-only dependency advisories above"
code:
name: Static analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install bandit
run: |
python -m pip install --upgrade pip --root-user-action=ignore
pip install --root-user-action=ignore bandit
- name: bandit (HIGH fails; medium/low listed)
run: |
bandit -r src/ -q --skip B104 -ll -ii || true
bandit -r src/ -q --skip B104 --severity-level high --confidence-level medium
licenses:
name: License report
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: pip
cache-dependency-path: requirements.txt
# A fresh venv, not the runner's site-packages: the report must list the
# project's runtime deps, not whatever the runner image or a previous
# workflow happened to leave installed (semgrep once showed up here).
- name: Install into a clean venv
run: |
python -m venv .lic && . .lic/bin/activate
pip install --upgrade pip --root-user-action=ignore
pip install --root-user-action=ignore -r requirements.txt pip-licenses
- name: Report
run: |
. .lic/bin/activate
pip-licenses --format=markdown --with-urls --output-file=licenses.md
pip-licenses --format=json --output-file=licenses.json
echo "Copyleft licenses among runtime deps (informational; LGPL is fine to link from MIT):"
pip-licenses --format=plain --ignore-packages pip-licenses | grep -iE 'GPL|AGPL|LGPL' || echo " none"
- uses: actions/upload-artifact@v3
with:
name: licenses-${{ github.run_number }}
path: |
licenses.md
licenses.json