name: "API: Security" on: push: branches: - "master" - "v5.*" pull_request: branches: - "master" - "v5.*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: API_WORKING_DIR: ./api permissions: {} jobs: api-security-scans: runs-on: ubuntu-latest timeout-minutes: 15 permissions: contents: read strategy: matrix: python-version: - "3.12" defaults: run: working-directory: ./api steps: - name: Harden Runner uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 with: egress-policy: block allowed-endpoints: > pypi.org:443 files.pythonhosted.org:443 github.com:443 auth.safetycli.com:443 pyup.io:443 data.safetycli.com:443 api.github.com:443 - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # zizmor: ignore[artipacked] persist-credentials: true # Required by tj-actions/changed-files to fetch PR branch - name: Check for API changes id: check-changes uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 with: files: | api/** .github/workflows/api-security.yml .safety-policy.yml files_ignore: | api/docs/** api/README.md api/CHANGELOG.md api/AGENTS.md - name: Setup Python with Poetry if: steps.check-changes.outputs.any_changed == 'true' uses: ./.github/actions/setup-python-poetry with: python-version: ${{ matrix.python-version }} working-directory: ./api update-lock: 'true' - name: Bandit if: steps.check-changes.outputs.any_changed == 'true' run: poetry run bandit -q -lll -x '*_test.py,./contrib/' -r . - name: Safety if: steps.check-changes.outputs.any_changed == 'true' # Accepted CVEs, severity threshold, and ignore expirations live in ../.safety-policy.yml run: poetry run safety check --policy-file ../.safety-policy.yml - name: Vulture if: steps.check-changes.outputs.any_changed == 'true' run: poetry run vulture --exclude "contrib,tests,conftest.py" --min-confidence 100 .