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
| Setting | Type | Required | Description |
|---|---|---|---|
| Backfill Start Time | string | No | The date to start fetching data from. If not specified, no past records will be fetched. |
Secrets
| Secret | Type | Required | Description |
|---|---|---|---|
| API Key | string | Yes | API 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_atfield 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_sincetimestamp
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
- First Seen: Converted from
- 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.
Related Articles
- https://semgrep.dev/api/v1/docs/#section/Authentication
- https://semgrep.dev/docs/semgrep-appsec-platform/semgrep-api
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"
}
}
}