Join our Newsletter — 33% off our NHI Course
Home› Guides› Semgrep Guide: Static Analysis Rules for Code Security
Guide Application Security

Semgrep Guide: Static Analysis Rules for Code Security

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 26 October 2026 12 min read
On this page

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

CapabilitySemgrep CE (LGPL 2.1)Commercial (Semgrep AppSec Platform, proprietary)
Pattern matching and autofixYes, with local or Registry rulesYes, with Pro rules and central policy
Taint (dataflow) analysisWithin a single function or methodAcross functions in a file (--pro-intrafile) and across files (--pro, rules with interfile: true)
Custom taint propagators, control sources, at-exit sinksNoYes
Dependency scanningNoSemgrep Supply Chain: reachability of vulnerable third-party functions, with Semgrep listing 14 supported languages
Secrets detectionOnly via rules you write or useSemgrep Secrets: regex, semantic analysis, entropy and a proprietary validator that runs locally
Triage, dashboards, PR commentsNo (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, HIGH or CRITICAL; the legacy INFO, WARNING and ERROR map to the first three), languages, and one of pattern, patterns, pattern-either or pattern-regex.
  • Combining patterns: patterns is a logical AND, pattern-either a logical OR, pattern-not and pattern-not-regex exclude, and pattern-inside or pattern-not-inside restrict matches by context.
  • Metavariables: $NAME binds any expression; metavariable-regex, metavariable-pattern, metavariable-comparison and metavariable-name constrain it, and focus-metavariable narrows the reported range.
  • Optional fields: fix (applied with --autofix), metadata (CWE, OWASP category, owner), paths with include and exclude globs, options and min-version.
  • Taint mode: mode: taint with pattern-sources (required), pattern-sinks, pattern-sanitizers and pattern-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=False on 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

  1. 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 --json output, and measure true and false positives by rule.
  2. Add to CI in monitor mode: run semgrep scan without --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.
  3. Scan only what changed: on pull requests use --baseline-commit (CE) or SEMGREP_BASELINE_REF (with semgrep ci) so developers see new findings only, and run full scans on a schedule.
  4. Block selectively: move a small set of high-precision rules to a blocking job with --error (exit code 1 on findings). Note that semgrep ci fails on findings by default. Treat exit codes 2 and above (engine, rule or configuration errors) as pipeline failures, not as clean scans.
  5. Govern exceptions: allow nosemgrep: rule-id comments only with the rule id and a reason, and review changes to .semgrepignore. The default ignore template skips paths such as tests/, vendor/ and node_modules/; override it if test code contains live credentials.
  6. Roll back: keep rule ids stable so a noisy rule can be removed with --exclude-rule or 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_PUBLISH token.
  • 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_TOKEN is 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=off or SEMGREP_SEND_METRICS=off where 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.

FrameworkReferenceHow Semgrep contributes
NIST SP 800-53 Rev. 5SA-11 Developer Testing and Evaluation; SA-11(1) Static Code AnalysisAutomated static analysis with recorded results on every change
NIST SP 800-53 Rev. 5SA-15 Development Process, Standards, and ToolsCoding standards expressed as executable rules
NIST CSF 2.0PR.PS-06 Secure software development practices are integrated and monitoredPipeline checks with metrics on findings and fix rates
NIST SP 800-218 (SSDF 1.1)PW.7 Review and/or analyse human-readable codeAutomated code analysis alongside manual review
CIS Controls v8.1Safeguard 16.12 Implement code-level security checksStatic analysis in the development pipeline
ISO/IEC 27001:2022Annex A 8.28 Secure codingEvidence that secure coding rules are applied
MITRE ATT&CK v20T1552.001 Credentials In Files; T1213.003 Code RepositoriesRemoving 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: nosemgrep comments 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

OptionApproachWhen it fits
Semgrep CESyntax-aware patterns, YAML rules, intraprocedural taint, LGPL 2.1 engineFast custom rules across many languages; teams that want to own their rules
OpengrepFork of Semgrep 1.100.0, LGPL 2.1, compatible rule formatTeams that want an open engine independent of one vendor's roadmap
GitHub CodeQLBuilds a database of the code and runs queries over it; deep dataflowDeep 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 languageSingle-language estates needing a quick baseline
Commercial SAST platformsBroad rule packs, cross-file analysis, triage workflow, supportLarge estates with compliance reporting needs
Dedicated secret scannersPattern, entropy and history scanning with validationCredential 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 nosemgrep and review .semgrepignore changes.
  • 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

Related NHI Mgmt Group resources: Application Security Guide · Secure Code Review Guide · Git Secret Scanning Guide · DevSecOps Guide · CI/CD Security Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 26 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.