Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.semgrep.dev/llms.txt

Use this file to discover all available pages before exploring further.

Semgrep offers two standard pre-commit hooks outlined here.
  • The semgrep hook is optimized to run with a provided set of rules, either local rules or rules from the Semgrep Registry.
  • The semgrep-ci hook is optimized to run with the rules from your organization in the Semgrep AppSec Platform, without sending results to the platform, since results from pre-commit are temporary and not linked to the final code in the repository.
    • This hook requires the user be logged in locally to fetch the rules from the organization.
You can also create your own Semgrep hooks for pre-commit if you have particular needs or preferences, such as if you want users to see the output of the Semgrep scan even if it passed, or if you want to limit the scan to a particular Semgrep product.

Show the scan output

By default, pre-commit does not show the scan output if the hook passes. If you want your developers to see the output even if non-blocking findings are found, you can set the verbose option to print the output. To limit output to findings only (no scan information or diagnostics), redirect stderr to /dev/null, or use --quiet. This example is based on the semgrep-ci hook, but a similar adjustment would also work with the semgrep hook.
repos:
- repo: https://github.com/semgrep/pre-commit
  rev: 'v1.101.0'
  hooks:
    - id: semgrep-verbose
      entry: semgrep
      args: ["ci", "--dry-run", "--baseline-commit", "HEAD" "2>/dev/null"]
      verbose: true
      pass_filenames: false
To print only a portion of the scan output, consider using shell-based text tools such as awk:
repos:
- repo: https://github.com/semgrep/pre-commit
  rev: 'v1.126.0'
  hooks:
      - id: semgrep-scan-summary-only
        entry: bash
        args:
          - -c
          - |
            semgrep ci --dry-run --baseline-commit HEAD 2>&1 \
              | awk '/Scan Summary/,/^CI scan completed successfully\./'
        pass_filenames: false
        language: system
        verbose: true
This example only prints the scan summary portion of the scan log. Using this approach, scan debugging output on stderr is redirected to stdout so that findings and debugging information appear in the same output stream. Then, the portion to show (the Semgrep scan summary) is selected using awk.

Limit the scan to a particular product

Semgrep Secrets is an ideal product to run before commit, since it can help prevent secrets from ever making it into the Git history, even locally. To run only Secrets in pre-commit, add the product flag to the args:
- repo: https://github.com/semgrep/pre-commit
  rev: 'v1.101.0'
  hooks:
    - id:  semgrep-secrets
      pass_filenames: false
      args: ["ci", "--dry-run", "--baseline-commit", "HEAD", "--secrets"]

Scan with Pro rules and cross-function analysis

The semgrep-ci hook requires the user to be logged in locally and runs with the engine configured in the organization, but the standard semgrep hook can also take advantage of local login to run with Pro rules and cross-function analysis.
- id: semgrep
  name: semgrep
  entry: semgrep
  args: ["--pro", "--disable-version-check", "--quiet", "--skip-unknown-extensions"]
This provides analysis across modified files during the pre-commit scan, which may catch additional vulnerabilities, or prevent false positives.

Customization tips

Useful arguments

The provided hooks include useful arguments for Semgrep that you may want to include in your hooks as well. For example, for the semgrep hook that runs with a provided --config, the arguments also include:
  • --disable-version-check: skip checking whether there’s a new version of Semgrep (speeds up the check and avoids irrelevant output)
  • --quiet: only print findings, not other messages
  • --skip-unknown-extensions: if files are modified that aren’t in a recognized language, skip them
The semgrep-ci hook runs with the pre-commit option pass_filenames: false. This is important because semgrep ci doesn’t expect a list of filenames; it just expects to scan the folder, so you should preserve this option in your usage. Adding baseline-commit HEAD performs a diff scan; this diff scan only scans the changes being added in the current commit (as intended for a pre-commit hook). It uses --dry-run so that findings that have no existence except in the local filesystem aren’t added to the platform, which would otherwise result in clutter.

Entry point

Both of the default hooks use semgrep as the entry, which means the command executed is just semgrep with the args provided. However, you can write your own entry point. This approach is used in the less commonly used semgrep-docker hook also available in the semgrep/pre-commit repository. It can also be used with a standard Semgrep execution to set environment variables in addition to (or instead of) arguments:
 entry: sh -c 'env SEMGREP_RULES=<SEMGREP_RULESET_URL> semgrep scan --code --no-suppress-errors --baseline-commit HEAD'
In this case, setting SEMGREP_RULES=<SEMGREP_RULESET_URL> substitutes for supplying --config and <SEMGREP_RULESET_URL> in the args.