# trivy integration

Source: https://www.testifysec.com/docs/cilock/tools/trivy

Scan containers, IaC, secrets, and licenses with Trivy under cilock — the SARIF report becomes a signed v0.3 attestation parsed by the rookery sarif attestor.

Trivy is Aqua Security's all-in-one scanner — containers, filesystems, IaC, secrets, licenses, and OS/library vulnerabilities, all from one binary. Cilock wraps the same `trivy` invocation, signs its SARIF output, and links it to the git commit and host environment it ran against.

 

| Upstream | [Trivy](https://github.com/aquasecurity/trivy) · Aqua Security · Apache-2.0 |
| --- | --- |
| Category | vulnerability-scan (primary) |
| Catalog source | attestor-backed (ships a native cilock attestor) |
| Emits format | [sarif](https://www.testifysec.com/docs/cilock/attestors/sarif) |
| Predicate type | `https://aflock.ai/attestations/trivy/v0.1` |
| Recommended trace | off — no syscall tracing needed |
| Detected when | - preargv\_prefix: trivy |

Confirm CI/lock detects it:

```bash
cilock plan --format=json -- trivy [...]
```

The facts in this box are generated from the CI/lock binary's own catalog (`cilock tools list`). Do not hand-edit — run `npm run gen:catalog`.

 

## Validated invocation

 

Cilock invokes `trivy` **directly** as the wrapped command — no `bash -c "cp ..."` shim. The real tool is what cilock executes, traces, and records.

 

```bash
cilock run --step trivy-scan \
  --signer-file-key-path _validation/key.pem \
  --outfile attestation.json \
  --attestations sarif,environment,git \
  --enable-archivista=false \
  -- trivy fs --scanners vuln --format sarif --output trivy.sarif .
```

 

This is the exact line validated end-to-end in [`tool-trivy-sarif`](https://github.com/aflock-ai/attestor-compliance-examples/tree/main/tool-trivy-sarif) — don't paraphrase it.

 

Trivy exits non-zero when it finds vulnerabilities at or above its severity threshold. The validated example uses Trivy's default exit-code behavior; cilock surfaces that exit code in the `command-run/v0.2` predicate, so policies can reason about scan results without re-parsing.

 

## What gets captured

 

A single run with `--attestations sarif,environment,git` produces these predicate types in the signed envelope:

 

- `https://aflock.ai/attestations/command-run/v0.2` — the actual `argv`, exit code, and traced syscalls of `trivy`.
 - `https://aflock.ai/attestations/material/v0.3` — Merkle hashes of every input file Trivy read.
 - `https://aflock.ai/attestations/product/v0.3` — Merkle hash of `trivy.sarif` as written by the run.
 - `https://aflock.ai/attestations/sarif/v0.1` — structured parse of the SARIF report, ready for policy.
 - `https://aflock.ai/attestations/environment/v0.1` — host OS, kernel, env vars (with redaction).
 - `https://aflock.ai/attestations/git/v0.1` — repo commit, branch, dirty/clean state.

 

## Why this shape

 

| Pattern | What cilock sees | Verdict |
| --- | --- | --- |
| `-- trivy fs --scanners vuln --format sarif --output trivy.sarif .` | Real `trivy` argv, real exit code, real syscalls. SARIF written into the workdir is picked up by `product/v0.3` and parsed by `sarif/v0.1`. | **Use this.** |
| `-- bash -c "trivy fs ... && cp trivy.sarif out/"` | `bash` argv, `bash` exit code, `bash` + `cp` syscalls. Trivy's real exit code is hidden behind the shell. | Antipattern. |

 

The direct invocation matters because the `command-run` attestor records what cilock actually executes. Wrapping the scanner in `bash -c` means a vuln-induced non-zero exit gets either silently swallowed or attributed to `bash`, and the syscall trace is the shell's, not Trivy's.

 

## Validate it locally

 

```bash
# 1. Generate an ephemeral signing key.
mkdir -p _validation
openssl genpkey -algorithm ed25519 -out _validation/key.pem

# 2. Clone the validated example and run it.
git clone https://github.com/aflock-ai/attestor-compliance-examples.git
cd attestor-compliance-examples/tool-trivy-sarif
cilock run --step trivy-scan \
  --signer-file-key-path ../_validation/key.pem \
  --outfile attestation.json \
  --attestations sarif,environment,git \
  --enable-archivista=false \
  -- trivy fs --scanners vuln --format sarif --output trivy.sarif .

# 3. Confirm the expected predicate types are present.
jq -r '.payload' attestation.json | base64 -d \
  | jq '.predicate.attestations | map(.type)'
```

 

Expected output (order may vary):

 

```text
https://aflock.ai/attestations/command-run/v0.2
https://aflock.ai/attestations/environment/v0.1
https://aflock.ai/attestations/material/v0.3
https://aflock.ai/attestations/product/v0.3
https://aflock.ai/attestations/sarif/v0.1
https://aflock.ai/attestations/git/v0.1
```

 

## FAQ

 

### Does cilock support Trivy?

 

Yes — through the generic [`sarif` attestor](https://www.testifysec.com/docs/cilock/attestors/sarif) (documented on this page). Run Trivy with `--format sarif` and cilock captures the report as a signed `sarif/v0.1` attestation, the same uniform predicate it produces for every SARIF-emitting scanner (Grype, Semgrep, gosec, …).

 

### What does Trivy scan when called from cilock?

 

Cilock doesn't change what Trivy scans — Trivy still scans whatever target you pass it (filesystem, container image, repository, Kubernetes cluster, IaC tree). The validated invocation runs `trivy fs --scanners vuln .`, which scans the working directory for OS-package and language-library vulnerabilities. Swap in `trivy image <ref>` or add `--scanners vuln,secret,misconfig,license` to widen coverage; cilock wraps whichever invocation you choose.

 

### Will the SARIF be empty if Trivy finds nothing?

 

Yes — and that's fine. Trivy still writes a valid SARIF document with an empty `results` array, the `product/v0.3` attestor still records the file's content hash, and the `sarif/v0.1` predicate is still produced. The collection shape doesn't depend on findings being non-empty, so a clean scan still proves the scan ran against the signed inputs.

 

## See also

 

- [`sarif` attestor](https://www.testifysec.com/docs/cilock/attestors/sarif) — the ingestion path used by this page
 - [`tool-trivy-sarif` example](https://github.com/aflock-ai/attestor-compliance-examples/tree/main/tool-trivy-sarif) — the validated end-to-end run
 - [Trivy homepage](https://trivy.dev/) — upstream tool documentation
 - [Tools index](https://www.testifysec.com/docs/cilock/tools)

 

---

**This page is generated from the CI/lock tool catalog.** Don't edit it here — the source is [`attestation/detection/docs/trivy.doc.md`](https://github.com/aflock-ai/rookery/edit/main/attestation/detection/docs/trivy.doc.md) in [aflock-ai/rookery](https://github.com/aflock-ai/rookery). The same catalog powers `cilock tools show trivy` in the CLI, so a single edit keeps the terminal and the website in sync.

[Edit this page →](https://github.com/aflock-ai/rookery/edit/main/attestation/detection/docs/trivy.doc.md) ·  [Add a new tool →](https://github.com/aflock-ai/rookery/new/main/attestation/detection/docs)

When you open the pull request: if you are an **AI agent**, add the `ai-agent` label. If you are a **human**, add the `human` label.

Reference generated from the product documentation. Match commands and support details to your installed release.
