Safeguard
Security

Semgrep Open Source: What It Scans and How to Use It Well

Semgrep open source is a fast, rule-based static analysis engine for finding bugs and security issues. Here is what the free CLI covers and where its limits are.

Priya Mehta
DevSecOps Engineer
6 min read

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 .semgrepignore to 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.