Files
gstack/docs/cso-scanners.md
T
Garry TanandOpenAI Codex 4a3c6a8a3c v1.87.0.0 feat: add verified CSO audits and replayable repair bundles (#2852)
* feat(cso): add verified audits and replayable repair bundles

* fix(cso): harden qualification and setup boundaries

* fix(cso): assemble security canaries at runtime

* fix(cso): bound release proof and maintenance work

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): require complete evaluation reports

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): replay expired snapshots from supplied source

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cso): synchronize DNS cancellation assertion

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore(ship): exempt repository owner from liveness proof

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cso): make recheck retention overlap deterministic

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: bump version and changelog (v1.85.0.0)

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): pass native release gates

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: move release to v1.86.0.0

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): resolve rechecks by finding

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: move release to v1.87.0.0

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): pass macOS and Windows release gates

Normalize BSD wc output, compare Windows paths by filesystem identity, preserve portable snapshot race coverage, and narrow POSIX-only Windows fixtures.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): harden native verification gates

* fix(cso): refine Windows native diagnostics

* test(cso): isolate Windows Git startup failure

* test(cso): stabilize Windows native diagnostics

* fix(cso): support hardened Git on Windows

* fix(cso): close final verification gaps

* test(cso): bound cold Docker fixture setup

* fix(cso): restore cross-platform free-suite gates

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
2026-09-14 15:14:58 -07:00

104 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Running CSO scanners
`gstack-cso scan RUN SCANNER [REQUEST.json]` collects candidate evidence through
the trusted helper when a matching qualified scanner catalog profile exists.
Recognized IDs are `gitleaks`, `osv`, `semgrep`, `zizmor`, `trivy`, and
`schemathesis`. Without a qualified profile, the command records a specific
prerequisite; static assessment and importing existing CodeQL or other SARIF
with `gstack-cso import-sarif RUN REPORT.sarif` remain available.
The returned immutable artifact can be read later with
`gstack-cso scanner-outcome RUN ARTIFACT_ID`; callers never need to open private
state files directly.
The source-controlled catalog in
[`scanner-images/catalog.json`](../lib/cso/scanner-images/catalog.json) is empty
until every release gate produces real evidence. Without a reviewed profile,
the command records a specific `not_assessed` prerequisite. Installing a
scanner on the host does not enable execution. Each profile binds a Linux
platform, immutable image digest, fixed entrypoint, absolute scanner executable,
version-probe hash, required adapter capabilities, helper ABI, and the exact
isolation-policy hash. The helper validates that catalog when it starts and has
no executable fallback.
Setup preloads the current platform's qualified scanner digests through the
trusted installation helper using anonymous public-registry access. A failed
preload or a bounded per-image/setup deadline is a nonfatal prerequisite and
never causes an audit to pull. The default is 30 seconds per declared image;
`GSTACK_CSO_IMAGE_PULL_TIMEOUT_SECONDS=120` selects a longer allowance (accepted
range: 5300 seconds) while the complete preload remains capped at one hour. Doctor is
read-only and reports each scanner unavailable unless its exact catalog digest
is already present locally.
All scanner processes use Docker containment with a watchdog, shared admission
limits, read-only source, bounded output, and an isolated network namespace.
Static scanners have no network access, including when the audit omits
`--offline`. Semgrep rules and OSV/Trivy databases must be baked into the reviewed
image. Their content hashes, scope, and freshness accompany the result. Database
refresh is a separately reviewed image acquisition/release operation; scans
never download missing assets or switch to unrestricted registry networking.
`REQUEST.json` can select an exact scanner `profile`. Schemathesis additionally
requires comprehensive mode and an `api` object; `gstack-cso schema` describes
its fields. The API harness supplies a bounded OpenAPI 3.0/3.1 JSON document,
120 unique path operation IDs, a qualified application runtime, an absolute
start command, a numeric loopback port, a legitimate HTTP control, and the
source files defining the security boundary. Internal schema references are
allowed. Server overrides, remote references/examples, hooks, callbacks, and
webhooks are rejected. The application must boot and pass the control before
the scanner starts. Application and scanner share only the admitted loopback
namespace. An API failure is a candidate, never a reproduced vulnerability or
certified repair. Sources needing dependency preparation report that prerequisite
until a prepared offline closure is available to the API runner.
Each execution probes the scanner version before scanning and validates the
retained source both before and after collection. Unknown output, failed
diagnostics, a timeout, changed source, or incomplete cleanup cannot become an
empty clean result. The helper retains valid partial candidates when the
adapter can distinguish them from failed coverage. Output that cannot be
redacted is withheld.
Scanner and SARIF collection hold the run's mutation lock and reject finished
or interrupted reports. Every outcome is written exclusively under a unique
`scanner-outcomes/` name before its coverage record enters the report. The
returned `artifact` path is relative to the run directory. Model submissions
cannot replace `scanner:*` coverage or certify the imported candidates. The
free scanner tests use injected runners and catalogs to verify dispatch and
failure handling; they do not claim real image qualification. The opt-in Docker
qualification test runs the production adapter, image, watchdog, and isolation
policy. It emits the version-output hash only after a representative scan
completes without a coverage gap.
The release inputs in
[`build-inputs.json`](../lib/cso/scanner-images/build-inputs.json) remain
`pending` until reviewers provide all six scanners on both native platforms.
The inputs require immutable base and SBOM-generator image digests, exact source
commits and versions, signer workflow identities and digests, and reviewed
canonical SLSA/SPDX statement-set digests. The workflow cryptographically
re-verifies each image with those repository, source, signer, and predicate
constraints before use. Semgrep additionally requires a reviewed local rules bundle. OSV and
Trivy require complete offline database bundles with recorded content hashes,
freshness, and ecosystem coverage. Publishing those asset-bearing base images
and reviewing their evidence are external prerequisites; the release workflow
does not invent or silently replace them.
[`cso-scanner-images.yml`](../.github/workflows/cso-scanner-images.yml) lets a
dispatched branch run read-only input and contract validation. Image publishing,
native amd64/arm64 qualification, attestation verification, embedded-asset hash
checks, containment, real-adapter execution, and catalog-proposal generation run
only from protected `main` through the `cso-scanner-release` environment. Before
enabling qualification or promotion, configure the repository's
`cso-scanner-release` GitHub environment with required maintainer reviewers and
deployments restricted to protected `main`. GitHub otherwise creates a referenced
missing environment without protection rules. Promotion requires an explicit
dispatch from `main` and approval through that configured environment. It opens a pull request
containing only the proposed source catalog, so code review remains the final
authorization step. `previousRevision` records the prior compatible catalog for
rollback and must still equal the current `main` catalog when promotion runs.
Scanner flags follow the primary documentation linked in
[`scanners.ts`](../lib/cso/scanners.ts). Offline qualification must exercise
the exact chosen version: OSV's maintainers documented a cache-location
regression in 2.5.0, which demonstrates why a version string alone is insufficient.
[OSV issue #2983](https://github.com/google/osv-scanner/issues/2983).
Trivy uses an explicit memory scan cache alongside read-only baked databases.
[Trivy filesystem reference](https://trivy.dev/docs/v0.68/guide/references/configuration/cli/trivy_filesystem/).