PRACTITIONER GUIDE
Practitioner Guide12 min read

Semgrep SAST Deployment: Custom Rule Writing, CI/CD Integration, and Reducing False Positives for Developer Adoption

3
enforcement tiers (block, warn, audit) that a mature Semgrep deployment uses to match rule confidence level to pipeline action, preventing developer friction from low-confidence findings.
30 days
target window for writing custom Semgrep rules covering organization-specific internal library patterns after initial deployment, before relying solely on registry rules.
20%
nosemgrep suppression rate threshold above which a repository warrants investigation, as it may indicate developers bypassing the security gate rather than fixing findings.
> 60%
true positive rate target per ruleset, measured as findings fixed by code change versus suppressed or marked false positive, indicating a healthy signal-to-noise ratio.

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

The security tool that developers actually use is the one that does not constantly interrupt them with false alarms and that produces findings they understand and can fix. Semgrep achieves developer adoption where other SAST tools fail because its rule syntax is readable, its finding messages are actionable, and the deployment model allows progressive enforcement — warnings before blocking, high-confidence findings before medium-confidence findings.

The deployment that produces security value requires custom rules for organization-specific patterns that the registry cannot cover, a false positive review process that removes noise before enforcement is enabled, and blocking policies that developers understand and trust because the findings they block on are real vulnerabilities.

Rule selection and custom rule development

Selecting the right registry rulesets and writing targeted custom rules are the two decisions that determine whether Semgrep produces actionable findings or noise that developers learn to ignore. The Semgrep registry contains thousands of rules, but enabling all of them simultaneously generates a high false positive rate that destroys developer trust before the program establishes credibility. Practitioners should start with the auto ruleset or curated language-specific sets (p/python-security, p/nodejs-security, p/java) and expand only after reviewing finding quality. Custom rules fill the gap the registry cannot address: insecure calls to internal wrapper libraries, bypassed authentication decorators specific to your framework, and hardcoded credentials in your organization's config file formats require rules written by someone who knows the codebase. Within the first 30 days, work with security champions in each engineering area to identify the highest-risk internal patterns and produce at least one custom rule per pattern, tested in the Semgrep Playground against both positive and negative examples.

Start with curated rulesets then expand based on your technology stack findings

Enable the auto ruleset (semgrep --config auto) which selects registry rules appropriate for each detected language automatically, rather than enabling all rules simultaneously. The auto ruleset applies rules with known low false positive rates for the detected file types. After the first scan, review the finding categories and add technology-specific rulesets for your primary languages: p/python-security for Python, p/nodejs-security for Node.js, p/java for Java. For each new ruleset addition, run it in warn mode for two weeks before switching findings to block, reviewing the findings to assess true positive rate before enforcement. Expand to framework-specific rulesets (p/flask, p/express, p/spring) after the language-level rulesets are tuned.

Write custom rules for your internal library patterns in the first 30 days

Within the first 30 days of Semgrep deployment, work with the security champion or AppSec team in each major engineering area to identify the internal library patterns that represent security risks: internal wrapper functions that are deprecated in favor of safer alternatives, authentication bypass patterns specific to your framework, hardcoded environment-specific credentials or API keys in configuration files with formats unique to your organization, or direct database access patterns that bypass your ORM's safety layer. Write one custom rule for each identified pattern, test against both positive and negative examples in the Semgrep Playground, and add to the organization's custom ruleset stored in the repository at .semgrep/rules/. These rules provide coverage that no commercial registry rule can offer.

Progressive enforcement: from audit to blocking

Moving from audit-only reporting to pipeline-blocking enforcement is the step that converts Semgrep from a reporting tool into a security gate, and it must be done gradually enough that developers trust the findings before they are forced to act on them. The standard approach is two weeks of audit mode, during which all findings are collected and triaged with the development team to separate confirmed vulnerabilities from false positives. Only after the team has reviewed and categorized the initial finding set should blocking enforcement be activated, and only for the confirmed true-positive finding categories. Communicating the cutover date in advance and sharing the specific finding types that will block merges reduces developer resistance because the enforcement is no longer a surprise. The nosemgrep suppression mechanism gives developers an escape valve, but tracking suppression rates per repository catches cases where it is being used to bypass genuine findings rather than dismiss confirmed false positives.

Run in audit mode for the first two weeks before any blocking enforcement

Configure the initial Semgrep CI/CD integration to run on all pull requests but never block merges (remove --error flag or configure semgrep-action with audit: true). During the audit period, collect all findings into Semgrep Cloud Platform or a finding log and review them with the development team to identify true positives and false positives. Categorize each finding type as: confirmed vulnerability to block on, uncertain pattern to warn on, or confirmed false positive to suppress. After the audit period, enable blocking only for confirmed true-positive finding categories. Inform developers in advance of the cutover date for blocking enforcement, share the findings that will block merges, and provide a self-service triage process for developers to flag potential false positives.

Configure finding suppression with team review to prevent security gate bypass

Enable nosemgrep comment suppression for developers to bypass false positive findings, but require code review approval specifically for any nosemgrep comment added. In GitHub, create a CODEOWNERS rule that requires AppSec team review for any pull request that modifies a nosemgrep comment or adds a new one — this ensures suppressions are reviewed rather than used as a bypass mechanism. Track the nosemgrep suppression rate monthly: a suppression rate above 20% of findings indicates that either the rules are generating too many false positives (requiring rule refinement) or developers are suppressing real findings to avoid fixing them (requiring enforcement policy review).

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

The bottom line

Semgrep SAST deployment succeeds when it is deployed progressively: audit mode first, developer review of findings, suppression of confirmed false positives, then blocking enforcement on high-confidence findings only. Custom rules for organization-specific patterns provide the coverage that distinguishes a security program that knows its own codebase from one relying solely on commercial registry rules. Track nosemgrep suppression rates and true positive rates monthly to maintain developer trust in the tool — a SAST scanner that developers trust to flag real vulnerabilities is the foundation of a functional shift-left security program.

Frequently asked questions

How do I write a basic Semgrep rule to detect a security vulnerability?

A Semgrep rule is a YAML file with five required fields: rules (the list), id (unique rule identifier), pattern (the code pattern to match), message (the finding description shown to developers), languages (the target language list), and severity (ERROR, WARNING, or INFO). A simple rule detecting use of MD5 for password hashing in Python looks like this: set rules, then under the first item set id to no-md5-password-hash, pattern to hashlib.md5(...), message to MD5 is cryptographically broken — use hashlib.sha256 or bcrypt for password hashing, languages to python, and severity to ERROR. Run it with semgrep --config path/to/rule.yaml . from the repository root. The rule matches any call to hashlib.md5() regardless of what arguments are passed. Refine the pattern to avoid false positives (such as MD5 used for non-security checksums) by adding pattern-not-inside conditions that exclude known safe usage contexts.

How do taint tracking rules work in Semgrep?

Semgrep taint tracking rules use the mode: taint field combined with pattern-sources (where user-controlled data enters the program), pattern-sanitizers (functions that safely clean or validate the data), and pattern-sinks (dangerous functions that should never receive unsanitized user data). A SQL injection taint rule for Python would set sources to Flask request.form and request.args field access, sanitizers to a parameterized query function, and sinks to cursor.execute() with string concatenation. When Semgrep analyzes the code, it builds a data flow graph and flags any path where a source reaches a sink without passing through a sanitizer. Taint rules generate more complex matches than simple pattern rules and require testing against both true-positive examples (vulnerable code) and true-negative examples (safe code with sanitization) to confirm the rule correctly distinguishes the two cases.

How do I integrate Semgrep into GitHub Actions CI/CD?

Create a GitHub Actions workflow file at .github/workflows/semgrep.yml that triggers on pull_request events. The workflow should checkout the code with actions/checkout, then run Semgrep using the returntocorp/semgrep-action step (for Semgrep Code with the cloud platform) or by installing Semgrep with pip install semgrep and running semgrep --config auto --error for OSS mode. For blocking enforcement: set the semgrep step to exit with code 1 on findings by using --error flag, which fails the workflow and blocks the pull request merge. Configure branch protection rules in GitHub to require this check to pass before merging. For Semgrep Code with the cloud platform, use the SEMGREP_APP_TOKEN secret and the cloud platform handles finding management, deduplication, and triage workflow. Set the workflow to also run on push to main to catch any findings that bypassed the PR check.

How do I reduce false positives in Semgrep to prevent developer friction?

The false positive reduction process for Semgrep has three steps: rule selection, rule refinement, and finding triage workflow. For rule selection, do not enable all registry rules simultaneously — start with the rules in the semgrep:defaults or p/ci rulesets which have been curated for low false positive rates, then expand based on your technology stack (p/python, p/javascript, p/java). For rule refinement, add pattern-not and pattern-not-inside conditions to rules that generate systematic false positives: if a rule for unsafe deserialization fires on every use of JSON.parse (a false positive because JSON.parse does not execute code), add pattern-not for JSON.parse specifically. For finding triage, categorize all initial findings before enabling blocking enforcement — a batch of 500 findings on the first run should be triaged to identify true positives before any blocking policies are enabled, so developers are not blocked on known false positives.

What Semgrep rules should I write first for custom security coverage?

The highest-value custom Semgrep rules for organization-specific security coverage: hardcoded credentials in your specific configuration file formats (rules that match your internal config YAML structure, not just generic password= patterns), calls to deprecated internal security library functions (your internal crypto wrapper's old encryption function), unsafe usage patterns in your specific framework (direct database query construction in your ORM, bypassing the parameterized query interface), disabled security controls (CSRF protection disabled in your framework's decorator, security headers removed in your custom middleware), and direct call to the internal admin API without the required authorization check that your code style requires. Write each rule with at least three example matches in the rule's metadata to document what the rule detects and three non-matches to document what should not trigger it.

How do I handle Semgrep findings on existing code without blocking all current development?

Deploy Semgrep in a scan-new-code-only mode for existing codebases to avoid being blocked by historical findings that cannot be fixed immediately. Use Semgrep's diff-aware scanning to scan only the changed files and lines in each pull request rather than the full codebase: configure the semgrep-action with baseline_ref to compare against the main branch, so only findings introduced by the pull request's changes trigger the check. This allows the team to fix new vulnerabilities as they are introduced without being blocked by the backlog of historical findings. Track the historical findings separately in Semgrep Cloud Platform or as a dedicated report, create a remediation backlog, and assign fixing historical findings as a separate engineering task separate from the CI/CD blocking policy.

How do I measure Semgrep adoption and security impact?

Measure Semgrep adoption and impact with these metrics tracked monthly: repositories with Semgrep enabled as a percentage of all active repositories (target 100% of repositories with security-sensitive code), mean time from finding creation to finding remediation for findings that block CI/CD (target under 3 days for high-severity findings), nosemgrep suppression count per repository and trend over time (rising suppression count indicates developers bypassing the security gate rather than fixing findings), true positive rate of findings resolved by fixing code versus suppressed with nosemgrep or marked as false positive (target over 60% true positive rate per ruleset), and vulnerability classes detected and remediated before production deployment as a measure of shift-left security value. Report these monthly in security program metrics alongside SAST findings prevented from reaching production.

Sources & references

  1. Semgrep Documentation
  2. Semgrep Rule Syntax Reference
  3. Semgrep Registry
  4. Semgrep GitHub Actions Integration

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.