(how to use this is way down so you can skip to that but if you want to know whats happening please continue)
SBOM-TM is a GitHub Action–based security tool that automatically scans your repository for software supply-chain risks using a Software Bill of Materials (SBOM).
It provides Dependabot-style security visibility, but for everything in your project — not just dependency updates.
Features
SBOM-TM scans your project for:
- Software components
- Known vulnerabilities (via Trivy)
- Dependency additions, removals, and version changes
- Upgrade / downgrade risks
- Threat-rule violations
It automatically generates:
- SBOM scan reports (Markdown / JSON / HTML)
- SBOM diff reports for Pull Requests
- Sticky PR comments highlighting new risks
- GitHub Issues when vulnerabilities exist on
main - GitHub Artifacts containing all reports
- Generates a CycloneDX SBOM using Syft
- Scans the SBOM using Trivy
- Applies threat-modeling rules
- Posts results on Pull Requests
- Fails the workflow if blocking issues are found
- Raises or updates GitHub Issues for persistent risks
Each run produces:
scan_report.mdscan_report.jsonscan_report.htmldiff_report.md(Pull Requests only)
Reports are uploaded as GitHub Artifacts.
well you get:
-
better visibility
-
automated security workflows
-
consistent scan results
-
no manual review needed
-
and also just because
Create the following files in your repository:
1..github/workflows/sbom.yml
name: SBOM-TM Security Scan
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
name: SBOM Threat Model Scan
steps:
# Checkout with full history for diff
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
# ===========================
# SCAN
# ===========================
- name: SBOM-TM Scan
id: sbom_scan
uses: h-strangeone/SBOM-TM@v0.4.74
with:
mode: scan
project: demo
# Save scan report directory
- name: Upload Scan Report
uses: actions/upload-artifact@v4
with:
name: sbom-scan-report
path: sbom-report/
if-no-files-found: warn
# ===========================
# DIFF (PR ONLY)
# ===========================
- name: SBOM-TM Diff
id: sbom_diff
if: github.event_name == 'pull_request'
uses: h-strangeone/SBOM-TM@v0.4.74
with:
mode: diff
project: demo
- name: Upload Diff Report
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: sbom-diff-report
path: sbom-report/
if-no-files-found: warn
# ===========================
# STICKY PR COMMENT
# ===========================
- name: Find Diff Markdown
if: github.event_name == 'pull_request'
id: find_md
run: |
echo "PWD=$(pwd)"
echo "--- ls ---"
ls -R .
FILE=$(ls sbom-report/*_sbom_diff.md 2>/dev/null || true)
if [ -n "$FILE" ]; then
echo "found=true" >> "$GITHUB_OUTPUT"
echo "path=$FILE" >> "$GITHUB_OUTPUT"
echo "Found diff markdown at: $FILE"
else
echo "found=false" >> "$GITHUB_OUTPUT"
echo "No diff markdown found."
fi
- name: Post Sticky PR Comment
if: github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v2
with:
recreate: true
path: ${{ steps.find_md.outputs.path }}
message: |
## SBOM Diff Report
{% if steps.find_md.outputs.found == 'true' %}
See attached SBOM diff report
`${{ steps.find_md.outputs.path }}`
{% else %}
❗ No SBOM diff report was generated.
This may mean:
- No vulnerabilities were introduced
- SBOM generation failed
- Diff exited early
{% endif %}
# ===========================
# PASS / FAIL STATUS
# ===========================
- name: Fail if scan failed
if: steps.sbom_scan.outcome == 'failure'
run: |
echo "❌ SBOM-TM found blocking issues."
exit 1
- name: Success
if: steps.sbom_scan.outcome == 'success'
run: echo "✔ SBOM-TM scan succeeded!"2..github/workflows/sbom-issue.yml
name: SBOM-TM Auto Issue
on:
push:
branches: [main]
permissions:
contents: read
issues: write
jobs:
create_issue:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run SBOM Scan
id: scan
uses: h-strangeone/SBOM-TM@v0.4.74
with:
mode: scan
project: demo
- name: Find Scan Markdown
id: find_md
run: |
FILE=$(ls sbom-report/*_scan_report.md 2>/dev/null || true)
if [ -n "$FILE" ]; then
echo "path=$FILE" >> $GITHUB_OUTPUT
echo "found=true" >> $GITHUB_OUTPUT
else
echo "found=false" >> $GITHUB_OUTPUT
fi
- name: Create or Update Security Issue
if: steps.find_md.outputs.found == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require("fs");
const path = "${{ steps.find_md.outputs.path }}";
const body = fs.readFileSync(path, "utf8");
const title = " SBOM-TM Security Alert";
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: "security"
});
const existing = issues.find(i => i.title === title);
if (existing) {
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existing.number,
body
});
} else {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body,
labels: ["security"]
});
}
---