Opengrep - Open-Source Static Code Analysis Cheatsheet
Opengrep is a community-governed fork of the Semgrep engine, created after features moved behind a commercial license. It performs fast, pattern-based static application security testing (SAST) across 30+ languages, using rules written in a syntax that looks like the code being matched — no AST expertise required. The fork’s premise is that core scanning capability (including features like cross-file dataflow) should remain fully open-source.
Installation
Scanning
| Command | Description |
|---|
opengrep scan . | Scan the current directory with default rules |
opengrep scan --config auto . | Auto-select rules for detected languages |
opengrep scan --config rules/ . | Use a local rule directory |
opengrep scan --config p/security-audit . | Use a rule pack |
opengrep scan --json -o out.json . | JSON output |
opengrep scan --sarif -o out.sarif . | SARIF for code-scanning platforms |
Writing Rules
Rules are YAML; the pattern looks like the code you want to find.
rules:
- id: hardcoded-aws-key
patterns:
- pattern: $KEY = "AKIA..."
message: Possible hardcoded AWS access key
languages: [python, javascript]
severity: ERROR
| Key | Purpose |
|---|
pattern | Code shape to match ($X = metavariable) |
patterns | AND of several conditions |
pattern-either | OR of alternatives |
pattern-not | Exclude a shape (kill false positives) |
pattern-inside | Only match within a context |
metavariable-regex | Constrain a metavariable |
severity | INFO / WARNING / ERROR |
Pattern Syntax Essentials
| Syntax | Matches |
|---|
$X | Any single expression (metavariable) |
... | Any sequence (args, statements) |
foo(...) | Any call to foo |
$OBJ.method(...) | Method call on anything |
"..." | Any string literal |
# Find eval() on any non-literal input
- pattern: eval($X)
pattern-not: eval("...")
Taint / Dataflow Rules
rules:
- id: sqli-taint
mode: taint
pattern-sources:
- pattern: request.args.get(...)
pattern-sinks:
- pattern: cursor.execute($Q)
message: Untrusted input reaches SQL execution
languages: [python]
severity: ERROR
Taint mode tracks data from sources (untrusted input) to sinks (dangerous operations), which is how you find real injection bugs rather than syntactic look-alikes.
CI Integration
# Fail the build on ERROR-severity findings
opengrep scan --config auto --error .
# Only scan files changed in this PR
opengrep scan --config auto --baseline-commit origin/main .
| Flag | Effect |
|---|
--error | Non-zero exit when findings exist |
--baseline-commit | Diff-aware scanning (new findings only) |
--severity ERROR | Filter by severity |
--exclude | Skip paths (vendor, tests) |
--sarif | Upload to GitHub code scanning |
Testing Rules
# Rules ship with test files annotated with expected findings
opengrep test rules/
Annotate a test file with # ruleid: my-rule above a line that should match and # ok: my-rule where it should not — then opengrep test verifies the rule behaves.
| Aspect | Opengrep | Semgrep | CodeQL |
|---|
| License | Fully open-source | Open core + commercial | Free for OSS, restricted commercial |
| Rule syntax | Code-like patterns | Same lineage | QL query language |
| Learning curve | Low | Low | High |
| Best for | Open SAST without feature gating | Managed platform + rules | Deep semantic queries |
Pairs with Semgrep knowledge (rules are largely compatible) and complements Bandit for Python-specific checks.
Resources