Skip to content

Lab session

Secrets Scanning and Precise Exceptions

Use Gitleaks to distinguish the current tree from Git history, then add one narrow exception without weakening detection elsewhere.

Release Date Sep 7, 2026
Due Date Sep 11, 2026
Starter Code Fork repository

Overview

In this lab, you learn to use Gitleaks to distinguish findings in the current file tree from findings in reachable Git history. You will read the evidence reported by each scan, configure one justified exception for harmless test data, and test whether that exception weakens detection elsewhere.

🎯 Learning Goals

After completing this lab, you should be able to:

  • Run Gitleaks against the current file tree and reachable Git history
  • Explain why the two scan modes can produce different findings
  • Read the rule and path associated with a finding
  • Test whether a path- and rule-scoped exception preserves detection elsewhere

Deliverables

By the end of the lab, your fork should contain a Gitleaks policy that permits the intentional test fixture without weakening detection elsewhere. You will submit the URL of the specific commit containing that policy through Canvas.

Setup

Fork the starter repository to your own account and open it in the provided devcontainer. Do not push commits to the upstream course repository. Instead, work entirely in your fork.

The starter is a small synthetic project with a deterministic test suite. The devcontainer provides the same pinned version of Gitleaks used by the checker. The starter .gitleaks.toml file extends the default rules but does not yet contain an exception.

From the repository root, confirm that Gitleaks is available and run the starter tests before changing anything:

gitleaks version
npm test

Setup is complete when Gitleaks reports version 8.25.0 or later and all tests pass.

Tasks

Task 1: Observe Two Scan Targets

gitleaks dir scans files in the current directory tree. gitleaks git asks Git for commit patches and scans content introduced through reachable history, including content later deleted from the current tree. A finding is evidence that a value matches a rule, not proof that the value authenticates to a real service.

Before running either scan, predict which one can report content that is no longer present in your checkout.

Run both scans from the repository root:

gitleaks dir --config .gitleaks.toml --verbose .
gitleaks git --config .gitleaks.toml --verbose --log-opts="--all" .

Both commands initially exit nonzero because the starter deliberately contains scanner matches. Compare their output and identify the rule and path shared by both scans. Then identify the additional rule and path reported only by the history scan. Do not copy either matched value into a note, commit message, or other file.

Check your reasoning: Why did the history scan report more?

The directory scan can inspect only files that exist now. The Git scan inspects content introduced through reachable commits, so it can report a value even after a later commit deletes its file.

Task 2: Add One Precise Exception

The finding shared by both scans is a fake service token in a test fixture. The fixture is harmless, and the test suite relies on it, so deleting or changing it merely to silence the scanner is not an acceptable fix.

Add a global [[allowlists]] entry to .gitleaks.toml that applies only when both of these conditions hold:

  • The finding comes from the rule you observed for the fixture
  • The finding comes from the exact fixture path you observed

Use targetRules for the rule restriction and paths for the path restriction. Anchor the path expression at both ends so it matches only the reported fixture path, not a similar path or filename. Keep [extend] with useDefault = true so every other default rule remains active.

Use this configuration shape, replacing the placeholders with evidence from your scan:

[[allowlists]]
description = "Allow the intentional service response fixture"
targetRules = ["RULE-ID"]
paths = ['''^EXACT/FIXTURE/PATH$''']

How a Gitleaks exception works

A Gitleaks rule describes a suspicious pattern and may also require context or sufficient entropy. An allowlist filters findings after those rules match. Combining targetRules with an anchored path expression limits the exception to one rule in one known location, while the same rule still protects the rest of the repository. Disabling a rule or allowlisting a broad directory changes much more policy than this fixture requires.

Re-run the tree scan with the committed configuration:

gitleaks dir --config .gitleaks.toml --verbose .

It should now exit zero without changing the fixture.

Task 3: Challenge the Policy

A clean scan establishes that the exception permits the known fixture. It does not establish that the policy still catches the same kind of value somewhere nearby.

Before running the checker, predict whether your policy will reject the same kind of finding at a neighboring path and whether the fixture exception will hide the finding from the deleted debug configuration.

Run the supplied checker:

./scripts/check-lab

The checker runs the tests, confirms that the current tree is accepted, and temporarily places a credential-shaped control next to the allowed fixture. Your policy must reject that control and identify its path. The checker removes the control before it exits.

The checker also repeats the history scan.

Check your reasoning: Why should the history scan still fail?

The exception is limited to the fixture's rule and current path. It should not suppress a different rule at a different path merely because that file was later deleted.

To inspect that result yourself, re-run the history scan:

gitleaks git --config .gitleaks.toml --verbose --log-opts="--all" .

It should still report the finding from the retired debug configuration and exit nonzero. That result is intentional: the value is absent from the current tree, and this preparation lab does not ask you to rewrite history or suppress a credential-shaped value.

Here, leave the starter history unchanged.

Additional Resources

Submission

  1. Commit .gitleaks.toml, then push that commit to your fork.
  2. Confirm that git status --short produces no output, then run ./scripts/check-lab one last time.
  3. Submit the URL of that exact commit—not a branch or pull request—using the Canvas link below.

Open assignment in Canvas

This lab is graded pass/fail.