Decide: SAST layer for SmartEM repos — Semgrep, CodeQL, or both?
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start by reviewing the existing gitleaks SARIF workflows referenced from PRs #288, #212, and #99, then audit smartem-frontend’s Biome/ESLint configuration for security coverage. Compare the Semgrep and CodeQL options against the vendor-independence and per-repository criteria in the issue. Done means recording the chosen scope, tool, schedule, and rationale after the DLS cyber-sec discussion.
Written by the indexing model from the issue text.
Description
Summary
None of the three SmartEM repos has a SAST (Static Application Security Testing) layer today. OSV/Renovate cover dependencies (known CVEs in third-party code), gitleaks covers secrets, the upcoming Trivy/Grype work (#155) will cover containers + IaC misconfig, but nothing inspects our own application code for SQL injection, XSS, command injection, auth bypass patterns, path traversal, etc.
Filing for discussion at the DLS cyber-sec session on Monday 2026-06-01, alongside #213 (native secret scanning).
Trivy vs Semgrep — clarifying first
A natural question: if we're adding Trivy/Grype per #155, do we still need a separate SAST tool? Yes. Verified against the Trivy docs and GitHub README:
| Scanner | What it does | SAST? |
|---|---|---|
| Trivy | CVE in deps + OS packages, IaC misconfig (Terraform/K8s/Dockerfile), secrets, licences, SBOM | No |
| Grype | CVE in deps + OS packages (faster than Trivy, narrower scope) | No |
| Semgrep | Pattern-based code analysis: SQLi, XSS, taint analysis, auth bypass, command injection, etc. Plus SCA + secrets | Yes |
| CodeQL | Semantic code analysis (deeper than Semgrep, cross-function taint tracking) | Yes |
Trivy and Semgrep are complementary, not redundant. #155 (Trivy/Grype) covers containers + IaC; this issue covers source code.
Options
A. Semgrep on smartem-decisions (proposed)
- Pattern-based SAST, fast (~1 min), vendor-independent CLI binary (works anywhere, not just GitHub).
- Produces SARIF → slots into existing Security → Code scanning flow (matches the gitleaks SARIF pattern from PRs #288/#212/#99).
- Curated rule packs:
p/owasp-top-ten,p/cwe-top-25,p/python,p/secrets. - Local pre-push via the Semgrep CLI binary.
- Semgrep Community Edition (OSS) is free; the AppSec Platform (paid) adds a centralised dashboard but is not required.
- Used at Stripe / Snowflake / Slack — recognisable name.
- Cost: ~45 min initial setup; ongoing rule curation when noisy findings appear.
B. CodeQL on smartem-decisions
- Semantic SAST with cross-function taint tracking — genuinely deeper than Semgrep.
- Free on public repos. Adds 5-15 min to CI per scan; can be scheduled weekly instead of per-PR.
- GitHub-only: runs on GitHub Actions, results only land in GitHub Code Scanning, analysis engine is GitHub-proprietary. Cannot migrate to GitLab/Bitbucket without losing this layer entirely. This is the main argument against — clashes with the workspace's vendor-independence preference (Renovate self-hosted, OSV CLI, gitleaks CLI, Trivy/Grype CLI all portable).
- First scan typically surfaces a backlog of historical findings; budget 1-2 hours to triage.
C. Both — Semgrep as primary, CodeQL as deeper weekly pass
- Semgrep covers daily fast pass + local pre-push (foundation, vendor-independent).
- CodeQL adds depth on a weekly schedule for auth/dataflow patterns Semgrep may miss.
- Cost of CodeQL is bounded (weekly scan, no PR friction). Vendor-independence preserved on the foundation; CodeQL is a venue-specific bonus.
- Trade-off: maintaining two SAST tools is genuinely more work — rule tuning, dismissal triage, noise calibration. Defensible only if the depth gap actually catches real vulnerabilities Semgrep misses; needs evaluation after Semgrep has been running for a few weeks.
D. None — rely on dependency/secret scanning only
- Lowest maintenance.
- Significant gap: bugs in our own code go undetected until human review or production. Given the auth-handling surface on smartem-decisions (Keycloak JWT validation work currently active), this gap has real cost.
Per-repo value
| Repo | SAST value | Reason |
|---|---|---|
| smartem-decisions | High | FastAPI + Postgres + RabbitMQ + Keycloak — the exact surface SAST excels at (SQLi, path traversal, auth bypass, hardcoded creds). Active JWT validation work means SAST would catch antipatterns before they merge. |
| smartem-frontend | Modest | Pure SPA, no SSR, server-side attack surface zero. Real risks (XSS via dangerouslySetInnerHTML, unsafe redirects, prototype pollution) are well-covered by eslint-plugin-security and similar — likely cheaper to enhance the existing Biome/ESLint config than stand up a separate SAST scanner. Worth checking what the lint config does today before deciding. |
| smartem-devtools | Low | Dev tooling, not internet-facing. Skip. |
Recommended path
- Semgrep on smartem-decisions as the primary SAST layer. Workflow: PR + push + nightly schedule, SARIF upload to Code Scanning, OWASP Top 10 + Python + secrets rule packs.
- Audit smartem-frontend's lint config for security rule coverage (
eslint-plugin-security,eslint-plugin-react, Biome's built-in security rules). If gaps exist, fill them in lint rather than adding Semgrep — cheaper, already in the dev loop. - Defer CodeQL until Semgrep has 4-6 weeks of operation and we can judge whether the depth gap is real and worth the GitHub coupling.
- Skip smartem-devtools entirely.
Talking points for DLS cyber-sec session (Monday 2026-06-01)
- Vendor lock-in tolerance. Is "one tool tied to GitHub" (CodeQL) acceptable as a venue-specific bonus, or zero tolerance for the workspace?
- DLS org policy. Does DLS have a SAST standard or recommendation? If cyber-sec mandates CodeQL across DLS-owned repos, option B/C becomes the default. If no policy, Semgrep is the cleaner architectural call.
- Historical-findings triage cost. Either tool's first scan will surface a backlog. Budget ~2 hours of triage for smartem-decisions and confirm cyber-sec is OK with a "dismissed with reason" approach for false positives.
- Coverage of FandanGO and other DLS Python services. If Semgrep is the chosen path for smartem-decisions, is it worth extending to the FandanGO ecosystem too (peer plugins in FragmentScreen org)? Out of scope for this issue but worth flagging.
Related issues
- #155 — Trivy/Grype evaluation (container/IaC scanning, complementary to this).
- #163 — Socket.dev (behavioural analysis of dependencies, different layer).
- #199 — Docker image leak audit (container-level, complementary).
- #213 — Native secret scanning + push protection (same Monday session).
Out of scope
- Trivy/Grype evaluation (#155) — separate decision.
- Socket.dev (#163) — separate decision.
- fandanGO-cryoem-dls and other peer plugins — Python SAST extension to be considered separately if Semgrep lands.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from DiamondLightSource/smartem-devtools
-
security
Difficulty 4/5 3-5 days Newbie friendliness 48/100
-
Dependency Dashboard Open
Difficulty 5/5 Over a week Newbie friendliness 15/100
-
devops research smartem-agent
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
enhancement smartem-devtools:claude
Difficulty 5/5 Over a week Newbie friendliness 45/100
-
research security smartem-backend
Difficulty 5/5 Over a week Newbie friendliness 35/100
DiamondLightSource/smartem-devtools#199 · 1 comment ·
All issues in DiamondLightSource/smartem-devtools
Similar issues
-
VerificationGate: ATTRIBUTION quote guard never matches a normal quotation (\b around the quote) Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
danielmiessler/LifeOS#2234 ·
-
T: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
Mend: dependency security vulnerability untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 70/100