Skip to content

Attestations

An attestation is a durable, audit-friendly record asserting why a specific vulnerability is not being remediated. Attestations are the canonical way to suppress a finding from compliance reports, SLA dashboards, and risk score calculations.

Object model

FieldTypeMeaning
cveIdstringThe CVE this attestation covers.
packagestringThe affected package name. The pair (cveId, package) must match a finding in your org.
categoryenumfalse_positive, not_applicable, risk_accepted, or compensating_control.
reasonstringFree-text justification recorded in the audit log.
evidencestring | nullOptional pointer to supporting evidence (URL, ticket ID, attached document).
scopeobjectWhere the attestation applies — see below.
expiresAtdatetime | nullOptional expiry; null means it never auto-expires.
statusenumACTIVE, EXPIRED, or REVOKED.
attestedByuser IDSet automatically from the authenticated user.

Scopes

Scope typeRequired fieldsBehaviour
tagtagIdSuppresses the finding only on that specific image tag.
historicalasOfDateSuppresses any detection whose timeline.detectedAt is on or before asOfDate. New detections after that date will surface again.
blanketSuppresses every detection of (cveId, package) org-wide, including future ones.

Use tag when a CVE is exploitable in some images but not others. Use historical to triage a one-time backlog without silencing future regressions. Use blanket only when you have decided org-wide that the CVE is not actionable.

Creating an attestation

POST /api/attestations requires the developer role. The endpoint validates that the (cveId, package) pair actually exists in your scan data — you cannot pre-attest to a CVE you have never observed.

curl -X POST \
  -H "Authorization: Bearer $HG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cveId": "CVE-2026-10012",
    "package": "openssl",
    "category": "compensating_control",
    "reason": "TLS terminated at the load balancer; container does not expose port 443.",
    "evidence": "https://wiki.example.com/runbooks/lb-tls-termination",
    "scope": { "type": "blanket" },
    "expiresAt": "2026-10-26T00:00:00Z"
  }' \
  "https://harborguard.co/api/attestations"

Tag-scoped example:

{
  "scope": { "type": "tag", "tagId": "tag_01HV..." }
}

Historical example:

{
  "scope": { "type": "historical", "asOfDate": "2026-04-01T00:00:00Z" }
}

Each create, revoke, or renewal action is recorded on the attestation's history array and emits a vulnerability.attested audit event.

Expiry

Attestations auto-revert to EXPIRED on their expiresAt date. Any finding that the attestation was suppressing reverts to OPEN and re-enters the SLA timer using its original detection date. To extend an attestation before it expires, update expiresAt via PATCH /api/attestations/{attestationId}.

A long-suppressed CVE that re-opens after attestation expiry can immediately appear as an SLA breach — its deadline is computed from the original detection date, not from the expiry. Renew before the date passes if you need to maintain suppression.

Revocation

Revoke an attestation explicitly with DELETE /api/attestations/{attestationId} (or the Revoke action in the UI). Revocation behaves the same as expiry — the suppressed finding re-opens — but it records who revoked it and why on the history trail.

See also

On this page