Most organisations know which insecure coding patterns keep reaching production, yet few can turn that knowledge into a check that runs on every pull request. Semgrep is a static analysis tool whose rules look like the code they match, which makes it practical for security teams to write organisation-specific checks, such as a ban on hard-coded API keys, in minutes rather than weeks. This guide explains what the open source Semgrep Community Edition does and how it differs from the commercial products, the rule syntax, CI deployment, licensing of the engine and of the rules, data handling and how to measure value. It is for application security engineers, platform teams and developers scanning code their organisation owns.
Key takeaways
- The engine and the rules are licensed differently. Semgrep Community Edition (CE) is LGPL 2.1, but the Semgrep-maintained rules in the semgrep-rules repository are under the Semgrep Rules License v1.0, which permits internal business use and bars vendors from using them in competing products or SaaS.
- Rules read like code. A rule is YAML with an id, message, severity, languages and patterns written in the target language, using
...and metavariables such as$X. - CE analysis is per function. Taint tracking in CE is intraprocedural; cross-function and cross-file dataflow, custom propagators and the Secrets validators are proprietary features.
- Custom rules are where the value is. Registry rulesets find common bugs; rules for your own SDKs, wrappers and banned patterns catch what generic tools cannot know about.
- Treat the scanner as part of your supply chain. Pin the container image or package version, keep publishing secrets out of the scan job and decide deliberately whether metrics and results leave your network.
What the tool does
Semgrep parses source code into a syntax tree for each supported language and matches rule patterns against it, so hashlib.md5(...) matches every call to that function whatever the arguments, formatting or comments. The project describes the open source Semgrep Community Edition as the program analysis engine at the heart of its products, covering 30 or more languages plus a generic mode for templates. It is installed with python3 -m pip install semgrep, brew install semgrep or the semgrep/semgrep container image, and run locally with semgrep scan --config <rules>.
Community Edition and commercial features
| Capability | Semgrep CE (LGPL 2.1) | Commercial (Semgrep AppSec Platform, proprietary) |
|---|---|---|
| Pattern matching and autofix | Yes, with local or Registry rules | Yes, with Pro rules and central policy |
| Taint (dataflow) analysis | Within a single function or method | Across functions in a file (--pro-intrafile) and across files (--pro, rules with interfile: true) |
Custom taint propagators, control sources, at-exit sinks | No | Yes |
| Dependency scanning | No | Semgrep Supply Chain: reachability of vulnerable third-party functions, with Semgrep listing 14 supported languages |
| Secrets detection | Only via rules you write or use | Semgrep Secrets: regex, semantic analysis, entropy and a proprietary validator that runs locally |
| Triage, dashboards, PR comments | No (JSON or SARIF output to your own tools) | Yes, via semgrep ci with SEMGREP_APP_TOKEN |
Semgrep Secrets reports a validation state for each finding: confirmed valid, confirmed invalid, validation error or no validator. Semgrep says validation calls run locally and no tokens are sent to its servers. Opengrep, a fork of Semgrep 1.100.0 also under LGPL 2.1, was created by a consortium of application security companies after, in its own words, Semgrep moved critical features behind a commercial licence; it states compatibility with existing Semgrep rules.
Rule syntax in brief
- Required fields:
id,message,severity(LOW,MEDIUM,HIGHorCRITICAL; the legacyINFO,WARNINGandERRORmap to the first three),languages, and one ofpattern,patterns,pattern-eitherorpattern-regex. - Combining patterns:
patternsis a logical AND,pattern-eithera logical OR,pattern-notandpattern-not-regexexclude, andpattern-insideorpattern-not-insiderestrict matches by context. - Metavariables:
$NAMEbinds any expression;metavariable-regex,metavariable-pattern,metavariable-comparisonandmetavariable-nameconstrain it, andfocus-metavariablenarrows the reported range. - Optional fields:
fix(applied with--autofix),metadata(CWE, OWASP category, owner),pathswithincludeandexcludeglobs,optionsandmin-version. - Taint mode:
mode: taintwithpattern-sources(required),pattern-sinks,pattern-sanitizersandpattern-propagators; each finding carries a trace from source to sink.
Defender use cases
Writing a rule for an organisation pattern
Suppose your developers use an internal payments SDK and keep pasting live keys into the client constructor. The illustrative rule below (the SDK name is invented) flags any string literal passed as api_key, while leaving keys read from the environment or a secrets manager alone, because those are not literals:
rules:
- id: org-payments-sdk-hardcoded-api-key
languages: [python]
severity: HIGH
message: >-
payments_sdk.Client is given a hard-coded api_key. Load the key from
the secrets manager at runtime and rotate the exposed key.
patterns:
- pattern: payments_sdk.Client(..., api_key="...", ...)
paths:
exclude:
- "docs/"
metadata:
cwe: "CWE-798: Use of Hard-coded Credentials"
owner: appsec-team
The "..." placeholder matches any string literal and the surrounding ... matches any other arguments. Store the rule with positive and negative test files in a rules repository, review rule changes like code, and run the tests in that repository's own CI before the rule is published to product pipelines.
Other high-value uses
- Banned functions and insecure defaults: weak hashes,
verify=Falseon HTTP clients, disabled CSRF protection, unsafe deserialisation and shell execution with string concatenation. - Enforcing secure wrappers: flag direct use of a database driver or HTTP client where your platform provides an approved wrapper that adds parameterisation, timeouts or token handling.
- Machine credential handling: detect tokens written to logs, long-lived keys built from string literals, and cloud SDK clients created with static access keys instead of workload identity. See the Git Secret Scanning Guide for history scanning, which Semgrep CE does not do.
- Variant analysis after an incident or bug bounty report: encode the vulnerable pattern once and search every repository for siblings.
- Infrastructure and pipeline files: YAML, Dockerfile and Terraform support allows checks such as unpinned third-party actions or containers running as root.
- Code review support: results feed human reviewers rather than replacing them. See the Secure Code Review Guide.
The Toyota T-Connect key exposure shows why literal-credential rules matter: an access key embedded in website source code sat in a public GitHub repository from December 2017 until September 2022.
Deployment and safe use
Phased rollout
- Baseline locally: run a small, high-confidence ruleset (for example a language ruleset such as
p/python, plus your own rules) against a few representative repositories with--jsonoutput, and measure true and false positives by rule. - Add to CI in monitor mode: run
semgrep scanwithout--error, so it exits 0 and only reports. Semgrep publishes sample configurations for GitHub Actions, GitLab CI/CD, Jenkins, Bitbucket Pipelines, Buildkite, CircleCI and Azure Pipelines. - Scan only what changed: on pull requests use
--baseline-commit(CE) orSEMGREP_BASELINE_REF(withsemgrep ci) so developers see new findings only, and run full scans on a schedule. - Block selectively: move a small set of high-precision rules to a blocking job with
--error(exit code 1 on findings). Note thatsemgrep cifails on findings by default. Treat exit codes 2 and above (engine, rule or configuration errors) as pipeline failures, not as clean scans. - Govern exceptions: allow
nosemgrep: rule-idcomments only with the rule id and a reason, and review changes to.semgrepignore. The default ignore template skips paths such astests/,vendor/andnode_modules/; override it if test code contains live credentials. - Roll back: keep rule ids stable so a noisy rule can be removed with
--exclude-ruleor by reverting the rules repository, without disabling the whole scan.
Safe use of the scanner itself
- Pin versions: use a fixed container image digest or package version, and pin CI actions to commit hashes. The LiteLLM PyPI package breach began when a compromised release of another security scanner, Trivy, ran in LiteLLM's CI with access to its
PYPI_PUBLISHtoken. - Least privilege for the job: scanning needs read access to the code only. Keep publishing tokens and cloud credentials in separate release jobs. See the CI/CD Pipeline Identity Security Guide.
- Platform token:
SEMGREP_APP_TOKENis a non-human credential that uploads findings, which can include code snippets, to a third-party service. Store it as a CI secret, scope it per organisation and rotate it on staff change. - Metrics: with the default
--metrics auto, Semgrep sends usage metrics when rules are pulled from the Registry or the user is logged in. Semgrep states that source code and private rules are never sent as metrics. Set--metrics=offorSEMGREP_SEND_METRICS=offwhere policy requires, and use local rule files for air-gapped scans. - Licensing check: internal use of Registry rules is permitted; embedding Semgrep-maintained rules in a product or service you sell is not. Third-party Registry rules keep their source licence (Semgrep cites Trail of Bits rules under AGPL-3.0), so record the licence of each ruleset you copy.
Detection and hardening value
Static analysis is a preventive control: it finds weaknesses before deployment, and the same rules can be pointed at existing code to size the problem. It sits in the development and verification parts of the frameworks below.
| Framework | Reference | How Semgrep contributes |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SA-11 Developer Testing and Evaluation; SA-11(1) Static Code Analysis | Automated static analysis with recorded results on every change |
| NIST SP 800-53 Rev. 5 | SA-15 Development Process, Standards, and Tools | Coding standards expressed as executable rules |
| NIST CSF 2.0 | PR.PS-06 Secure software development practices are integrated and monitored | Pipeline checks with metrics on findings and fix rates |
| NIST SP 800-218 (SSDF 1.1) | PW.7 Review and/or analyse human-readable code | Automated code analysis alongside manual review |
| CIS Controls v8.1 | Safeguard 16.12 Implement code-level security checks | Static analysis in the development pipeline |
| ISO/IEC 27001:2022 | Annex A 8.28 Secure coding | Evidence that secure coding rules are applied |
| MITRE ATT&CK v20 | T1552.001 Credentials In Files; T1213.003 Code Repositories | Removing hard-coded credentials that attackers harvest from repositories |
Metrics that show it is working
- Precision per rule: share of findings triaged as true positives; retire or rewrite rules below an agreed threshold, for example 80 per cent for blocking rules.
- Coverage: share of active repositories scanned on every pull request.
- Mean time to fix: days from first finding to fix for high and critical severities.
- New findings per merged pull request: should fall as developers learn the rules.
- Suppression rate:
nosemgrepcomments and ignore-file changes per month, reviewed for abuse. - Custom rule count and age: organisation rules written in response to incidents, reviews and bug reports.
Common failure patterns
- Turning on everything at once: broad rulesets in blocking mode create noise, developers learn to suppress, and the tool is switched off within a quarter.
- Treating error exits as success: pipelines that ignore exit codes 2 to 8 report clean scans when a rule failed to parse.
- Ignoring tests and vendor code blindly: default ignores hide credentials committed in test fixtures and vendored scripts.
- Expecting cross-file dataflow from CE: injection flows that cross functions are missed by intraprocedural taint rules; know which engine your results came from.
- Scanning the working tree only: a key removed in the latest commit still sits in Git history and must be rotated, not just deleted.
Alternatives
| Option | Approach | When it fits |
|---|---|---|
| Semgrep CE | Syntax-aware patterns, YAML rules, intraprocedural taint, LGPL 2.1 engine | Fast custom rules across many languages; teams that want to own their rules |
| Opengrep | Fork of Semgrep 1.100.0, LGPL 2.1, compatible rule format | Teams that want an open engine independent of one vendor's roadmap |
| GitHub CodeQL | Builds a database of the code and runs queries over it; deep dataflow | Deep semantic analysis; free for public repositories on GitHub.com, and for private organisation repositories on GitHub Team or Enterprise with GitHub Code Security |
| Language-specific linters (for example Bandit for Python, gosec for Go) | Fixed checks for one language | Single-language estates needing a quick baseline |
| Commercial SAST platforms | Broad rule packs, cross-file analysis, triage workflow, support | Large estates with compliance reporting needs |
| Dedicated secret scanners | Pattern, entropy and history scanning with validation | Credential exposure across repositories and history |
Choosing: small teams often start with Semgrep CE or a native platform scanner on default rules plus a handful of custom rules. Larger organisations commonly run a deep engine such as CodeQL or a commercial SAST product for broad coverage, and keep a pattern-based engine for fast, organisation-specific rules and variant analysis. Many keep secret scanning as a separate control. See the Application Security Testing Buyer's Guide and the Secrets Scanning Buyer's Guide.
Practitioner checklist
- Pin the Semgrep version or image digest in every pipeline and update it through a reviewed change.
- Keep organisation rules in a version-controlled repository with test cases and code review.
- Start in monitor mode, measure precision per rule, then block on a small high-precision set.
- Write custom rules for your own SDKs, wrappers and hard-coded credential patterns, tagged with CWE and an owner.
- Fail the pipeline on Semgrep error exit codes, not only on findings.
- Require a rule id and reason for every
nosemgrepand review.semgrepignorechanges. - Run the scan job without publishing or cloud deployment secrets, and vault any
SEMGREP_APP_TOKEN. - Decide on metrics and result upload under your data policy, and record the licence of every ruleset used.
- Pair Semgrep with history-aware secret scanning and rotate any credential it finds.
Standards and references
- Semgrep: Rule syntax
- Semgrep: Licensing
- Semgrep: CLI reference
- Semgrep: Sample CI configurations
- Semgrep: Semgrep Community Edition repository
- NIST: SP 800-218 Secure Software Development Framework 1.1
- NIST: SP 800-53 Rev. 5
- GitHub: About code scanning with CodeQL
Related NHI Mgmt Group resources: Application Security Guide · Secure Code Review Guide · Git Secret Scanning Guide · DevSecOps Guide · CI/CD Security Guide