nessus attestor
Ingests a Tenable Nessus .nessus XML report from the attestation products and emits a digest-pinned summary of hosts scanned, findings bucketed by severity, and CVEs referenced by critical/high findings.
| Name | nessus |
| Predicate type | https://aflock.ai/attestations/nessus/v0.1 |
| Lifecycle | postproduct |
| Default binary? | No — builder opt-in only |
What it captures
The attestor walks ctx.Products() looking for files whose path ends in .nessus, verifies the file digest matches the product digest already recorded by the attestation context, then XML-decodes the NessusClientData_v2 document. The predicate records three top-level json-tagged fields:
reportFile— path of the.nessusfile that was ingested.reportDigestSet— the digest set carried by the matching product (used as the integrity anchor; the on-disk file is rejected if its digest does not match).scanSummary— aSummaryobject containing:totalHosts— count of<ReportHost>elements across all<Report>elements.vulnerabilities— aSeverityCountsobject with integer fieldscritical,high,medium,low,info(mapped from Nessus numeric severity 4/3/2/1/0; anything outside 1-4 falls intoinfo).topCVEs— deduplicated list of CVE IDs that appeared on any finding with severity High or Critical.
Per-finding raw data (plugin ID, plugin name, full CVE list, per-host item lists) is parsed from the XML but is not preserved in the predicate — only the aggregated counts and the critical/high CVE set survive into the attestation.
Subjects
The attestor implements attestation.Subjecter and emits SHA-256 digested subjects:
nessus:host:<host-name>for every<ReportHost name="...">encountered.cve:<CVE-ID>for every CVE referenced by a finding whose severity is High (3) or Critical (4). Medium/Low/Info findings do not produce CVE subjects.
When to use
Add this attestor to a custom cilock build when Nessus is your authoritative vulnerability scanner and you want a tamper-evident record of the scan summary attached to a release. The CVE subjects make the attestation joinable against vex statements and other CVE-keyed evidence.
Flags
None. The attestor takes no configuration; it discovers the .nessus file by scanning the product set.
Output shape
{
"reportFile": "out/scan-2026-05.nessus",
"reportDigestSet": {
"sha256": "..."
},
"scanSummary": {
"totalHosts": 12,
"vulnerabilities": {
"critical": 2,
"high": 7,
"medium": 15,
"low": 4,
"info": 88
},
"topCVEs": [
"CVE-2024-12345",
"CVE-2024-67890"
]
}
}
Gotchas
.nessusXML only. The source matches strictly on the.nessussuffix andxml.Unmarshals aNessusClientData_v2document. JSON exports,.csv, and.htmlreports are ignored.- Must be a product. The file has to be present in
ctx.Products()— typically because an earlier step (or--attestor-product-include-glob) added it. If no.nessusfile is in the product set the attestor returnsno .nessus file found in productsand fails the step. - Digest gate. If the on-disk file's digest does not equal the product digest already recorded, that file is silently skipped (debug-logged) and the attestor falls through to the next candidate.
- Lossy summary. Plugin IDs, plugin names, and CVEs from Medium/Low/Info findings are parsed but discarded. If you need the full finding list, attach the raw
.nessusfile as a product as well — the digest inreportDigestSetlets verifiers fetch and re-parse it. - First match wins. Iteration order over
ctx.Products()is map order; if multiple.nessusfiles are present, only the first one whose digest matches is recorded.
CLI example
See the constraint summary + reproduction recipe at https://github.com/aflock-ai/attestor-compliance-examples/tree/main/35-nessus. This attestor is currently blocked or doc-only — the linked example explains why and shows the recipe to validate once the constraint is removed.