@codacy/tools-opengrep-1
v0.12.0
Published
Opengrep adapter — CLI-mode multi-language SAST scanner
Downloads
1,089
Readme
@codacy/tools-opengrep-1
Table of Contents
- Overview
- Rule bundling
- Updating patterns
- Updating rules
- Updating the Opengrep version
- Development
- Notes for maintainers
Overview
Multi-language SAST (Static Application Security Testing) scanner using the Opengrep binary. Supports 30+ languages via YAML rule files. Uses the CLI execution strategy.
| Property | Value |
| ---------------- | ------------------------------------------------------------------ |
| Tool ID | Semgrep (legacy, for Codacy platform compatibility) |
| Display name | Opengrep |
| Codacy UUID | 6792c561-236d-41b7-ba5e-9d6bee0d548b |
| Strategy | CLI |
| Languages | 30+ (Python, JavaScript, TypeScript, Java, Go, Ruby, C, C++, etc.) |
| Binary | opengrep |
| File patterns | * (auto-detects by language) |
| Pattern count | ~2500 |
| Extra dependency | yaml (for YAML rule config parsing/generation) |
Rule bundling
Opengrep uses YAML rule files for detection. The adapter bundles ~2200 rules into src/rules.yaml, sourced from:
- semgrep/semgrep-rules — community rules (pinned at commit
4ccd3b9) - GitLab SAST rules — MIT-licensed rules from
gitlab.com/gitlab-org/security-products/sast-rules - Codacy custom rules — from
codacy/codacy-opengrepwrapper repo
The bundled src/rules.yaml is committed to the repository for consistency and reproducibility.
Updating patterns
# Re-fetch pattern metadata from the Codacy API
pnpm prefetch
# Commit the result
git add src/patterns.jsonPattern IDs follow the format Semgrep_python.lang.security.audit.exec-detected.exec-detected (dot-separated rule paths).
Updating rules
# Re-fetch and bundle rules from all three sources
pnpm fetch-rules
# This clones the rule repos, extracts matching rules, and writes src/rules.yaml
# Only rules whose IDs match src/patterns.json are included
# Commit the result
git add src/rules.yamlThe fetch-rules script (scripts/fetch-rules.mjs):
- Clones
semgrep/semgrep-rulesat the pinned commit - Clones GitLab SAST rules (latest)
- Clones
codacy/codacy-opengrepfor custom rules - Extracts rules, assigns path-based IDs
- Filters to only rules matching
src/patterns.json - Writes concatenated YAML to
src/rules.yaml
To update the pinned semgrep-rules commit, edit SEMGREP_RULES_COMMIT in scripts/fetch-rules.mjs.
Updating the Opengrep version
- Update
preferredVersioninsrc/adapter.ts - Run
pnpm testto verify compatibility - Consider re-running
pnpm fetch-rulesif the new version supports new rule syntax
Development
pnpm build # Build with tsup
pnpm test # Run tests (requires opengrep in PATH)
pnpm fetch-rules # Re-bundle rules from upstream sources
pnpm prefetch # Re-fetch pattern metadata from Codacy APIInstalling the binary:
The adapter auto-installs opengrep into ~/.codacy/tools/ when run with
--install-dependencies (no manual step needed):
codacy-analysis analyze . --tool opengrep --install-dependenciesinstall() downloads the matching statically-linked binary from GitHub releases
(no archive to unpack) and chmod +xes it. The platform/arch/libc → asset
mapping mirrors opengrep's official install.sh:
| Platform | Asset |
| ------------------------- | ---------------------------- |
| macOS x64 | opengrep_osx_x86 |
| macOS arm64 | opengrep_osx_arm64 |
| Linux x64 (glibc) | opengrep_manylinux_x86 |
| Linux arm64 (glibc) | opengrep_manylinux_aarch64 |
| Linux x64 (musl/Alpine) | opengrep_musllinux_x86 |
| Linux arm64 (musl/Alpine) | opengrep_musllinux_aarch64 |
To install manually instead:
curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bashNotes for maintainers
- Tool ID is
Semgrepfor legacy compatibility with the Codacy platform. ThedisplayNameis set toOpengrepfor CLI display. Never change the tool ID without coordinating with the Codacy platform team. - Config materialization: When Codacy patterns are specified, the adapter loads
src/rules.yaml, filters to enabled rules, and writes a filtered config to.codacy/generated/opengrep-rules.yaml. - check_id prefix stripping: Opengrep prepends a path-based namespace to check_ids derived from the config file path relative to cwd. The adapter computes and strips this prefix (e.g.
codacy.generated.) plus anytmp.legacy prefix. - Config file search:
.semgrep.yaml,.opengrep.yaml,.semgrep.yml,.opengrep.yml(in that order). - Opengrep errors: Parse errors (syntax errors, partial parsing) from Opengrep's JSON
errorsarray are converted to structuredAnalysisErrorobjects withfilePath. Stderr (scan status table) is logged at debug level only. - Rule ID format: Semgrep-rules use
{dir}.{filename}.{ruleId}(dots), GitLab rules use{dir}_{filename}(underscores), Codacy custom rules keep their original IDs. - Install / binary download:
install()downloads the bare per-platform binary fromhttps://github.com/opengrep/opengrep/releases/download/v{version}/{asset}andchmod +xes it into~/.codacy/tools/. The release tag carries avprefix (v1.16.4) even thoughpreferredVersiondoes not. On Linux the libc flavour is detected with anldd /bin/shprobe (musl→ musllinux, else manylinux); detection failures fall back to glibc/manylinux. Unlike install.sh, the Codacy-managed install does not verify the cosign.cert/.sigsignatures — if signature verification becomes a requirement, fetch those sibling assets and validate before chmod. - Argv-size chunking (no directory walk): The adapter always passes Opengrep an explicit file list — the runner's already git-ignored, exclude-filtered target set — so Opengrep never walks the repository tree itself.
chunkFilesByArgvBudget()splits that list into the fewest, largest chunks that each fitARGV_BYTE_BUDGET(200 KB, well underARG_MAX), and each chunk is scanned in its ownopengrep scaninvocation; findings and errors are merged across chunks. Chunk by size, not count: every invocation re-compilesrules.yaml, so fewer/larger chunks amortize that fixed cost. The earlier directory/“root” fallback was removed because on huge repos (a single tracked file at the repo root collapsed the minimal-cover dirs to.) it made Opengrep walk the entire tree — re-scanning excluded/generated/vendored files and timing out at the runner's 10-minute limit. - File-size cap: invocations pass
--max-target-bytes 1000000(~1 MB). This restores Opengrep's default size cap — the adapter previously passed0, which disables the cap, so giant generated/minified bundles were scanned and dominated runtime. The cap applies to explicitly-listed files (verified on v1.16.4). Note:--exclude-minified-filesis not used — that flag is rejected by the bundled binary unless--experimental(a different engine) is also passed, so we rely on the size cap instead. (The runner also enforces a tighter 150 KB per-file limit centrally before files reach the adapter, so this--max-target-bytesis now a secondary defense.) - Partial results on timeout: the per-chunk loop checks
ctx.signal(the runner's timeout abort) between chunks and passes it tospawnTool, so an in-flight scan is killed promptly. On abort the adapter keeps the findings from completed chunks and adds a singleTimeouterror (→status: "partial") rather than losing everything. This is why chunking matters beyond ARG_MAX: it's the granularity at which a long scan can be stopped with results preserved.
