🏠 Home ← Docs Index
Open Beta 📖 Interactive Reader Raw .md llms.txt

Vulnerability Management & VEX Architecture

This guide describes GoClaw's vulnerability assessment lifecycle, how govulncheck is used for call-graph analysis, and how to consume OpenVEX statements to eliminate false-positive security alerts.


1. Vulnerability Assessment Lifecycle

Traditional software security tools rely on naive package version matching. If an application imports a library with a known CVE, the scanner reports a vulnerability even if the vulnerable function is never invoked or compiled into the binary.

GoClaw solves this problem using a 3-pillar supply-chain security architecture:

  1. SBOM (Software Bill of Materials): Exhaustive machine-readable dependency inventory (CycloneDX 1.5 and SPDX 2.3).
  2. govulncheck (Call-Graph Reachability Analysis): Go's official vulnerability tool that performs static analysis on symbol execution paths.
  3. OpenVEX (Vulnerability Exploitability eXchange): Machine-readable declarations explaining why specific reported vulnerabilities do not affect GoClaw.

2. govulncheck Static Analysis

govulncheck analyzes symbol call graphs against the official Go vulnerability database (vuln.go.dev).

Key Differences: Naive Scanner vs. govulncheck

Feature Naive Scanner (Trivy / Grype basic) govulncheck (GoClaw standard)
Analysis Level Module name & version string only AST, Symbol, and Call-Graph reachability
False Positive Rate High (reports CVEs in unused functions) Near Zero (only flags executed symbols)
Runtime Impact None None (runs at CI/build time only)

Generating govulncheck Reports

govulncheck is automatically executed during the release build pipeline. You can also run it locally:

The release pipeline pins the scanner version rather than tracking @latest, so that a report can be reproduced later from the same inputs. Use the same pin locally (it is GOVULNCHECK in .github/workflows/release.yml; v1.1.4, the earlier pin, crashes on Go 1.27):

# Run human-readable vulnerability inspection
go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./...

# Export machine-readable JSON for compliance archives
go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 -json ./... > govulncheck-report.json

In its default text mode, govulncheck exits 3 when it finds reachable vulnerabilities and 0 when it does not; any other non-zero exit is a tool or build failure, and the report it produced should not be trusted. With -json it exits 0 whether or not it finds anything, so read the findings from the report itself, not from the exit code.


3. OpenVEX (Vulnerability Exploitability eXchange)

What is VEX?

When an enterprise security scanner audits GoClaw's SBOM, it may flag transitive library CVEs. Instead of lengthy email exchanges and manual review meetings, GoClaw publishes an official OpenVEX file (goclaw-${VERSION}-vex.json) alongside each release.

VEX lets compliance scanners filter out non-exploitable findings using the fixed set of justifications defined by the OpenVEX specification. The definitions below are the specification's, not GoClaw's — a VEX that reinterprets them is a VEX an auditor can reject:

[!IMPORTANT] A statement is only worth publishing if it survives being checked against the govulncheck report shipped beside it. Where a vulnerability is reachable and a fixed upstream release exists, GoClaw upgrades the dependency instead of writing a justification for it.

Sample OpenVEX Statement (security/vex.json)

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://goclaw.ulab.mn/vex/release-advisory",
  "author": "ULAB.mn Security Team <security@ulab.mn>",
  "timestamp": "2026-09-21T00:00:00Z",
  "version": 2,
  "statements": [
    {
      "vulnerability": {
        "name": "GO-2026-6452",
        "description": "Panic via negative shared-string index in github.com/xuri/excelize"
      },
      "products": [
        "pkg:golang/ulab.mn/agents/goclaw"
      ],
      "status": "not_affected",
      "justification": "inline_mitigations_already_exist",
      "impact_statement": "The vulnerable code is reachable ... the panic is recovered in WorkerPool.executeTask (internal/agent/worker_pool.go), so the residual impact is the failure of the single spreadsheet call that triggered it."
    }
  ]
}

4. How Enterprise InfoSec Teams Consume Release Artifacts

The audit assets of the current release are hosted under https://goclaw.ulab.mn/releases/${VERSION}/, where VERSION is the version named in https://goclaw.ulab.mn/releases/latest.json (for example v0.0.96). Only the current release is served there: a request for an earlier version's files returns 404. The files of earlier releases are available from security@ulab.mn.

  1. SBOM: https://goclaw.ulab.mn/releases/${VERSION}/goclaw-${VERSION}-linux-amd64-sbom.cdx.json (and …-sbom.spdx.json)
  2. OpenVEX: https://goclaw.ulab.mn/releases/${VERSION}/goclaw-${VERSION}-vex.json
  3. govulncheck: https://goclaw.ulab.mn/releases/${VERSION}/goclaw-${VERSION}-govulncheck.json (JSON) and goclaw-${VERSION}-govulncheck.txt (text summary)
  4. Checksums: https://goclaw.ulab.mn/releases/${VERSION}/checksums.json

Scanning with Grype + VEX:

VERSION=$(curl -fsSL https://goclaw.ulab.mn/releases/latest.json \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')

# Scan SBOM with VEX suppression in a single command
grype "sbom:goclaw-${VERSION}-linux-amd64-sbom.cdx.json" --vex "goclaw-${VERSION}-vex.json"

Scanning with Trivy + VEX:

trivy sbom "goclaw-${VERSION}-linux-amd64-sbom.cdx.json" --vex "goclaw-${VERSION}-vex.json"

With the VEX advisory supplied, a scanner suppresses the findings the advisory accounts for. It will not necessarily report a clean result: the scanner's own database may carry advisories GoClaw has not yet assessed, and suppression depends on the scanner matching the VEX product identifier to the SBOM. Treat the VEX as evidence to review alongside the govulncheck report, not as a guarantee of a green scan.