Skip to Content
Welcome to the Novantra documentation.

Findings

The Findings endpoints expose the gap register, and let an external system create findings so a scanner, a code-quality tool, an external auditor’s portal, or any other source of remediation items can push directly into the workspace.

v1 supports reading findings and creating new ones. Update and archive happen in the Novantra UI today.

For shared conventions (auth, errors, pagination, ID format, reason field), read v1 conventions first.

Scopes required

EndpointScope
Read endpointsgovernance.findings:read
Create findinggovernance.findings:write

Endpoints

List findings

GET /api/v1/governance/findings Authorization: Bearer <access-token>

Query parameters:

ParameterTypeNotes
statusstringOptional. Filter by status: open, triaged, remediation_planned, remediating, verified, closed, accepted, archived.
sourceKindstringOptional. Filter by source: assessment, audit, evidence_gap, control_gap, obligation_gap, risk_review, manual, module_signal.

Response:

{ "findings": [ { "id": "find_01HXY...", "findingKey": "scanner-CVE-2026-12345-affecting-service-x", "sourceKind": "module_signal", "sourceModuleKey": "external", "sourceResourceType": "scanner-finding", "sourceResourceId": "SCANNER-REF-998877", "subjectModuleKey": "controls", "subjectResourceType": "control", "subjectResourceId": "ctrl_01HXY...", "title": "High-severity dependency vulnerability in service X build chain", "description": "CVE-2026-12345 detected in transitive dependency; upgrade or compensating control required.", "severity": "high", "status": "open", "ownerResponsibilityId": null, "ownerMemberUserId": null, "dueAt": null, "closedAt": null, "lifecycleInstanceId": null, "createdAt": "2026-05-25T03:14:07.000Z", "updatedAt": "2026-05-25T03:14:07.000Z" } ], "pagination": {} }

Get one finding

GET /api/v1/governance/findings/:findingId Authorization: Bearer <access-token>

Returns the single-finding shape from the list above.

Create a finding

POST /api/v1/governance/findings Authorization: Bearer <access-token> Content-Type: application/json Idempotency-Key: scanner-batch-2026-05-25-finding-998877
{ "findingKey": "scanner-CVE-2026-12345-affecting-service-x", "sourceKind": "module_signal", "sourceModuleKey": "external", "sourceResourceType": "scanner-finding", "sourceResourceId": "SCANNER-REF-998877", "subjectModuleKey": "controls", "subjectResourceType": "control", "subjectResourceId": "ctrl_01HXY...", "title": "High-severity dependency vulnerability in service X build chain", "description": "CVE-2026-12345 detected in transitive dependency; upgrade or compensating control required.", "severity": "high", "reasonForChange": "Automated ingest from dependency scanner nightly run on 2026-05-25." }

Response: the created finding record, with status: "open" by default.

Use idempotency keys for every create call. A scanner that retries on transient failure will otherwise create duplicate findings. A stable key derived from the source’s own finding ID is the cleanest choice.

Field notes

findingKey

A stable, deterministic key your integration controls. Two different findings about the same vulnerability in the same place should produce the same findingKey so they aren’t duplicated by retry; two different findings about different vulnerabilities should produce different keys. The key is unique per organization.

sourceKind

Pick the kind that best describes where the finding came from. The product treats them all the same operationally; the kind drives filtering and helps reviewers understand provenance.

sourceModuleKey, sourceResourceType, sourceResourceId

Identify the upstream source. For external scanners use "external" as sourceModuleKey and a meaningful resource type like "scanner-finding", "audit-observation", "pen-test-finding". sourceResourceId is whatever identifier the source system uses.

subjectModuleKey, subjectResourceType, subjectResourceId

The governed object the finding is about. Typically a control, but can be an asset, an obligation, a vendor engagement, or any other governed object. See Attaching records to governed subjects.

severity

Free text. Your organization picks the vocabulary. Common values are critical, high, medium, low, informational, but tier-1 / tier-2 or any other scheme works. Map your source system’s severity into your own canonical severity when ingesting.

ownerResponsibilityId and ownerMemberUserId

Optional. If your integration knows who should own this finding, set one of them. If not, leave both null and Novantra’s triage workflow will assign one.

dueAt

Optional. If your organization has policy (“high findings due within 30 days”), the integration can pre-compute and set it. Otherwise leave null and triage will set it.

reasonForChange

Required, like every mutation. Explain the source and intent. The reason is captured in the audit log.

Real-case integration: a dependency scanner pushes findings nightly

A software product company runs a dependency vulnerability scanner against its main service repositories every night. The scanner produces a list of vulnerabilities with severity, CVE identifiers, affected packages, and recommended fix versions.

Their integration is a small service that runs after the scanner completes:

  1. Reads the scanner output.
  2. For each vulnerability, derives a stable findingKey from <repo>-<package>-<cve> so re-runs don’t create duplicates.
  3. Maps the scanner’s severity (the scanner uses critical / important / moderate / minor) to the organization’s canonical severity (critical / high / medium / low).
  4. Looks up the subject control: the company has a control dependency-vulnerability-management that owns this class of finding.
  5. Calls POST /api/v1/governance/findings for each new vulnerability with:
    • sourceKind: "module_signal".
    • sourceModuleKey: "external", sourceResourceType: "dep-scanner-finding", sourceResourceId: <scanner's finding ID>.
    • subjectResourceId: <the control's ID>.
    • Idempotency-Key: <findingKey> so the call is safe to retry and safe to re-run.
  6. For vulnerabilities the scanner reports as “no longer found” (because they’ve been patched upstream), the integration calls a separate UI-side workflow to close the finding; v1 doesn’t support programmatic close. This is the only manual step.

The integration’s service account holds exactly governance.findings:write (plus governance.controls:read to resolve subject IDs). It runs once a day, takes a few minutes, and respects rate limits. Daily triage in the Novantra UI handles the rest.

Same pattern works for: SAST findings, IaC scanners, CSPM tools, SBOM monitors, third-party audit drops.

Webhooks

The Findings module emits these webhook events:

  • finding.created - a new finding was recorded.
  • finding.updated - severity, status, owner, or due date changed.
  • finding.closed - the finding was closed (resolved, accepted, or archived).

See Webhooks for the payload shape, signature verification, and delivery semantics. A common pattern is to subscribe to finding.closed and update the source scanner’s view so the scanner knows the gap was handled.

Last updated on