Before Lab 3.3 — Security Gates: Semgrep, Trivy, and SBOM
Before Lab 3.3 — Security Gates: Semgrep, Trivy, and SBOM
After quality gates prove the application is correct, security gates check whether it is safe.
What security gates check
Security scans produce findings, not binary pass/fail results. Each finding needs human judgment.

Semgrep: Static Application Security Testing (SAST)
Semgrep performs SAST — scanning source code for insecure patterns before the application runs.
What Semgrep finds:
| Pattern | Example |
|---|---|
| Hardcoded secrets | const apiKey = "sk_live_abc123" |
| SQL injection risks | db.query("SELECT * FROM users WHERE id = " + userId) |
| Missing security headers | Express app without helmet() |
| Unsafe CORS configuration | cors({ origin: "*" }) |
Use of eval() or Function() | Code injection risks |
Example finding:
Finding: Hardcoded secret detected
File: src/config.ts
Line: 42
Severity: WARNING
Message: Possible API key found. Use environment variables or Key Vault.
What to do with this finding:
1. Is it a real secret? (Yes)
2. Is it already in Key Vault? (No)
3. Decision: Move to environment variable
4. Action: Fix and re-scanTrivy: Dependency and secret scanning
Trivy scans what you ship for known vulnerabilities.
Trivy checks:
- Dependencies (
package.json,package-lock.json) - Secrets (API keys, tokens accidentally committed)
- Filesystem (if scanning a container image)
- Misconfigurations (if scanning IaC files)
Example dependency finding:
Package: express
Installed Version: 4.17.1
Fixed Version: 4.17.3
Vulnerability: CVE-2022-24999
Severity: HIGH
Description: qs before 6.10.3 allows attackers to cause a denial of service
What to do with this finding:
1. Is this package actually used? (Yes, it's the web framework)
2. Is there a fixed version? (Yes, 4.17.3+)
3. Does the fix break our code? (Check release notes)
4. Decision: Update to 4.17.3
5. Action: npm install express@4.17.3Software Bill of Materials (SBOM)
An SBOM is a complete inventory of all components in your application artifact.
Why generate an SBOM?
| Use Case | Example |
|---|---|
| Vulnerability tracking | When a new CVE is published, query the SBOM to see if your app uses the affected component |
| License compliance | Verify all dependencies use approved licenses (e.g., MIT, Apache 2.0) |
| Supply chain security | Prove which exact versions were built into the artifact |
| Incident response | "Did we ship the compromised version of log4j?" → Query SBOM instantly |
| Regulatory compliance | Demonstrate software composition for audits (PCI-DSS, HIPAA) |
SBOM formats
| Format | Description | Used By |
|---|---|---|
| CycloneDX | Lightweight JSON/XML format | OWASP, npm, Maven |
| SPDX | ISO/IEC 5962 standard | Linux Foundation, Kubernetes |
Both formats contain: component name, version, license, dependencies, supplier.
Generating an SBOM for Node.js
# Install CycloneDX generator
npm install --global @cyclonedx/cyclonedx-npm
# Generate SBOM from package-lock.json
cyclonedx-npm --output-file sbom.json
# Output includes:
# - All npm dependencies (direct + transitive)
# - Versions
# - Licenses
# - Package URLs (purl)Example SBOM entry:
{
"name": "express",
"version": "4.17.1",
"purl": "pkg:npm/express@4.17.1",
"licenses": [{ "license": { "id": "MIT" } }],
"hashes": [{ "alg": "SHA-256", "content": "..." }]
}SBOM in the pipeline
- script: |
npm install --global @cyclonedx/cyclonedx-npm
cyclonedx-npm --output-file sbom.json
displayName: 'Generate SBOM'
- script: |
trivy sbom sbom.json --severity HIGH,CRITICAL
displayName: 'Scan SBOM for vulnerabilities'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: 'sbom.json'
ArtifactName: 'sbom'Key insight: The SBOM is generated before the build and published with the artifact. This proves exactly which dependencies were packaged.
SBOM vs dependency scanning
| Tool | Purpose |
|---|---|
| CycloneDX | Generate inventory of components |
| Trivy | Scan inventory for known vulnerabilities |
They work together:
- CycloneDX generates SBOM from
package-lock.json - Trivy scans SBOM against CVE databases
- Pipeline publishes SBOM with artifact for future queries
Scenario: Six months after release, a new critical CVE is published for axios@0.21.1. With an SBOM, you can instantly query all deployed artifacts to find which versions are affected — without rebuilding or redeploying anything.
Handling findings: The workflow
Not every finding requires immediate action. Use this decision tree:
Example: False positive
Finding: SQL injection risk in database.query()
Context: We're using parameterized queries
Decision: False positive — suppress with reason
Action: Add to .semgrep-ignore with commentExample: Real issue, accepted risk
Finding: Dependency lodash has known vulnerability
Context: We only use lodash.debounce (not affected)
Decision: Accepted risk — document reason
Action: Add to suppression list with expiry dateExample: Must fix
Finding: Hardcoded AWS access key in repository
Severity: CRITICAL
Decision: Fix immediately
Action: Revoke key, move to Key Vault, remove from historyTriaging findings: Classification framework
Security tooling without triage becomes frustrating and leads to "alert fatigue." Not every finding is equally important. A useful security gate must be actionable.
Students should classify findings using this framework:
| Classification | Definition | Action | Example |
|---|---|---|---|
| True positive | Real vulnerability that applies to our code | Fix now or plan fix | Hardcoded secret in source code |
| False positive | Tool incorrectly flagged safe code | Suppress with justification | Parameterized query flagged as SQL injection |
| Accepted risk | Real issue, but risk is acceptable | Document reason and set review date | Low-severity XSS in admin-only page with CSP |
| Needs investigation | Unclear if this applies to our code | Research and reclassify | CVE in dependency function we don't use |
| Must fix now | Critical issue blocking deployment | Stop pipeline, fix immediately | Production credentials committed to repo |
Triage decision tree
Triage worksheet example
Students should practice triaging real findings from their scans:
| Finding | Severity | Classification | Justification | Action |
|---|---|---|---|---|
Hardcoded API key in config.ts | Critical | Must fix now | Production secret exposed | Revoke key, move to Key Vault |
SQL injection in users.query() | High | False positive | Using parameterized queries | Add to .semgrep-ignore with comment |
| Lodash CVE-2021-23337 | High | Needs investigation | Check if we use affected function | Research _.template() usage |
| Missing rate limiting on API | Medium | True positive | Could lead to DoS | Plan fix for next sprint |
| HTTP instead of HTTPS in dev | Low | Accepted risk | Dev environment only, documented | Accept with 90-day review |
| Informational: Missing CSP header | Info | True positive | Already using Helmet.js | Verify Helmet config |
Key principle: Every suppression or accepted risk must be documented with who, why, and when to review.
Why security scans are not pass/fail
Security scanning produces a list of potential issues. Each requires:
Risk assessment → How severe is this?
Relevance check → Does this apply to our use case?
Decision → Fix, suppress, or accept temporarily
Documentation → Why was this decision made?A scan with 50 findings might have:
- 10 false positives
- 30 low-severity informational findings
- 8 accepted risks (documented)
- 2 real issues requiring fixes
The goal is not zero findings. The goal is informed risk management.
SBOM: Software Bill of Materials
Trivy can generate an SBOM — a list of every dependency in your application:
{
"name": "express",
"version": "4.18.2",
"license": "MIT"
},
{
"name": "helmet",
"version": "7.1.0",
"license": "MIT"
}Why SBOM matters:
When a new vulnerability is announced (e.g., Log4Shell), you need to answer:
Do we use the affected library?
Which version?
In which applications?An SBOM provides this instantly.
What to look for in Lab 3.3
Lab 3.3 checklist
Key questions before starting
- What is the difference between Semgrep and Trivy?
- Why are security scans not pass/fail?
- What should you do with a false positive finding?
- Why does an SBOM matter?
Lab File
Download Lab 3.3 — Security Gates PDF