agenticaisecured

How do you set up secret scanning in pre-commit hooks?

Install the pre-commit framework, add a .pre-commit-config.yaml referencing gitleaks and/or TruffleHog, then run pre-commit install to wire the git pre-commit hook. Every commit is then scanned for secrets and blocked if one is found. Treat this local gate as a first line, not a replacement for server-side and CI scanning.

By Sunny Patel Updated

Independent SEO consultant & AI practitioner who builds and tests these tools.

How do you set up secret scanning in pre-commit hooks?

To set up secret scanning in pre-commit hooks, install the pre-commit framework, add a .pre-commit-config.yaml that references gitleaks and/or TruffleHog, then run pre-commit install to wire the git pre-commit hook. From then on every commit is scanned and blocked if a secret is found. Treat this local gate as a first line of defence, not a replacement for server-side and CI scanning.

TL;DR:

  • A git pre-commit hook runs before a commit is recorded and can abort it if a check fails.
  • The pre-commit framework manages hooks across languages via a single .pre-commit-config.yaml.
  • Wire in gitleaks for a fast regex and entropy gate, TruffleHog for verified detection.
  • Handle false positives with inline allow comments, ignore files, or config allowlists.
  • A local hook is bypassable, so keep CI and server-side scanning as the real backstop.

What is a git pre-commit hook?

A pre-commit hook is a script that git runs automatically just before a commit is finalised. Per the git hooks documentation, hooks live in the repository’s .git/hooks directory, and the pre-commit hook in particular runs before the commit message is even entered. If the script exits with a non-zero status, git aborts the commit.

That abort behaviour is what makes it useful for security. Instead of catching a leaked API key after it has been pushed, you catch it at the moment of commit, on the developer’s own machine, before it ever enters shared history. The catch is that raw .git/hooks scripts are not version controlled and not shared with the team, which is the gap the pre-commit framework fills.

What does the pre-commit framework do?

Per its documentation, pre-commit is “a framework for managing and maintaining multi-language pre-commit hooks”. Rather than hand-writing shell scripts in .git/hooks, you declare the hooks you want in a .pre-commit-config.yaml file that lives in the repository and is committed alongside your code. Anyone who clones the repo gets the same hook definitions.

Each entry references a repo, a pinned rev, and one or more hooks by id. The framework clones the hook repository, installs its dependencies in an isolated environment, and runs it on commit. This means a secret scanner can be added in a few lines without every contributor installing it manually.

How do you wire in gitleaks and TruffleHog?

Here is a sample .pre-commit-config.yaml that runs gitleaks on commit. The gitleaks config below uses the official hook published in the gitleaks repository, per its documentation:

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.2
    hooks:
      - id: gitleaks

TruffleHog publishes its own pre-commit support. Per the TruffleHog PreCommit.md documentation, the recommended setup uses a local hook that calls the already-installed TruffleHog binary:

  - repo: local
    hooks:
      - id: trufflehog
        name: TruffleHog
        description: Detect secrets in your data.
        entry: bash -c 'trufflehog git file://.'
        language: system
        stages: ["pre-commit", "pre-push"]

Pin the rev values to the latest released tags shown on each project’s releases page rather than copying these verbatim, since versions move on. With gitleaks, the framework manages the binary for you; with the TruffleHog local hook, TruffleHog must already be installed on the machine because language: system runs it as an existing system command.

Install steps

  1. Install the framework: pip install pre-commit (or use your platform’s package manager).
  2. Confirm it is available: pre-commit --version.
  3. Add the .pre-commit-config.yaml above to the repository root.
  4. Install TruffleHog if you use its local hook, following its repository instructions.
  5. Wire the git hook: pre-commit install.
  6. Scan the existing tree once: pre-commit run --all-files.
  7. Commit normally; the hooks now run on every git commit.

After step 5, the pre-commit hook script is written into .git/hooks/pre-commit, and any commit that introduces a detected secret will fail until you remove it. For a deeper walkthrough of gitleaks itself, including custom rules, see the gitleaks tutorial.

How do you handle false positives and allowlists?

Secret scanners flag candidate strings, and sometimes a high-entropy value is harmless, for example a test fixture or a public sample key. You do not want to disable the whole gate over one match.

Per gitleaks documentation, there are three ways to allowlist a finding. You can add an inline #gitleaks:allow comment on the offending line, add the finding’s unique fingerprint to a .gitleaksignore file at the repo root, or define [[allowlists]] rules in a .gitleaks.toml config that filter by path, regex, commit, or stopword. TruffleHog supports a trufflehog:ignore comment on the line containing the secret, per its documentation.

Use the narrowest mechanism that works. An inline comment documents exactly why one specific line is safe; a broad path allowlist can silently hide real leaks in a whole directory. Review allowlist additions in code review the same way you would review the code itself.

Why is pre-commit a first gate, not a full solution?

A pre-commit hook only protects the machine it is installed on. Per the framework documentation, hooks can be skipped deliberately: a developer can run git commit --no-verify or set SKIP=gitleaks to bypass them, and a freshly cloned repository has no active hooks at all until someone runs pre-commit install. Nothing on the server enforces that the scan ran.

That is why a local hook is the first gate, not the whole defence. You still need server-side or CI scanning that runs independently of any one laptop: a CI job that runs gitleaks or TruffleHog on every push, and ideally a verified-only TruffleHog sweep that confirms whether a leaked credential is actually live. For how the two scanners differ in CI and verification, see gitleaks vs TruffleHog.

The other limit is timing. The hook stops new secrets, but anything already committed before you added scanning is still in history. Run pre-commit run --all-files once to sweep the current tree, and if you find a secret that has already been pushed, rotate it first and follow the response steps in committed a secret to GitHub. A scanned commit is only safe if the key it caught never reached a remote, so when in doubt, assume it is public and rotate.

Frequently asked questions

What is a git pre-commit hook?

A pre-commit hook is a script git runs automatically before a commit is recorded. Per the git documentation, if the script exits non-zero the commit is aborted, which lets you reject changes that contain secrets, fail linting, or break formatting rules before anything reaches history.

Do I need both gitleaks and TruffleHog?

No, one is enough to start. gitleaks is fast and simple for a commit-time gate, while TruffleHog adds live credential verification. Many teams run gitleaks at commit time for speed and let TruffleHog do deeper verified sweeps in CI.

How do I handle a false positive?

Per gitleaks documentation you can add an inline #gitleaks:allow comment, list a finding fingerprint in a .gitleaksignore file, or define allowlists in .gitleaks.toml. TruffleHog supports a trufflehog:ignore comment on the offending line.

Can someone bypass the hook?

Yes. A developer can run git commit --no-verify or set the SKIP environment variable to skip hooks, and a fresh clone has no hooks until pre-commit install runs. That is exactly why server-side and CI scanning are still required.

Does the hook scan existing git history?

By default a commit-time hook only checks the changes you are about to commit, not the whole repository. To audit existing history run pre-commit run --all-files, or scan the full git log directly with gitleaks or TruffleHog.