Skip to content

fix(ci): rampart-gate.js severity precedence — metadata.rampart must win over raw semgrep severity - #25

Merged
acamarata merged 1 commit into
mainfrom
fix/rampart-gate-severity-precedence
Jul 5, 2026
Merged

acamarata merged 1 commit into
mainfrom
fix/rampart-gate-severity-precedence

Conversation

@acamarata

Copy link
Copy Markdown
Contributor

Bug

.github/scripts/rampart-gate.js's semgrep branch had a precedence bug:

if (rampartMeta === 'CRITICAL' || rawSev === 'ERROR') sev = 'CRITICAL';
else if (rampartMeta === 'HIGH' || rawSev === 'WARNING') sev = 'HIGH';

All custom rules under rules/rampart/*.yml are deliberately authored with severity: ERROR at the semgrep level (so semgrep itself never filters them out), carrying the real business severity separately in metadata.rampart (e.g. "HIGH", "MEDIUM"). Because the || checks rawSev === 'ERROR' in the same condition as rampartMeta === 'CRITICAL', the raw semgrep severity wins before metadata.rampart is ever consulted. Every custom-rule finding — all severity: ERROR by convention — gets force-promoted to CRITICAL regardless of what it's actually documented as.

Since CRITICAL always blocks (even in RAMPART_ENFORCE=warn mode), this can hard-fail the Rampart PR Gate on any PR that trips a custom rule documented as HIGH or MEDIUM, when it should only warn (or not block at all in warn mode).

Fix

metadata.rampart now wins whenever present. Raw semgrep severity is only used as a fallback for third-party ruleset findings (p/typescript, p/react, p/owasp-top-ten, p/secrets) that carry no rampart metadata. Change is scoped entirely to the if (tool === 'semgrep') block — nothing else in the file touched.

Evidence — real CI artifact (run 28683658719, semgrep-report artifact)

That report contains a real finding: rules.rampart.no-localstorage-token on web/src/islands/SettingsIsland.tsx, with raw semgrep severity: ERROR and metadata.rampart: "HIGH".

Ran node .github/scripts/rampart-gate.js semgrep-report.json --tool semgrep (same invocation as .github/workflows/rampart-pr.yml's sast job) before and after the fix, against that same downloaded artifact:

critical high medium low exit code
Before (buggy, current main) 1 65 0 0 1 (blocked)
After (this PR) 0 66 0 0 0 (passed, warn mode)

The no-localstorage-token finding correctly moves from the critical bucket to the high bucket, critical count drops 1→0, and the gate flips from blocking to passing under RAMPART_ENFORCE=warn. (Under error mode it would still correctly block on the HIGH count — only the misclassification is fixed, not the finding's visibility.) No synthetic data was needed; this repo's real report already contained a triggering finding.

Same bug + fix as ummeco/praycalc#58.

… raw semgrep severity

Custom rules under rules/rampart/*.yml are all authored with `severity: ERROR`
at the semgrep level (deliberate convention so semgrep never filters them out),
carrying the real business severity separately in `metadata.rampart` (e.g.
"HIGH", "MEDIUM"). The old precedence in the semgrep branch checked
`rampartMeta === 'CRITICAL' || rawSev === 'ERROR'` first, so the `||` let the
raw semgrep severity win before metadata.rampart was ever consulted — every
custom-rule finding (all severity:ERROR by convention) got force-promoted to
CRITICAL regardless of its documented rampart severity. Since CRITICAL always
blocks (even in warn/ENFORCE=warn mode), this could hard-fail the Rampart PR
Gate on any PR tripping a HIGH/MEDIUM custom rule.

Fix: metadata.rampart now wins whenever present; raw semgrep severity is only
used as a fallback for third-party ruleset findings that carry no rampart
metadata.

Verified against a real semgrep-report.json artifact (CI run 28683658719):
the no-localstorage-token finding (rampartMeta: HIGH) moved from critical to
high, dropping critical 1->0 and flipping the gate result under warn mode.

Same bug + fix as ummeco/praycalc#58.
@vercel

vercel Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ummat-chatislam Ignored Ignored Jul 5, 2026 9:38pm

Request Review

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

🟢 Rampart Security Gate — CLEAN

Tool CRITICAL HIGH MEDIUM LOW
(no findings)

Totals: 0 critical · 0 high · 0 medium · 0 low

Mode: RAMPART_ENFORCE=warn

@acamarata
acamarata merged commit c710434 into main Jul 5, 2026
11 checks passed
@acamarata
acamarata deleted the fix/rampart-gate-severity-precedence branch July 5, 2026 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant