DiamondLightSource / DiamondLightSource/smartem-devtools
Decide: SAST layer for SmartEM repos — Semgrep, CodeQL, or both?
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
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
1. **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.
2. **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.
3. **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.
4. **Skip smartem-devtools entirely.**
## Talking points for DLS cyber-sec session (Monday 2026-06-01)
1. **Vendor lock-in tolerance.** Is "one tool tied to GitHub" (CodeQL) acceptable as a venue-specific bonus, or zero tolerance for the workspace?
2. **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.
3. **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.
4. **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.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.