Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

By updated

Improve this page

A secret committed to Git stays there, even after the file is deleted. A Docker image published with an embedded token can be exploited very quickly. Automated detection is an indispensable safety net to intercept these leaks before they become incidents. This guide compares the main detection tools, Gitleaks, TruffleHog, Trivy and detect-secrets, and proposes a combined strategy covering the developer workstation, CI/CD, container images and the filesystem.

This page is about choosing and combining tools. The step-by-step use of a single scanner is in the Gitleaks lesson, the governance side (blocking rules, ownership, exceptions) in secrets scanning in the pipeline, and what to do once a secret is found in responding to a compromised secret.

What you will learn

Secrets detection is the safety net that catches what escaped good practice. Concretely, you will be able to:

  • Choose the right tool for each surface: Gitleaks, TruffleHog, Trivy, detect-secrets.
  • Block a secret before the push with a pre-commit hook.
  • Integrate detection into a CI/CD pipeline and on container images.
  • Combine several tools for complete coverage (workstation, CI, images, history).
  • Connect this detection to the SOCLE threat model (in French), which makes it a requirement (leak detection and response procedure).

Why detect early?

The longer an exposed secret goes undetected, the higher the risk of exploitation. A secret pushed to a public repository can be spotted by scanning bots within minutes: it is safer to treat it as compromised as soon as it is published.

Moment of detectionRemediation costResidual risk
Before the commit (pre-commit)Very lowReduced, but can be bypassed
At the pull request (CI)LowLimited (branch)
After merge (periodic scan)MediumHigh (history)
After publication (image, release)HighCritical

No row is risk-free. A pre-commit hook can be skipped with git commit --no-verify, it does not see what is already in the history, and it depends on a local installation that nothing guarantees for every contributor. It lowers the risk, it does not remove it: the CI, which runs on the server rather than on the contributor's workstation, is the next safety net.

The goal is to move detection as far left as possible in the development cycle: pre-commit > CI > periodic scan, each level catching what the previous one missed.

Which detection tools exist?

Four tools cover most needs. Each has a distinct positioning. In the table, a false positive is an alert on something that is not a real secret, and entropy is a measure of how random a string looks, which tools use to spot keys.

CriterionGitleaksTruffleHogTrivydetect-secrets
TypeRegex patterns + entropyPatterns + active verificationMulti-target scannerPatterns + baseline
Git (history)YesYesNoYes
FilesystemYesYesYesYes
Docker imagesNoYesYesNo
Active verificationNoYes (API calls)NoNo
False positivesModerateLow (thanks to verification)ModerateManageable (baseline)
SpeedFastMediumFastFast
Native pre-commitYesYesNoYes
LicenceMITAGPL-3.0Apache 2.0Apache 2.0

For the installation details and advanced configuration of each tool:

How do you detect secrets at pre-commit?

A pre-commit hook is a small program that Git runs just before it records a commit. Here it blocks the commit if a secret is detected in the staged files (the files you added with git add). It is the first line of defence.

With Gitleaks

  1. Install Gitleaks

    Terminal window
    # Linux (binary)
    curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz | tar xz
    sudo mv gitleaks /usr/local/bin/
    # macOS
    brew install gitleaks

    Check the installation:

    Terminal window
    gitleaks version
  2. Configure the pre-commit hook

    With the pre-commit framework, add the following to .pre-commit-config.yaml:

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

    Then install the hook:

    Terminal window
    pre-commit install
  3. Test the hook

    Create a test file containing a fake secret:

    Terminal window
    echo 'GITHUB_TOKEN="ghp_0123456789abcdefghijklmnopqrstuvwxyz"' > test-secret.txt
    git add test-secret.txt
    git commit -m "test"

    The commit must be blocked, with the github-pat rule in the message.

    The test pattern is not interchangeable. An AWS AKIA… key paired with its public example value does not trigger on gitleaks 8.30.1: the rule requires an entropy that documentation strings do not reach. A learner who tests with it sees the commit go through and believes the hook is broken. The patterns that trigger for sure are a ghp_ token and a PEM private key block.

    Terminal window
    # Clean up after the test
    git reset HEAD test-secret.txt
    rm test-secret.txt

With detect-secrets

The detect-secrets approach relies on a baseline: a .secrets.baseline file that lists the known secrets (to ignore or track them).

Terminal window
# Create the initial baseline
detect-secrets scan > .secrets.baseline
# Install the pre-commit hook
cat >> .pre-commit-config.yaml << 'EOF'
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
EOF
pre-commit install

How do you detect secrets in CI/CD?

The CI scan intercepts the secrets that escaped pre-commit. It runs on every pull request or push.

name: Secret Scan
on:
pull_request:
push:
branches: [main]
permissions: {}
jobs:
gitleaks:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Adding TruffleHog for active verification

TruffleHog can check whether a detected secret is still valid by testing the matching APIs. It is an ideal complement to Gitleaks in CI.

# Add this job to your GitHub Actions pipeline
trufflehog:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: TruffleHog scan
run: |
docker run --rm -v "$PWD:/repo" \
trufflesecurity/trufflehog:3.99.2@sha256:47a84bc18a0d04a165498bbbd3bacfd84176661cbc91f8e0f85467f6a771e99a \
git file:///repo --only-verified --fail

How do you scan a filesystem or an image?

Scanning a directory

Some secrets never reach Git: .env files excluded by .gitignore, local configurations, exports. A filesystem scan looks at the files on disk instead of the Git history.

Terminal window
# With Gitleaks
gitleaks detect --source /path/to/project --no-git --verbose
# With TruffleHog
trufflehog filesystem /path/to/project --only-verified
# With Trivy
trivy fs --scanners secret /path/to/project

Scanning a Docker image

Docker images can contain secrets embedded in their layers (the stacked file changes that make up an image). Of the four tools, Trivy and TruffleHog (trufflehog docker --image) can scan an image directly; Gitleaks and detect-secrets cannot. This guide picks Trivy for this surface.

Terminal window
trivy image --scanners secret my-image:1.4.0

Trivy inspects each layer of the image and reports the secrets found with their exact location.

Terminal window
# Sample output
my-image:1.4.0 (secrets)
============================
Total: 1 (HIGH: 1)
┌──────────┬──────────────────┬──────────┬───────────────────────────┐
│ Category │ Description│ Severity │ Match │
├──────────┼──────────────────┼──────────┼───────────────────────────┤
│ AWS │ AWS Access Key ID│ HIGH │ AKIA**************** │
└──────────┴──────────────────┴──────────┴───────────────────────────┘

To avoid embedding secrets in images in the first place, see the guide Secret leaks: logs, Docker, variables.

What is active verification of secrets?

Active verification consists in testing whether a detected secret is still valid. Only TruffleHog offers this feature natively.

ProviderVerification method
AWSsts:GetCallerIdentity call
GitHubAPI call with the token
Slackauth.test call
Google CloudOAuth tokeninfo call
StripeCharges API call

Active verification reduces false positives: an invalid secret is no longer an emergency, it is a hygiene point.

Terminal window
# Scan only the secrets verified as active
trufflehog git file:///path/to/repo --only-verified
# Scan and also include the unverified ones
trufflehog git file:///path/to/repo --results=verified,unknown

To go deeper into active verification: TruffleHog guide (in French).

How do you handle false positives?

An excessive false-positive rate leads developers to ignore alerts. Two techniques keep it under control, then one rule tells you when to use which.

Excluding known patterns

With Gitleaks, create a .gitleaks.toml file at the root of the repository:

[allowlist]
description = "Known false positives"
paths = [
'''tests/fixtures/.*''',
'''docs/examples/.*''',
]
regexes = [
'''EXAMPLE_.*''',
'''AKIAIOSFODNN7EXAMPLE''',
]

Using the detect-secrets baseline

Terminal window
# Audit the baseline: mark each secret as a true or false positive
detect-secrets audit .secrets.baseline

The interactive audit goes through each entry and asks for confirmation. The false positives you mark no longer trigger an alert.

General rule

The table sums up which action fits which situation, so that the choice does not depend on mood.

ActionWhen
Exclude via allowlistRecurring and verified pattern (test keys, mocks)
Baseline + auditProject with a lot of history
Fix the codeReal secret, even if inactive

Which combined strategy should you adopt?

Each tool has its strengths and limits. The following strategy combines three tools to take advantage of each and cover every surface.

SurfaceToolMoment
Developer workstationGitleaks (pre-commit)Before every commit
Pull requestGitleaks + TruffleHog (CI)On every PR
Full historyTruffleHog (--only-verified)Weekly scan
Docker imagesTrivy (--scanners secret)On every build
FilesystemTrivy or Gitleaks (--no-git)One-off audit

The diagram shows how these layers catch each other's misses: what pre-commit lets through is stopped by CI, and what CI does not see comes out in the periodic scan.

Defence in three layers: on the developer side, Gitleaks at pre-commit blocks the commit; in CI/CD, Gitleaks, TruffleHog and Trivy block the pull request; periodically, TruffleHog goes through the whole history and produces an audit report followed by rotation, for what escaped the previous layers.secret not blockedsecret not detectedPeriodicTruffleHogfull historyAudit report + rotationCI/CDGitleaks(PR scan)PR blockedif secretTruffleHog(active verification)Trivy image(Docker build)DeveloperGitleakspre-commitCommit blockedif secret
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %
  1. Install Gitleaks at pre-commit on all repositories

    This is the simplest measure to deploy. A secret blocked before the commit never enters the history and needs no rotation, provided the hook is really installed.

  2. Add Gitleaks in CI on every pull request

    A developer may not have the hook enabled. CI is the safety net.

  3. Add TruffleHog in CI for active verification

    Complements Gitleaks by identifying the secrets that are still valid. TruffleHog also offers a pre-commit hook, but Gitleaks, which is faster according to the comparison table, suits the developer workstation better: a slow hook ends up bypassed.

  4. Scan Docker images with Trivy before publication

    Add trivy image --scanners secret to the build pipeline, before the docker push.

  5. Schedule a weekly scan of the full history

    Terminal window
    trufflehog git file:///path/to/repo --only-verified --json > secrets-report.json

    Use the report to prioritise rotations.

Key points

  • Pre-commit detection is the first line of defence: it keeps the secret out of the Git history, but it can be bypassed (--no-verify) and does not replace CI.
  • Gitleaks excels at pre-commit and in CI thanks to its speed and customisable rules.
  • TruffleHog stands out for its active verification: it tests whether the secret is still valid.
  • For Docker images, Trivy and TruffleHog scan the image directly; Gitleaks and detect-secrets do not.
  • detect-secrets suits projects with a heavy history thanks to its baseline system.
  • Each tool has its strengths and limits: combine pre-commit, CI and image scanning.
  • Better to tolerate a few false positives than to hide a true one: never silence an alert without checking it.
  • A detected secret, even inactive, must be removed from the source code and renewed (rotation).

Knowledge check

Check that the essentials of this lesson are in place. The questions only cover what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

3 questions
3 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn