HunterX Security Pipeline

Status: Ratified (Sprint 006.9) Version: 1.0.0 Owner: HunterX Engineering Council


1. Purpose / Scope

This document describes eng.security, the pipeline that scans the HunterX repository for security defects on every CI run. It covers the scanner inventory, the graceful-degradation contract, finding classification, artifact output, and how the pipeline plugs into the security quality gate (v7-quality-gates.md).

The pipeline is invoked with:

python -m eng security            # human-readable summary
python -m eng security --json     # machine-readable report

The CI entry point is security-tests.yml; the aggregate result is also wired into the blocking ci.yml job through the security quality gate.


2. Scanner Inventory

Scanner Target Format Purpose
bandit src/hunterx txt Python static security analysis
semgrep src/ JSON Pattern-based SAST (--config auto)
gitleaks repo JSON Secret / credential detection
pip-audit requirements.lock JSON Known-vulnerability audit (PyPI OSV)
safety requirements.lock JSON Known-vulnerability audit (Safety DB)
trivy-fs repo tree JSON Vulnerabilities + secrets + misconfigurations
trivy-image nullc0d30/hunterx:latest JSON Published-image HIGH/CRITICAL audit

Scanner invocation

bandit -r src/hunterx -f txt -o artifacts/security/bandit.txt -q
semgrep --config auto --json-output artifacts/security/semgrep.json src/
gitleaks detect --source . --report-format json --report-path artifacts/security/gitleaks.json --no-banner
pip-audit -r requirements.lock --disable-pip --format json -o artifacts/security/pip-audit.json
safety check -r requirements.lock --json -o artifacts/security/safety.json
trivy fs --scanners vuln,secret,misconfig --skip-dirs build,dist,reports,artifacts,payloads \
  --format json --output artifacts/security/trivy-fs.json --exit-code 1 .
trivy image --scanners vuln,secret --severity HIGH,CRITICAL \
  --format json --output artifacts/security/trivy-image.json --exit-code 1 nullc0d30/hunterx:latest

3. Graceful Degradation Contract

The pipeline MUST never fail a local or CI run merely because a scanner is unavailable. Each scanner reports one of four statuses:

Status When
pass Scanner ran with a zero exit code (no blocking findings).
fail Scanner ran and reported findings (or a blocking error).
error The executable exists but failed to start (exit 127).
skipped The executable is not installed, or the scan subject is genuinely unavailable in this context.

Skipped scans do not block the pipeline. This is what makes a bare local environment usable and lets CI install the full toolchain without the pipeline breaking on missing tools.

Context-aware skipping

Some scans depend on artifacts that do not exist in every context. The container image scan (trivy-image) is the canonical example: before the image is published, Trivy reports “image not found”. SecurityScanner supports skip_failures_containing, a tuple of substrings; when a failed run’s output matches any of them, the scan is reported as skipped instead of failed:

skip_failures_containing=("image not found", "unable to", "not found",
                          "failed to pull", "no such image")

4. Finding Classification

eng.security._count_findings extracts a best-effort finding count per scanner output format:

Every scan’s raw combined output is persisted to artifacts/security/<name>.txt (or the scanner’s own JSON output path) for auditability.


5. Artifacts

artifacts/security-report.json    <- aggregate: scans, failed, blocked, summary
artifacts/security/
  bandit.txt
  semgrep.json
  gitleaks.json
  pip-audit.json
  safety.json
  trivy-fs.json
  trivy-image.json

The aggregate report is uploaded by CI and consumed by the security quality gate via eng.security.to_gate_result, which maps a blocked report to a GateStatus.FAIL.


6. CI Wiring


7. Local Usage

The pipeline degrades to the tools you have installed. To run the full suite locally, install the toolchain (see pyproject.toml [project.optional-dependencies] dev extras) and the system scanners. Then:

python -m eng security

A clean run prints 7/7 scanners clean (skipped scans count as clean).