# 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):

```bash
# 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:

- `component_not_present`: The vulnerable component is not in the product at all.
- `vulnerable_code_not_present`: The component is present, but the vulnerable code was removed or never shipped.
- `vulnerable_code_not_in_execute_path`: The vulnerable code is present but is never invoked.
- `vulnerable_code_cannot_be_controlled_by_adversary`: The vulnerable code executes, but an attacker cannot influence the input that reaches it.
- `inline_mitigations_already_exist`: The product contains a built-in protection that prevents exploitation, which the attacker cannot subvert and the operator cannot disable.

> [!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`)
```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:
```bash
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:
```bash
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.
