Skip to main content

Supply Chain Findings

Fetches software supply chain-related findings from Semgrep to identify third-party risk.

Sync Type: Incremental

Requirements

  • Before you connect Monad to Semgrep, you need an API token. API tokens are scoped to include all code findings from a specific account in Semgrep.
  • Please make sure that your account is on Semgrep Code Team tier to have access to the API endpoints.
  • To generate a new Semgrep API key,
  • Log in to Semgrep, and check to confirm which account you are using. If needed, switch to the account that you want to connect to Monad.
  • Click Settings > Tokens > Create new token.
  • In the dialog that appears, make sure that WebAPI is selected and Agent (CI) is deselected in the Token Scopes section.
  • In the Description, enter something like Monad Connector token so that it's clear later what this token is for.
  • Copy the Secrets Value (the token value) to a secure place so you can use it to set up the connector. Once you close this dialog, you cannot view the token value again.

Details

Monad uses the since filter on the API to determine which findings to display. This field is updated every time a request to get findings is successful with the last time a request to get findings was initiated. If this was the first time requesting for findings, a full sync of the data is performed.

Settings

SettingTypeRequiredDescription
Backfill Start TimestringNoThe date to start fetching data from. If not specified, no past records will be fetched.

Secrets

SecretTypeRequiredDescription
API KeystringYesAPI Key for the Semgrep API. This is required to authenticate requests.

OCSF Conversion

The following JQ transformation converts Semgrep Code Finding data to OCSF Version 1.1.0 compliant format.

JQ Transformation

{
class_uid: 2002, # Vulnerability Finding
category_uid: 2, # Findings
type_uid: 200200, # Vulnerability Finding: Unknown
activity_id: 0, # Unknown
severity_id: (.severity | if . == "medium" then 2 else if . == "high" then 3 else if . == "critical" then 4 else 1 end end end),
time: (.created_at | sub("\\.[0-9]+"; "") | fromdateiso8601),
cloud: {
provider: "Unknown",
account: { name: .repository.name }
},
finding_info: {
uid: .id | tostring,
title: .rule_name,
desc: .rule_message,
first_seen_time: (.relevant_since | sub("\\.[0-9]+"; "") | fromdateiso8601)
},
vulnerabilities: [{
desc: .rule_message,
severity: .severity,
title: .rule_name,
vendor_name: "Semgrep",
first_seen_time: (.relevant_since | sub("\\.[0-9]+"; "") | fromdateiso8601),
last_seen_time: (.created_at | sub("\\.[0-9]+"; "") | fromdateiso8601),
cwe: {
uid: (.rule.cwe_names[0] | split("-")[1]),
caption: (.rule.cwe_names[0] | split(":")[1])
},
affected_code: [{
file: {
path: .location.file_path,
name: (.location.file_path | split("/")[-1]),
type_id: 0 #Unknown
},
start_line: .location.line,
end_line: .location.end_line
}],
references: .rule.owasp_names
}],
raw_data: (. | tostring),
metadata: {
version: "1.1.0",
product: {
vendor_name: "Semgrep",
name: "Semgrep"
}
}
}

OCSF Mapping Details

The JQ transformation converts Semgrep Code Findings to OCSF Version 1.1.0 with the following key mappings:

Core Fields

  • Class UID: Set to 2002 (Vulnerability Finding)
  • Category UID: Set to 2 (Findings)
  • Type UID: Set to 200200 (Vulnerability Finding: Unknown)
  • Activity ID: Set to 0 (Unknown)
  • Severity ID: Mapped from Semgrep severity levels:
    • critical → 4
    • high → 3
    • medium → 2
    • others → 1 (Low)
  • Time: Extracted from created_at field with milliseconds stripped

Cloud Information

  • Provider: Set to "Unknown"
  • Account Name: Maps from repository name

Finding Information

  • UID: Finding ID converted to string
  • Title: Maps from rule name
  • Description: Maps from rule message
  • First Seen Time: Converted from relevant_since timestamp

Vulnerability Details

  • Description: Maps from rule message
  • Severity: Maps directly from Semgrep severity
  • Title: Maps from rule name
  • Vendor Name: Set to "Semgrep"
  • Time Information:
    • First Seen: Converted from relevant_since
    • Last Seen: Converted from created_at
  • CWE Information:
    • UID: Extracted from first CWE name (after "-")
    • Caption: Extracted from first CWE name (after ":")
  • Affected Code:
    • File Path: Full file path
    • File Name: Extracted from last segment of path
    • Line Numbers: Start and end lines from location data
  • References: Maps from OWASP names in rule

Metadata

  • Version: Set to "1.1.0"

  • Product:

    • Vendor name: "Semgrep"
    • Name: "Semgrep"
  • Customization

The transformation serves as a starting point and can be modified to accommodate specific requirements while maintaining OCSF compliance. The mapping prioritizes essential asset information and cloud provider detection while providing fallback values for optional fields.

Sample Record

{
"id": 3036615,
"ref": "refs/pull/5845/merge",
"first_seen_scan_id": 9931,
"syntactic_id": "0fce095f-c9f5-6918-3eaa-096ea07e88f9",
"match_based_id": "7e96b193-ff68-d2c0-8485-3a6f34116c76_2",
"repository": {
"name": "static-checks",
"url": "https://github.com/semgrep/semgrep"
},
"line_of_code_url": "https://github.com/semgrep/semgrep/blob/8f56c040-923f-f831-6ba7-5c816f314a09/src/core_cli/Core_CLI.ml#L997",
"triage_state": "untriaged",
"state": "resolved",
"status": "open",
"severity": "low",
"confidence": "low",
"categories": [
"security"
],
"created_at": "2025-08-11T23:46:37.549344Z",
"relevant_since": "2025-08-11T23:46:37.54935Z",
"rule_name": "typescript.react.security.audit.react-no-refs.react-no-refs",
"rule_message": "`ref` usage found. refs give direct DOM access and may create a possibility for XSS, which could cause sensitive information such as user cookies to be retrieved by an attacker. Instead, avoid direct DOM manipulation or use DOMPurify to sanitize HTML before writing it into the page.",
"location": {
"file_path": "frontend/src/corpComponents/Code.tsx",
"line": 100,
"column": 26,
"end_line": 271,
"end_column": 40
},
"sourcing_policy": {
"id": 720,
"name": "Custom Policy",
"slug": "custom-policy"
},
"triaged_at": "2025-08-11T23:46:37.549437Z",
"triage_comment": "sed nostrud aute ut mollit mollit sed in sed nulla",
"triage_reason": "acceptable_risk",
"state_updated_at": "2025-08-11T23:46:37.549469Z",
"rule": {
"name": "html.security.plaintext-http-link.plaintext-http-link",
"message": "This link points to a plaintext HTTP URL. Prefer an encrypted HTTPS URL if possible.",
"confidence": "high",
"category": "security",
"subcategories": [
"vuln"
],
"vulnerability_classes": [
"Mishandled Sensitive Information"
],
"cwe_names": [
"CWE-319: Cleartext Transmission of Sensitive Information"
],
"owasp_names": [
"A03:2017 - Sensitive Data Exposure",
"A02:2021 - Cryptographic Failures"
]
},
"assistant": {
"autofix": {
"fix_code": "cookie.setHttpOnly(true);\nresponse.addCookie(cookie);",
"explanation": "This fix requires an additional library to be imported."
},
"autotriage": {
"verdict": "true_positive",
"reason": "The matched code is used for a non-security related feature."
},
"component": {
"tag": "user data",
"risk": "low"
}
}
}