Security Scanning
The CI security job runs on every pull request and push to main. It is the evidence source for dependency vulnerability review, SAST, image scanning, and secret scanning.
CI Gates
| Gate | Tool | Evidence | Failure policy |
|---|---|---|---|
| Secret scan | Gitleaks | GitHub Actions log and annotations | Any detected secret fails the job |
| Dependency audit | pip-audit against requirements exported from uv.lock | GitHub Actions log | Known vulnerable packages fail the job |
| SAST | Semgrep OWASP Top Ten and secrets rules | Uploaded SARIF | Error-level findings fail the job |
| Image scan | Trivy for API and embedding images | Uploaded SARIF | High or critical fixed vulnerabilities fail the job |
| Runtime smoke | Docker runtime images | GitHub Actions log | Missing runtime imports or present build tools fail the job |
The lockfile freshness gate remains in the main test job with uv lock --check, CI exports a frozen requirements file from uv.lock for pip-audit, and CI installs dependencies with uv sync --frozen --all-extras --dev.
Runtime smoke checks run after the API and embedding images are built. Both images must import app.main, onnxruntime, and rapidocr_onnxruntime; the embedding image must also import spacy and fastembed. Both images must reject build-time tooling by proving setuptools, pkg_resources, and wheel are absent and python -m pip --version fails.
Suppression Process
Suppress a finding only when it is a false positive or an accepted risk with a tracked owner. Record the finding ID, affected file or package, reason, expiry date, and owner in the pull request. Prefer fixing or upgrading over suppressing.
Local Checks
Use the same evidence sources before requesting sign-off:
uv lock --check
uv export --frozen --all-extras --dev --no-emit-project --format requirements-txt --output-file requirements-audit.txt
uv tool run --python 3.11 pip-audit -r requirements-audit.txt --no-deps --disable-pip
just check
docker build -f docker/Dockerfile --target api-runtime -t infoconnect-api:scan .
docker build -f docker/Dockerfile --target embedding-runtime -t infoconnect-embedding:scan .
docker run --rm --entrypoint python infoconnect-api:scan -c "import app.main, onnxruntime, rapidocr_onnxruntime"
docker run --rm --entrypoint python infoconnect-embedding:scan -c "import app.main, spacy, fastembed, onnxruntime, rapidocr_onnxruntime"
Run Gitleaks, Semgrep, pip-audit, and Trivy locally when those CLIs are installed. CI remains the authoritative pass/fail gate.