5.1 KiB
Security CI guide
This project runs a set of automated security checks on pull requests and selected branch pushes. This page explains what each one does, whether it can block a merge, and the few one-time settings you should turn on to get the full benefit.
What runs, and why
Most checks live in files under .github/workflows/. CodeQL is configured
through GitHub's code scanning default setup, so it appears as a dynamic GitHub
workflow instead of a checked-in workflow file. They run automatically; you do
not start them.
| Check | What it protects against | Blocks a merge? |
|---|---|---|
| Secret scan (gitleaks) | An API key, token, or password being committed by mistake or on purpose | Yes |
| Workflow security (actionlint + zizmor) | A broken or insecure automation file that could leak the repo's access token | Yes |
| Dependency review | A pull request that adds a software library with a known security hole | Yes |
| pip-audit | Known security holes in the Python libraries already used | No (advisory) |
| Container scan: hadolint | Mistakes and insecure patterns in the Dockerfile |
Yes |
| Container scan: Trivy | Known security holes in the Docker image | No (advisory) |
| CodeQL | Real bugs in the app's own code: injection, auth mistakes, path traversal | No (advisory) |
"Blocks a merge" means a red X appears on the pull request and, once you enable the setting below, the Merge button is disabled until it is fixed.
"Advisory" means it reports problems into the repository's Security tab so you can review them on your own schedule, but it never stops a merge. These are advisory on purpose: they often flag long-standing issues in other people's libraries, not something a given pull request introduced.
Where results appear
- Checks tab of a pull request: the pass/fail of each check. A green tick is good; a red X needs attention.
- Security tab of the repository: detailed findings from the advisory scanners (Trivy and CodeQL). This is your dashboard.
If a check fails
- Secret scan failed: a real credential may have been committed. Treat it as leaked: rotate (regenerate) that key or token immediately, then remove it from the file. Do not just delete the commit; assume it was seen.
- Dependency review failed: the pull request adds a library with a known vulnerability. Ask the contributor to use a patched version, or decline the change.
- hadolint / workflow security failed: the contributor changed the
Dockerfileor an automation file in a way the linter rejects. Ask them to address the message shown in the failed check.
One-time settings to turn on
These two settings unlock the full value. You only do them once.
1. Require the blocking checks before merging
This makes the Merge button refuse to work until the gating checks pass.
-
Go to the repository on GitHub.
-
Click Settings (top right of the repo).
-
In the left sidebar, click Branches.
-
Under Branch protection rules, click Add branch ruleset (or Add rule), and set the branch name pattern to
dev(this is the branch all pull requests target;mainis fast-forwarded at releases). -
Enable Require status checks to pass before merging.
-
In the search box that appears, add these checks by name:
Python syntax (compileall)JS syntax (node --check)gitleaksactionlintzizmor (Actions SAST)hadolint (Dockerfile lint)dependency-review (PR gate)
The first two come from the correctness CI (
ci.yml); the rest are this security suite. Leave pytest, pip-audit, Trivy, and CodeQL unchecked so they stay advisory. -
Also enable Require a pull request before merging and Require review from Code Owners (this uses the
.github/CODEOWNERSfile so every change needs your sign-off). -
Click Create / Save changes.
Note: a check name only appears in the list after it has run at least once, so let the workflows run on one pull request first, then add them here.
2. Turn on the Security tab features
-
Settings -> Code security (or Code security and analysis).
-
Turn on Dependency graph (usually on by default for public repos) -- this powers Dependency review and Dependabot.
-
Turn on Dependabot alerts and Dependabot security updates.
-
Under Code scanning, use Set up -> Default for CodeQL. GitHub then runs CodeQL as a dynamic workflow without the fork-token limitations that affect checked-in advanced workflows.
Do not also add a checked-in CodeQL workflow while default setup is enabled: GitHub rejects advanced CodeQL uploads when default setup is active. If the project later needs an advanced CodeQL workflow, disable default setup first and keep only one CodeQL publishing path active.
Keeping it current
.github/dependabot.yml opens small weekly pull requests to update Python and
npm packages, the Docker base image, and the pinned automation actions
themselves. Review and merge those like any other pull request; they keep the
project patched without manual tracking.