- Introduced AGENTS.md, README.md, TASKS.md, and implementation_plan.md for Vexer, detailing mission, responsibilities, key components, and operational notes. - Established similar documentation structure for Vulnerability Explorer and Zastava modules, including their respective workflows, integrations, and observability notes. - Created risk scoring profiles documentation outlining the core workflow, factor model, governance, and deliverables. - Ensured all modules adhere to the Aggregation-Only Contract and maintain determinism and provenance in outputs.
11 KiB
Export Center Trivy Adapters
The Trivy adapters translate StellaOps normalized advisories into the format consumed by Aqua Security's Trivy scanner. They enable downstream tooling to reuse StellaOps' curated data without bespoke converters, while preserving Aggregation-Only Contract (AOC) boundaries. This guide documents bundle layouts, field mappings, compatibility guarantees, validation workflows, and configuration toggles introduced in Sprint 36 (EXPORT-SVC-36-001, EXPORT-SVC-36-002).
The current Export Center build is wiring the API and workers. Treat this document as the canonical interface for adapter implementation and update any behavioural changes during task sign-off.
1. Adapter overview
| Variant | Bundle | Default profile | Notes |
|---|---|---|---|
trivy:db |
db.bundle |
trivy:db |
Core vulnerability database compatible with Trivy CLI >= 0.50.0 (schema v2). |
trivy:java-db |
java-db.bundle |
Optional extension | Java ecosystem supplement (Maven, Gradle). Enabled when ExportCenter:Profiles:Trivy:EnableJavaDb=true. |
Both variants ship inside the export run under /export/trivy/. Each bundle is a gzip-compressed tarball containing:
metadata.json
trivy.db # BoltDB file with vulnerability/provider tables
packages/*.json # Only when schema requires JSON overlays (language ecosystems)
The adapters never mutate input evidence. They only reshape normalized advisories and copy the exact upstream references so consumers can trace provenance.
2. Bundle layout
trivy/
db.bundle
+-- metadata.json
+-- trivy.db
java-db.bundle # present when Java DB enabled
+-- metadata.json
+-- trivy-java.db
+-- ecosystem/...
signatures/
trivy-db.sig
trivy-java-db.sig
metadata.json aligns with Trivy's expectations (schemaVersion, buildInfo, updatedAt, etc.). Export Center adds an stella block to capture profile id, run id, and policy snapshot hints.
Example metadata.json (trimmed):
{
"schemaVersion": 2,
"buildInfo": {
"trivyVersion": "0.50.1",
"vulnerabilityDBVersion": "2025-10-28T00:00:00Z"
},
"updatedAt": "2025-10-29T11:42:03Z",
"stella": {
"runId": "run-20251029-01",
"profileId": "prof-trivy-db",
"tenant": "acme",
"policySnapshotId": "policy-snap-42",
"schemaVersion": 2
}
}
3. Field mappings
3.1 Namespace resolution
| Stella field | Trivy field | Notes |
|---|---|---|
advisory.source.vendor |
namespace |
Canonicalized to lowercase; e.g. Ubuntu -> ubuntu. |
advisory.source.product |
distribution / ecosystem |
Mapped via allowlist (Ubuntu 22.04 -> ubuntu:22.04). |
package.ecosystem |
package.ecosystem |
OSS ecosystems (npm, pip, nuget, etc.). |
package.nevra / package.evr |
package.version (OS) |
RPM/DEB version semantics preserved. |
If a record lacks a supported namespace, the adapter drops it and logs adapter.trivy.unsupported_namespace.
3.2 Vulnerability metadata
| Stella field | Trivy field | Transformation |
|---|---|---|
advisory.identifiers.cve[] |
vulnerability.CVEIDs |
Array of strings. |
advisory.identifiers.aliases[] |
vulnerability.CWEIDs / References |
CVE -> CVEIDs, others appended to References. |
advisory.summary |
vulnerability.Title |
Stripped to 256 chars; rest moved to Description. |
advisory.description |
vulnerability.Description |
Markdown allowed, normalized to LF line endings. |
advisory.severity.normalized |
vulnerability.Severity |
Uses table below. |
advisory.cvss[] |
vulnerability.CVSS |
Stored as {"vector": "...", "score": 7.8, "source": "NVD"}. |
advisory.published |
vulnerability.PublishedDate |
ISO 8601 UTC. |
advisory.modified |
vulnerability.LastModifiedDate |
ISO 8601 UTC. |
advisory.vendorStatement |
vulnerability.VendorSeverity / VendorVectors |
Preserved in vendor block. |
Severity mapping:
| Stella severity | Trivy severity |
|---|---|
critical |
CRITICAL |
high |
HIGH |
medium |
MEDIUM |
low |
LOW |
none / info |
UNKNOWN |
3.3 Affected packages
| Stella field | Trivy field | Notes |
|---|---|---|
package.name |
package.name |
For OS distros uses source package when available. |
package.purl |
package.PURL |
Copied verbatim. |
affects.vulnerableRange |
package.vulnerableVersionRange |
SemVer or distro version range. |
remediations.fixedVersion |
package.fixedVersion |
Latest known fix. |
remediations.urls[] |
package.links |
Array; duplicates removed. |
states.cpes[] |
package.cpes |
For CPE-backed advisories. |
The adapter deduplicates entries by (namespace, package.name, vulnerableRange) to avoid duplicate records when multiple upstream segments agree.
Example mapping (Ubuntu advisory):
// Stella normalized input
{
"source": {"vendor": "Ubuntu", "product": "22.04"},
"identifiers": {"cve": ["CVE-2024-12345"]},
"severity": {"normalized": "high"},
"affects": [{
"package": {"name": "openssl", "ecosystem": "ubuntu", "nevra": "1.1.1f-1ubuntu2.12"},
"vulnerableRange": "< 1.1.1f-1ubuntu2.13",
"remediations": [{"fixedVersion": "1.1.1f-1ubuntu2.13"}]
}]
}
// Trivy vulnerability entry
{
"namespace": "ubuntu",
"package": {
"name": "openssl",
"version": "< 1.1.1f-1ubuntu2.13",
"fixedVersion": "1.1.1f-1ubuntu2.13"
},
"vulnerability": {
"ID": "CVE-2024-12345",
"Severity": "HIGH"
}
}
3.4 Java DB specifics
The Java supplement only includes ecosystems maven, gradle, sbt. Additional fields:
| Stella field | Trivy Java field | Notes |
|---|---|---|
package.group |
GroupID |
Derived from Maven coordinates. |
package.artifact |
ArtifactID |
Derived from Maven coordinates. |
package.version |
Version |
Compared with semver-lite rules. |
affects.symbolicRanges[] |
VulnerableVersions |
Strings like [1.0.0,1.2.3). |
4. Compatibility matrix
| Trivy version | Schema version | Supported by adapter | Notes |
|---|---|---|---|
| 0.46.x | 2 | Yes | Baseline compatibility target. |
| 0.50.x | 2 | Yes | Default validation target in CI. |
| 0.51.x+ | 3 | Pending | Adapter throws ERR_EXPORT_UNSUPPORTED_SCHEMA until implemented. |
Schema mismatches emit adapter.trivy.unsupported_schema_version and abort the run. Operators can pin the schema via ExportCenter:Adapters:Trivy:SchemaVersion.
5. Validation workflow
- Unit tests (
StellaOps.ExportCenter.Tests):- Mapping tests for OS and ecosystem packages.
- Severity conversion and range handling property tests.
- Integration tests (
EXPORT-SVC-36-001):- Generate bundle from fixture dataset.
- Run
trivy module db import <bundle>(Trivy CLI) to ensure the bundle is accepted. - For Java DB, run
trivy java-repo --db <bundle>against sample repository.
- CI smoke (
DEVOPS-EXPORT-36-001):- Validate metadata fields using
jq. - Ensure signatures verify with
cosign. - Check runtime by invoking
trivy fs --cache-dir <temp> --skip-update --custom-db <bundle> fixtures/image.
- Validate metadata fields using
Failures set the run status to failed with errorCode="adapter-trivy" so Console/CLI expose the reason.
6. Configuration knobs
ExportCenter:
Adapters:
Trivy:
SchemaVersion: 2 # enforce schema version
IncludeJavaDb: true # enable java-db.bundle
AllowEmpty: false # fail when no records match
MaxCvssVectorsPerEntry: 5 # truncate to avoid oversized payloads
Distribution:
Oras:
TrivyRepository: "registry.example.com/stella/trivy-db"
PublishDelta: false
Download:
FilenameFormat: "trivy-db-{runId}.tar.gz"
IncludeMetadata: true
AllowEmpty=falseconverts empty datasets intoERR_EXPORT_EMPTY.MaxCvssVectorsPerEntryprevents extremely large multi-vector advisories from bloating the DB.PublishDeltaworks in tandem with the planner's delta logic; when true, only changed blobs are pushed.FilenameFormatlets operators align downloads with existing mirror tooling.IncludeMetadatatoggles whethermetadata.jsonis stored alongside the bundle in the staging directory for quick inspection.
7. Distribution guidelines
- Download profile:
db.bundleplaced under/export/trivy/and signed. Recommended filenametrivy-db-<runId>.tar.gz. - OCI push: ORAS artifact with annotations:
org.opencontainers.artifact.description=StellaOps Trivy DBio.stella.export.profile=trivy:dbio.stella.export.run=<runId>io.stella.export.schemaVersion=2
- Offline Kit: When
offlineBundle.includeTrivyDb=true, the exporter copies the latest full bundle plus the lastNdeltas (configurable) with manifests for quick import.
Consumers should always verify signatures using trivy-db.sig / trivy-java-db.sig before trusting the bundle.
Example verification flow:
cosign verify-blob \
--key tenants/acme/export-center.pub \
--signature signatures/trivy-db.sig \
trivy/db.bundle
trivy module db import trivy/db.bundle --cache-dir /tmp/trivy-cache
8. Troubleshooting
| Symptom | Likely cause | Remedy |
|---|---|---|
ERR_EXPORT_UNSUPPORTED_SCHEMA |
Trivy CLI updated schema version. | Bump SchemaVersion, extend mapping tables, regenerate fixtures. |
adapter.trivy.unsupported_namespace |
Advisory namespace not in allowlist. | Extend namespace mapping or exclude in selector. |
trivy import fails with "invalid bolt page" |
Corrupted bundle or truncated upload. | Re-run export; verify storage backend and signatures. |
| Missing Java advisories | IncludeJavaDb=false or no Java data in Findings Ledger. |
Enable flag and confirm upstream connectors populate Java ecosystems. |
| Severity downgraded to UNKNOWN | Source severity missing or unrecognized. | Ensure upstream connectors populate severity or supply CVSS scores. |
ERR_EXPORT_EMPTY returned unexpectedly |
Selectors yielded zero records while AllowEmpty=false. |
Review selectors; set AllowEmpty=true if empty exports are acceptable. |
9. References
- Export Center API reference
- Export Center CLI Guide
- Export Center Architecture
- Export Center Overview
- Aqua Security Trivy documentation (external reference for schema expectations)
Imposed rule: Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.