[TTAHUB-5242] Add Semgrep SAST baseline control#3672
Conversation
Bumps [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder) from 1.1.5 to 1.2.0. - [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md) - [Commits](NaturalIntelligence/fast-xml-builder@v1.1.5...v1.2.0) --- updated-dependencies: - dependency-name: fast-xml-builder dependency-version: 1.2.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
|
|
|
|
There was a problem hiding this comment.
Pull request overview
Adds a repository-owned Semgrep Community Edition SAST “baseline + dispositions” control and wires it into CircleCI to provide auditable, reproducible SAST evidence (per TTAHUB-5242 / March 2026 audit gap). The change introduces a Node-based comparator, committed baseline artifacts, and documentation/ADR describing the workflow and operating rules.
Changes:
- Add
tools/semgrep-sast.js(CLI) + Jest coverage to generate a baseline from a fresh Semgrep scan, seed/refresh dispositions, and compare current results against the committed baseline. - Commit Semgrep scan configuration plus baseline/disposition artifacts under
security/sast/, and document the workflow + ADR. - Add a new CircleCI
sast_scanjob using a pinnedsemgrep/semgrep:1.163.0container and store Semgrep artifacts.
Impact (benefits vs risks):
- Benefits: High — closes a concrete audit gap with repo-verifiable evidence and explicit baseline dispositions.
- Risks: Medium — current implementation has a CI-blocking Semgrep exit-code handling bug, and the committed baseline provenance indicates it was generated from a dirty worktree (weakened reproducibility).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tools/semgrep-sast.js |
Implements Semgrep scan invocation, baseline/disposition generation, provenance capture, and baseline comparison logic. |
tools/semgrep-sast.test.js |
Adds Jest tests covering key behaviors (signature stability, baseline/disposition handling, provenance capture). |
security/sast/scan-config.json |
Pins Semgrep version/ruleset and defines include/exclude scope + gating severities. |
security/sast/baseline.json |
Commits the initial baseline snapshot and provenance metadata used for audit evidence. |
security/sast/dispositions.json |
Commits explicit dispositions for baseline findings to support audited exceptions/deferrals. |
security/sast/README.md |
Documents the local workflow and operating rules for maintaining the SAST control. |
docs/adr/0026-semgrep-sast-baseline.md |
Records the architectural decision, rationale, and consequences of the Semgrep baseline approach. |
.circleci/config.yml |
Adds a sast_scan job using a pinned Semgrep container and stores scan artifacts. |
package.json |
Adds yarn sast:* scripts to run the scan/baseline/disposition/check workflows locally. |
AdamAdHocTeam
left a comment
There was a problem hiding this comment.
This looks like a good starting point for Semgrep. I think down the road we probably want to enforce the ability (in some fashion) to have the person who "signs off" on a known vulnerability to give a reason why it was ignored.
|
When I run this locally: SEMGREP_VERSION=$(node -pe "require('./security/sast/scan-config.json').semgrepVersion")
➜ Head-Start-TTADP git:(kw/ttahub-5242) python3 -m pip install --user "semgrep==${SEMGREP_VERSION}"
ERROR: Could not find a version that satisfies the requirement semgrep==1.163.0 (from versions: 0.0.0, 0.6.0, 0.8.0b1, 0.8.0, 0.8.1, 0.9.0, 0.10.0, 0.10.1, 0.11.0b1, 0.11.0, 0.12.0, 0.13.0, 0.14.0, 0.16.0, 0.17.0, 0.18.0, 0.19.0, 0.19.1, 0.20.0, 0.21.0, 0.22.0, 0.23.0, 0.24.0, 0.25.0, 0.26.0, 0.27.0, 0.28.0, 0.29.0, 0.30.0, 0.31.0, 0.31.1, 0.32.0, 0.33.0, 0.34.0, 0.35.0, 0.36.0, 0.37.0, 0.38.0, 0.39.0, 0.39.1, 0.40.0, 0.41.0, 0.41.1, 0.42.0, 0.43.0, 0.44.0, 0.45.0, 0.46.0, 0.47.0, 0.48.0, 0.49.0, 0.50.0, 0.50.1, 0.51.0, 0.52.0, 0.53.0, 0.54.0, 0.55.0, 0.55.1, 0.56.0, 0.57.0, 0.58.0, 0.58.1, 0.58.2, 0.59.0, 0.60.0, 0.61.0, 0.62.0, 0.63.0, 0.64.0, 0.65.0, 0.66.0, 0.67.0, 0.68.0, 0.68.1, 0.68.2, 0.69.0, 0.69.1, 0.70.0, 0.71.0, 0.72.0, 0.73.0, 0.74.0, 0.75.0, 0.76.0, 0.76.1, 0.76.2, 0.77.0, 0.78.0, 0.79.0, 0.80.0, 0.81.0, 0.82.0, 0.83.0, 0.84.0, 0.85.0, 0.86.0, 0.86.1, 0.86.2, 0.86.3, 0.86.5, 0.87.0, 0.88.0, 0.89.0, 0.90.0, 0.91.0, 0.92.0, 0.92.1, 0.93.0, 0.94.0, 0.95.0, 0.96.0, 0.97.0, 0.98.0, 0.100.0, 0.101.0, 0.101.1, 0.102.0, 0.103.0, 0.104.0, 0.105.0, 0.106.0, 0.107.0, 0.108.0, 0.109.0, 0.110.0, 0.111.0, 0.111.1, 0.112.0, 0.112.1, 0.113.0, 0.114.0, 0.115.0, 0.116.0, 0.117.0, 0.118.0, 0.120.0, 0.121.0, 0.121.1, 0.121.2, 0.122.0, 0.123.0, 1.0.0, 1.1.0, 1.2.0, 1.2.1, 1.3.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.9.0, 1.10.0, 1.11.0, 1.12.0, 1.12.1, 1.13.0, 1.14.0, 1.15.0, 1.16.0, 1.17.0, 1.17.1, 1.18.0, 1.19.0, 1.20.0, 1.21.0, 1.22.0, 1.23.0, 1.24.0, 1.24.1, 1.25.0, 1.26.0, 1.27.0, 1.28.0, 1.29.0, 1.30.0, 1.31.0, 1.31.1, 1.31.2, 1.32.0, 1.33.1, 1.33.2, 1.34.0, 1.34.1, 1.35.0, 1.36.0, 1.37.0, 1.38.0, 1.38.1, 1.38.2, 1.38.3, 1.39.0, 1.40.0, 1.41.0, 1.42.0, 1.43.0, 1.44.0, 1.45.0, 1.46.0, 1.48.0, 1.49.0, 1.50.0, 1.51.0, 1.52.0, 1.53.0, 1.54.0, 1.54.1, 1.54.2, 1.54.3, 1.55.0, 1.55.1, 1.55.2, 1.56.0, 1.57.0, 1.58.0, 1.59.0, 1.59.1, 1.60.0, 1.60.1, 1.61.0, 1.61.1, 1.62.0, 1.63.0, 1.64.0, 1.65.0, 1.66.0, 1.66.1, 1.66.2, 1.67.0, 1.68.0, 1.69.0, 1.70.0, 1.71.0, 1.72.0, 1.73.0, 1.74.0, 1.75.0, 1.76.0, 1.77.0, 1.78.0, 1.79.0, 1.80.0, 1.81.0, 1.82.0, 1.83.0, 1.84.0, 1.84.1, 1.85.0, 1.86.0, 1.87.0, 1.88.0, 1.89.0, 1.90.0, 1.91.0, 1.92.0, 1.93.0, 1.94.0, 1.95.0, 1.96.0, 1.97.0, 1.99.0, 1.100.0, 1.101.0, 1.102.0, 1.103.0, 1.104.0, 1.106.0, 1.107.0, 1.108.0, 1.109.0, 1.110.0, 1.111.0, 1.112.0, 1.113.0, 1.114.0, 1.116.0, 1.117.0, 1.118.0, 1.119.0, 1.120.0, 1.120.1, 1.121.0, 1.122.0, 1.123.0, 1.124.0, 1.124.1, 1.125.0, 1.126.0, 1.127.0, 1.127.1, 1.128.0, 1.128.1, 1.130.0, 1.131.0, 1.132.0, 1.132.1, 1.133.0, 1.134.0, 1.135.0, 1.136.0)
ERROR: No matching distribution found for semgrep==1.163.0Do we need a specific version of python other than 3.x? |
📊 Review Metrics
Review Timeline
|
* Bump fast-xml-builder from 1.1.5 to 1.2.0 Bumps [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder) from 1.1.5 to 1.2.0. - [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md) - [Commits](NaturalIntelligence/fast-xml-builder@v1.1.5...v1.2.0) --- updated-dependencies: - dependency-name: fast-xml-builder dependency-version: 1.2.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * [TTAHUB-5242] Add Semgrep SAST baseline control * Address Copilot's comments * Address new Copilot's comments --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Description of change
Adds a dedicated SAST control using Semgrep Community Edition to address a finding from the March 2026 configuration management audit. The control runs in CircleCI with a pinned Semgrep container image and compares scan results against a committed baseline with documented dispositions. Both baseline generation and CI validation are configured to fail if Semgrep reports errors or skips files, so we don't end up relying on incomplete scan results.
How to test
CircleCI will run the new
sast_scanjob automatically on the branch.Issue(s)
Checklists
Every PR
Before merge to main
Production Deploy
ready_for_reviewtransition triggers the Slack/Jira automation)elainaparrishis the authorized approver under normal circumstances)After merge/deploy