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.
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¶
- Gitleaks documentation: scan modes and command-line options
- Gitleaks configuration reference: extending the default configuration and scoping allowlists
- Git revision selection: how refs determine which commits are reachable to a history scan
Submission¶
- Commit
.gitleaks.toml, then push that commit to your fork. - Confirm that
git status --shortproduces no output, then run./scripts/check-labone last time. - Submit the URL of that exact commit—not a branch or pull request—using the Canvas link below.
This lab is graded pass/fail.