Harden security audit result contracts
This commit is contained in:
@@ -34,16 +34,28 @@ tools/checks/security-audit/run.sh --mode full --scope govoplan
|
||||
```
|
||||
|
||||
Reports are written to `audit-reports/`, which is intentionally ignored by git.
|
||||
Each run records tool versions, report checksums, and start/end repository
|
||||
revision plus worktree fingerprints. A repository change during scanning makes
|
||||
the run fail so a mixed code snapshot cannot be reported as a valid audit.
|
||||
Step exit codes are recorded separately from findings: report-only mode may
|
||||
accept findings, but scanner execution errors and malformed JSON/SARIF reports
|
||||
always fail the run. The manifest lists the expected, present, and missing
|
||||
reports for that invocation. Validation and checksums use that explicit set, so
|
||||
reusing a report directory cannot make stale output look like part of a new run.
|
||||
|
||||
The wrapper tags the toolbox image by a fingerprint of the Dockerfile and
|
||||
`requirements-audit.txt`. If those inputs have not changed, subsequent runs reuse
|
||||
the existing local image instead of reinstalling all tools. The stable alias is
|
||||
`govoplan/security-audit:local` unless `SECURITY_AUDIT_IMAGE` is set.
|
||||
The wrapper tags the toolbox image by a fingerprint of the Dockerfile,
|
||||
`requirements-audit.txt`, and the Semgrep smoke-test inputs. If those inputs have
|
||||
not changed, subsequent runs reuse the existing local image instead of
|
||||
reinstalling all tools. The stable alias is `govoplan/security-audit:local`
|
||||
unless `SECURITY_AUDIT_IMAGE` is set.
|
||||
|
||||
Semgrep is installed separately in the toolbox image because current Semgrep
|
||||
packages pin Click to an affected `8.1.x` line. The image upgrades Click after
|
||||
Semgrep installation and fails during build if Semgrep no longer starts with the
|
||||
patched Click version.
|
||||
packages pin affected Click and MCP versions. The image upgrades both after
|
||||
Semgrep installation, runs an actual local-rule scan, and audits the final
|
||||
toolbox Python environment during the image build. The compatibility releases
|
||||
are pinned exactly to keep the tested override reproducible. Remove either
|
||||
compatibility override only after Semgrep's own dependency bounds include a
|
||||
fixed version.
|
||||
|
||||
Force a cached rebuild:
|
||||
|
||||
@@ -70,6 +82,10 @@ tools/checks/security-audit/run.sh --mode quick --scope current --update --build
|
||||
- `ci`: quick plus Semgrep public registry rulesets, Trivy, pip-audit, npm audit.
|
||||
- `full`: ci plus OSV-Scanner, jscpd, Radon, and Xenon.
|
||||
|
||||
Semgrep and Trivy are invoked with finding-sensitive exit codes. Their exit 1
|
||||
is therefore a finding under the wrapper contract; higher exit codes, missing
|
||||
output, invalid JSON/SARIF, and scanner error payloads are execution failures.
|
||||
|
||||
Bandit and Ruff security reports are split by source kind. Production code under
|
||||
`src/` is written to `bandit.json` and `ruff-security.json` and controls strict
|
||||
mode. Test code under `tests/` is still scanned for visibility, but its findings
|
||||
@@ -153,7 +169,10 @@ cd /mnt/DATA/git/govoplan
|
||||
python -m venv .venv
|
||||
./.venv/bin/python -m pip install -r requirements-audit.txt
|
||||
./.venv/bin/python -m pip install 'semgrep>=1.140,<2'
|
||||
./.venv/bin/python -m pip install --upgrade --no-deps 'click>=8.3.3'
|
||||
./.venv/bin/python -m pip install --upgrade --no-deps 'click==8.3.3'
|
||||
./.venv/bin/python -m pip install --upgrade --no-deps 'mcp==1.28.1'
|
||||
./.venv/bin/semgrep scan --metrics=off --config tools/checks/security-audit/semgrep-govoplan.yml tools/checks/check-version-alignment.py
|
||||
./.venv/bin/pip-audit --progress-spinner off
|
||||
```
|
||||
|
||||
Then install the non-Python tools (`gitleaks`, `trivy`, `osv-scanner`, `jscpd`)
|
||||
|
||||
Reference in New Issue
Block a user