Skip to content

rust-security

Four MR-time security scanners for Rust workspaces:

  • cargo-deny — license + advisory + bans check (RustSec / CVSS). Pinned to ^0.18 for CVSS 4.0 parsing (RustSec began shipping CVSS 4.0 advisories in late 2025; 0.16.x trips on them with unsupported CVSS version: 4.0).
  • cargo-audit — secondary advisory check on a different cadence. Pinned to ^0.22 for the same CVSS 4.0 reason. allow_failure: true, so an upstream advisory landing mid-day doesn't immediately block merges — review and either patch or pin in deny.toml.

    allow_failure also hides environmental breakage

    cargo-audit fetches the RustSec advisory DB as a git clone, which needs a lock file. Left at its default location under $CARGO_HOME, a runner whose CARGO_HOME is on a shared NFS/EFS cache fails every run with failed to obtain lock file … NFS do not support locking — and allow_failure means nobody notices. advisory_db_path therefore defaults to container-local /tmp. Advisory coverage does not depend on this job: cargo-deny checks the same database and does gate.

    • trivy — filesystem scan, catching transitive vulns the Rust-specific scanners don't model.
    • gitleaks — secret-pattern scan, scoped to the MR's own commits.

cargo-deny and cargo-audit run on rust-tools, which bakes both (versions pinned there, not here). trivy and gitleaks run from their own pinned upstream images.

Always-on — no change-detection input. See Explanation: security, always-on.

Jobs

Job What it runs
cargo-deny cargo deny check
cargo-audit cargo audit --db $[[ inputs.advisory_db_path ]] (allow_failure)
trivy trivy fs --exit-code 1 --severity $[[ inputs.trivy_severity ]] --no-progress .
gitleaks gitleaks detect, with optional --config $[[ inputs.gitleaks_config ]], scoped to the MR diff base

Inputs

Input Type Default Description
stage string security GitLab CI stage.
if string '$CI_PIPELINE_SOURCE == "merge_request_event"' Gating rules:if: for every job.
rust_image string rust-tools:v0.1.0 Image used to run cargo-deny / cargo-audit.
cargo_deny_version string "^0.18" DEPRECATED / ignored on the default image (baked, pinned there).
cargo_audit_version string "^0.22" DEPRECATED / ignored on the default image.
advisory_db_path string "/tmp/advisory-db" Where cargo-audit keeps its RustSec advisory-db clone. Not cargo-audit's default of $CARGO_HOME/advisory-db — see the note below. Point at a persistent local path to avoid re-cloning each run.
trivy_image string "ghcr.io/aquasecurity/trivy:0.72.0" Trivy image.
trivy_severity string "HIGH,CRITICAL" Severities trivy fails on.
gitleaks_image string "ghcr.io/gitleaks/gitleaks:v8.30.1" Gitleaks image.
gitleaks_config string "" Optional --config <path> for a project-local allowlist.
extra_before_script string "" Prepended to the cargo-deny/cargo-audit jobs' before_script (apt installs the trivy/gitleaks images don't need).
trivy_cache_dir string "/opt/ci-cache/trivy" Shared trivy vuln-DB cache. When a DB already exists here, trivy scans offline (--skip-db-update) instead of re-downloading the ~1.2 GB Aqua DB. Absent → downloads exactly as before.

Hermetic scanning via a shared runner cache

trivy_cache_dir defaults to a conventional path, but nothing changes unless a DB actually exists there — a runner that doesn't mount it downloads online as today. To get the speedup, mount a shared writable dir across your runner's jobs and refresh it nightly (trivy image --download-db-only). See the shared-cache spec.

Usage

include:
  - component: gitlab.com/phpboyscout/cicd/[email protected]

See also