Get started

Export cloud security findings

Exports read findings already stored in the graph, up to 500 rows, ordered by normalized_score descending. Run rules or CVE enrichment first. Findings that exist only in a scanner and were never ingested are not included. The CLI supports three formats. There is no filter by severity, rule, or account.

./om export findings run --format siem --out findings.jsonl
./om export findings run --format slack
./om export findings run --format jira

--format defaults to siem. Unknown formats fail with unsupported format. SIEM output is JSON Lines on stdout unless --out is set. --out creates or truncates that file. A short count goes to stderr so it stays out of the JSONL stream: Exported N findings to SIEM JSONL.

Record shape

Each SIEM line is one JSON object. timestamp is the export time in UTC, the same value on every line in the run.

{
  "timestamp": "2026-09-28T18:00:00.000000Z",
  "finding": {
    "id": "finding:cspm-public-datastore:aws:s3:acme-logs-public",
    "type": "Finding",
    "name": "Public datastore",
    "provider": "aws",
    "properties": {
      "finding_type": "cspm",
      "rule_id": "cspm-public-datastore",
      "title": "Public datastore: acme-logs-public",
      "severity": "critical",
      "normalized_score": 95
    }
  },
  "affected_resource_id": "aws:s3:acme-logs-public",
  "affected_resource_name": "acme-logs-public",
  "affected_resource_type": "Datastore"
}

affected_resource_* comes from the VIOLATES edge. A finding with no such edge still exports. Those three fields are omitted. An attack-path finding also includes path, the ordered node ids, both on the record and inside finding.properties.

Slack

--format slack requires SLACK_WEBHOOK_URL. The message is a single {"text":"..."} payload titled OpenSourceOM findings export. It lists up to 20 findings as [SEVERITY] title — resource, then …and N more when the export is longer. An empty graph posts No findings to export. The CLI prints Posted N findings to Slack. using the full record count, not the 20 shown in the message. A webhook status of 300 or higher fails the command and includes the response body.

The API posts the same digest:

curl -s -X POST -H "Authorization: Bearer $OM_API_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{"webhook":"https://hooks.slack.com/services/..."}' \
  http://localhost:8080/v1/export/slack

The route rejects ?webhook=. The CLI does not take the URL as a flag. Keep it in the environment. See Security.

Jira

--format jira creates one issue per finding, in order, and stops on the first error. Issues created before that error remain. All four variables are required: JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN, and JIRA_PROJECT. The client calls POST {JIRA_URL}/rest/api/3/issue with HTTP basic auth (email and API token). Each issue is type Task in JIRA_PROJECT. The summary is [SEVERITY] title. The description is Atlassian document format: the finding description, then Affected: name (type). The command prints Created N Jira issues.

A second run creates another issue per finding. There is no deduplication key. Run it when you mean to open tickets.