Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Weekly security check

# New vulnerabilities are published for code nobody touched, and CI only looks when code
# changes. This checks every dependency this repository ships against the public advisory
# databases each Monday and whenever those dependencies change, and fails loudly: a red run,
# which GitHub emails to whoever last edited this schedule. GitHub pauses schedules in public
# repositories after 60 days without a commit; "Run workflow" on the Actions tab resumes it.

on:
schedule:
- cron: "27 5 * * 1"
pull_request:
paths:
- ".github/workflows/security.yml"
- "services/api/requirements.txt"
- "dashboard/package.json"
- "dashboard/package-lock.json"
- "dashboard/Dockerfile"
workflow_dispatch:

# Read-only token: the check reads code and public advisories; it writes nothing.
permissions:
contents: read

jobs:
python:
name: Python dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: "3.11"

- name: Install pip-audit
run: python -m pip install --quiet pip-audit==2.10.1

- name: Service requirements
# Resolved the way the image build resolves them, then checked package by package.
run: pip-audit --strict --progress-spinner off -r services/api/requirements.txt

dashboard:
name: Dashboard dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: "24.11.1"

- name: npm packages, moderate advisories and above
working-directory: dashboard
run: npm audit --audit-level=moderate

- uses: actions/setup-python@v7
with:
python-version: "3.11"

- name: The dashboard image's Python server
# The image installs these pins inline, so read them from the Dockerfile itself.
run: |
python -m pip install --quiet pip-audit==2.10.1
grep -oE '[A-Za-z0-9_.-]+==[0-9][A-Za-z0-9_.]*' dashboard/Dockerfile > "$RUNNER_TEMP/server.txt"
test -s "$RUNNER_TEMP/server.txt"
pip-audit --strict --progress-spinner off -r "$RUNNER_TEMP/server.txt"
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ a decision with visible consequences.

## Unreleased

- Update certifi to 2026.10.19 for a published advisory, and the dashboard's build
tooling and React Router for published advisories.
- A weekly security check (`.github/workflows/security.yml`) audits every dependency this
repository ships against the public advisory databases each Monday and whenever they
change, and fails loudly.
- Outbound HTTP clients now ignore ambient proxy environment variables and
refuse redirects, with live hostile-proxy and static policy regression tests.
- Processing jobs now use durable, renewable leases. Restarted workers reclaim
Expand Down
Loading
Loading