Finding Schema

Every engine on the platform — CSPM checks, CIEM, vulnerability, data security, CDR, and the rest of the 29 engines — emits findings normalized to one shared data model. This reference documents that model: the base finding item, the detail response with its compliance and remediation blocks, the list envelopes, the status lifecycle, and the severity scale. If you consume findings through the REST API or a webhook integration, this is the contract.

The findings view in the Onam console (demo account)
The findings view in the Onam console (demo account)

Where findings come from

Engines write findings into tenant-scoped engine databases during each scan run. The BFF gateway serves them through two shapes: compact list rows for tables (GET /api/v1/<engine>/findings) and a full detail document for the finding page (GET /api/v1/views/finding/{engine}/{id}).

How data flows from cloud scans through engines to the API
How data flows from cloud scans through engines to the API

Field naming is cloud-neutral by design, so one integration works across all 7 providers:

Canonical fieldInstead of
resource_uidARN, instance ID, compartment OCID
account_idSubscription ID, project ID
regionAvailability zone
providerOne of aws, azure, gcp, oci, alicloud, ibm, k8s
provider_metadataOpaque dict for CSP-specific fields that don't normalize

BaseFindingItem

BaseFindingItem is the required base for every per-finding list item, regardless of engine.

FieldTypeNotes
finding_idstringStable identifier, unique per engine
resource_uidstringCloud-neutral resource identifier
resource_typestringe.g. aws_s3_bucket, azure_storage_account
providerenumaws, azure, gcp, oci, alicloud, ibm, k8s
regionstringRegion the resource lives in
severityenumcritical, high, medium, low, info
statusstringLifecycle status — see below
account_idstring, optionalCloud account, subscription, or project
scan_run_idstring, optionalThe scan run that produced or last confirmed the finding
first_seen_atdatetime, optionalFirst scan run that raised the finding
last_seen_atdatetime, optionalMost recent scan run that still observed it
provider_metadataobjectCSP-specific extras that don't normalize across clouds
Credential fields never reach the API. credential_ref and credential_type are declared on the model but excluded from serialization, and a validator rejects any payload containing credential- or secret-material keys anywhere in its nested structure. This is enforced in the schema layer as defense in depth — not just in the UI.

Example finding

{
  "finding_id": "chk-4f9a2c31",
  "resource_uid": "arn:aws:s3:::billing-exports",
  "resource_type": "aws_s3_bucket",
  "provider": "aws",
  "region": "us-east-1",
  "severity": "critical",
  "status": "OPEN",
  "account_id": "123456789012",
  "scan_run_id": "550e8400-e29b-41d4-a716-446655440000",
  "first_seen_at": "2026-06-28T04:12:09Z",
  "last_seen_at": "2026-07-19T04:10:44Z",
  "provider_metadata": {
    "bucket_policy_is_public": true,
    "block_public_access_enabled": false
  }
}

Severity levels

Five severity levels apply across all engines. Severity is assigned by the rule (for configuration findings) or computed (for vulnerabilities, where EPSS and CISA KEV feed prioritization).

SeverityMeaningRecommended remediation window
CriticalExploitable exposure with severe impact — public data, admin-level privilege escalation, actively exploited CVEs7 days
HighSignificant weakness likely to be exploited or with broad blast radius30 days
MediumWeakness requiring specific preconditions, or partial control failure90 days
LowHardening gap with limited direct impactNext maintenance cycle
InfoObservation, inventory fact, or best-practice note — no action required

Status lifecycle

Finding status is mutable through the console and the API. New findings open as OPEN; every transition is audit-logged.

StatusMeaningSet by
OPENDetected and unresolved — the default for new or regressed findingsAutomatic
IN_PROGRESSAssigned and being remediatedManual
RESOLVEDFixed — a subsequent scan verifying the fix also resolves it automaticallyManual or automatic on rescan
SUPPRESSEDAccepted risk — hidden from default views, kept for auditManual, note recommended
FALSE_POSITIVEJudged not a real issue — feeds rule tuningManual, note recommended

Status is updated with a StatusUpdateRequest:

PATCH /api/v1/views/finding/{engine}/{id}/status

{
  "status": "SUPPRESSED",
  "note": "Public access is intentional - static website bucket, exception EX-142."
}
FieldTypeNotes
statusenumOPEN, IN_PROGRESS, RESOLVED, SUPPRESSED, FALSE_POSITIVE
notestring, optionalFree-text justification, stored in the audit log
If a resource regresses after being RESOLVED — the misconfiguration comes back — the next scan reopens the finding as OPEN and preserves the original first_seen_at, so your mean-time-to-remediate metrics stay honest.

FindingDetailResponse

GET /api/v1/views/finding/{engine}/{id} returns the full detail document that powers the finding page's tabs. The engine path segment is one of: check, threat, iam, network-security, datasec, encryption, container-security, dbsec, ai-security, cdr, secops, attack-path, api-security.

FieldTypeNotes
findingFindingHeaderThe full header — also aliased as header
relatedFindingsRelatedFindingsBlockCross-engine findings on the same resource
complianceComplianceBlockFramework control mappings for the rule
remediationRemediationBlockOrdered fix steps and references
resourceContextobject, optionalNull here — the UI calls /api/v1/asset-context/{resource_uid} separately
engineExtensionsobjectEngine-specific extra tab payloads
degradedEnginesstring listEngines that timed out during the related-findings fan-out
restrictedEnginesstring listEngines your role may not read (viewer role restrictions)

FindingHeader

The header carries identity, rule metadata, taxonomy, and framework mappings. Detail responses use camelCase field names. Key fields:

FieldTypeNotes
findingId, engine, ruleIdstringIdentity — which rule fired, in which engine
title, description, rationalestringHuman-readable summary and why it matters
severity, status, riskScorestring, string, intTriage fields; riskScore is 0–100
resourceUid, resourceType, resourceNamestringThe affected resource
provider, accountId, regionstringWhere it lives
firstSeenAt, lastSeenAtdatetimeLifecycle timestamps
module, module_label, subcategory, subcategory_labelstringTaxonomy codes and display labels for filter grouping
ruleTypestringconfig, cdr, or threat
mitreTactics, mitreTechniquesstring listMITRE ATT&CK mappings, when threat-relevant
cisBenchmark, cisSection, nistControls, soc2Criteriastring / listDirect framework references on the rule
ticketId, ticketUrlstringLinked Jira or ServiceNow ticket, if one exists
standardColumnsStandardColumnsThe mandatory 14 columns echoed from every finding table
findingDataobjectEngine-specific evidence payload

ComplianceBlock

Maps the finding's rule to compliance controls across the 70+ supported frameworks.

FieldTypeNotes
availablebooleanFalse when the engine has no rule-to-control mapping
controlMappingslistItems of { framework, controlId, controlName, status }

RemediationBlock

FieldTypeNotes
availablebooleanFalse when no guidance exists for the rule
stepsRemediationStep listOrdered steps — { order, action, detail }
referenceItemslist{ url, title } links to vendor documentation
estimatedEffortstring, optionale.g. "15 minutes"
slaPrioritystring, optionalSuggested remediation window from the severity table above
guidance, markdownstring, optionalLong-form guidance
runbook_urlstring, optionalLink to an internal runbook, if configured

RelatedFindingsBlock

Cross-engine findings on the same resource_uid, fetched with a bounded per-engine fan-out.

FieldTypeNotes
availablebooleanWhether the fan-out ran
itemslist{ engine, findingId, severity, ruleId, title, status }
perEngineAvailabilityobjectWhich engines answered within the time budget
restrictedEnginesstring listEngines omitted because your role lacks <engine>:read

List envelopes

Three container shapes wrap findings in list and aggregate responses.

PaginatedList — every scrollable table:

FieldTypeNotes
itemslistPage of finding items
totalintTotal matching rows
page, page_sizeintDefaults 1 and 50; page_size max 200
has_morebooleanTrue when further pages exist

SeverityCounts — KPI breakdowns:

FieldTypeNotes
critical, high, medium, low, infointCounts per severity
by_providerobjectPer-provider SeverityCounts — populated only on multi-cloud aggregation pages (dashboard, compliance, risk)

ScanRunRef — lightweight scan-run metadata attached to results:

FieldTypeNotes
scan_run_idstringThe run identifier
provider, account_idstring, optionalWhich account the run covered
completed_atdatetime, optionalCompletion time
total_findingsint, optionalFindings produced by the run

Next steps

  • API Reference — authentication, pagination, and the endpoint map these schemas travel through
  • CSPM — how the Check engine evaluates 10,000+ rules to produce configuration findings
  • Integration Catalog — push these finding payloads to Jira, Slack, Splunk, or any webhook
  • Data Retention — how long findings are stored and when they are deleted