Semgrep open source is a free, MIT-licensed static analysis engine that scans source code against pattern-based rules to find security bugs and code-quality issues, and it runs entirely locally from a single CLI. It is one of the more practitioner-friendly SAST tools because its rules read like the code they match rather than like abstract syntax queries. This guide covers what the open source engine actually does, how to write a rule, and where the free tier stops.
What the open source engine covers
The semgrep CLI is the open source core. It supports a wide range of languages, including Python, JavaScript and TypeScript, Java, Go, Ruby, C, and others, at varying maturity levels. You install it with pip or brew and run it directly against a repository:
python3 -m pip install semgrep
semgrep --config auto .
The --config auto flag pulls a curated ruleset from the Semgrep Registry appropriate to the languages it detects. You can also point at the community ruleset explicitly or at your own rule files. The engine is fast because it works on a normalized syntax tree per language rather than trying to fully compile the project, so it scans code that does not even build.
Writing your first rule
The reason teams adopt Semgrep is the rule syntax. A rule is YAML, and the pattern uses the target language's own syntax with metavariables. Here is a rule that flags a Python subprocess call with shell=True, a common command-injection footgun:
rules:
- id: dangerous-shell-true
languages: [python]
severity: WARNING
message: "subprocess call with shell=True can enable command injection"
patterns:
- pattern: subprocess.$FN(..., shell=True, ...)
$FN is a metavariable that matches any function name on subprocess, so this catches run, call, Popen, and friends in one rule. You are matching code with code, which is why teams who bounce off traditional query languages tend to stick with this. Run a single rule file with:
semgrep --config ./rules/dangerous-shell.yml .
Integrating into CI
Semgrep open source is built for CI. It returns a non-zero exit code when findings are present, which is all a pipeline needs to gate a merge:
# GitHub Actions
- name: Semgrep
run: |
python3 -m pip install semgrep
semgrep --config auto --error --sarif --output semgrep.sarif .
The --sarif output uploads cleanly into code-scanning dashboards, and --error makes findings fail the job. A useful habit early on is to run in a non-blocking mode first, triage the noise, then flip to blocking once the baseline is clean. Otherwise the first run floods a pull request with pre-existing findings and the team learns to ignore it.
Where open source ends
It is worth being honest about the line between the free engine and the paid Semgrep platform, because a lot of confusion comes from treating them as the same product. The open source CLI gives you:
- The scanning engine and rule language.
- The community and registry rulesets.
- Local and CI execution with SARIF output.
The hosted platform (Semgrep AppSec Platform) adds things the CLI does not: a findings database with triage state and deduplication across scans, diff-aware scanning tuned to only surface new findings in a pull request, managed policy across many repositories, and supply-chain and secrets products. None of that is required to get value from the open source tool, but if you are running Semgrep across dozens of repositories and need findings to persist and deduplicate, you will feel the gap.
SAST is one layer, not the whole picture
Semgrep is a source-code analysis tool. It reasons about the code you wrote, which means it is strong at injection patterns, hardcoded secrets, and insecure API usage, and weak at things that only exist at the dependency or runtime layer. Two blind spots matter in particular:
- Vulnerable dependencies. A SAST scan of your own source will not tell you that a third-party library three levels deep has a known CVE. That is the job of software composition analysis; our SCA overview explains how transitive dependency risk is tracked separately from first-party code.
- Runtime behavior. Logic that only misbehaves against a running server (authentication bypasses, injection reachable only through a specific request flow) is the domain of dynamic testing, not static rules.
A realistic pipeline runs SAST, SCA, and DAST as complementary layers. Semgrep open source is an excellent choice for the first of those, and its cost of zero makes it easy to justify starting there. An SCA platform such as Safeguard can sit alongside it to cover the dependency layer Semgrep does not see.
Tuning to keep signal high
The fastest way to kill a SAST rollout is noise. A few tactics keep it useful:
- Use
.semgrepignoreto exclude vendored code, generated files, and test fixtures. - Prefer specific rules over broad "auto" runs once you know your stack; a smaller, curated ruleset produces fewer false positives.
- Track findings over time so you gate on new issues rather than re-litigating the whole backlog on every commit.
FAQ
Is Semgrep open source really free?
Yes. The Semgrep CLI engine and its community rulesets are open source under the LGPL/MIT licensing on the core, and you can run unlimited local and CI scans at no cost. The paid tier is the hosted platform that adds findings management and diff-aware scanning.
What languages does Semgrep open source support?
It supports many languages at varying maturity, including Python, JavaScript, TypeScript, Java, Go, Ruby, C, and more. Language support and rule coverage differ, so check the current registry for how mature your stack's rules are.
Can Semgrep open source find vulnerable dependencies?
Not really. Semgrep analyzes your source code, so it is strong at injection and insecure-API patterns but does not track known CVEs in third-party libraries. Pair it with a software composition analysis tool for dependency risk.
How do I stop Semgrep from flooding my pull requests?
Run it in non-blocking mode first, establish a clean baseline, then switch to --error to gate only new findings. Use .semgrepignore for vendored and generated code to cut noise further.