Block Leaked API Keys Before GitHub
Use GitGuardian to block secrets in commits and scan your Git history.
Introduction
30 Second Summary
A credential copied into the wrong file can travel farther than you expect. Once it reaches a public repository, someone can use it before you notice.
In this project, you will create a practice Git repository protected by GitGuardian's ggshield command line tool. You will prove the protection works at commit time before auditing older commits for exposed credentials.
What You'll Build
You will try to commit a fake credential and watch ggshield block it before it can reach GitHub.
By the end of this project, you'll have:
- A protected practice repository where ggshield blocks a staged secret before the commit succeeds.
- A safe configuration pattern that loads a credential from an environment variable and allows the clean commit through.
- A full history audit that surfaces past findings as a report you can investigate in the GitGuardian dashboard.
- Secret Mission: An optional challenge to push your secret-scanning skills further.
Do I need any experience before starting?
You need Git plus either Python or Homebrew available on your computer. You will create your free GitGuardian account and install ggshield in Step 1.
Before We Start
Secret scanning starts from your terminal. A reliable scan needs a terminal that can reach Git.
The later history scan also needs a local repository that you own. In this step, you will prepare both starting points without changing any project files.
In this step, get ready to:
- Open a terminal on your computer.
- Verify that Git is installed.
- Identify a local repository you own for the later history scan.
Open a terminal and check Git
A terminal lets you run the scanner from the command line. Git must be available there before later tools can inspect commits.
macOS
The Terminal app gives you a command prompt on macOS.
- Press Cmd+Space to open Spotlight.
- Type Terminal into the search field.
- Press Return to open Terminal.
You will see a command prompt where you can enter commands.
Windows
Windows includes Windows PowerShell for running command-line tools.
- Press the Windows key to open search.
- Type PowerShell into the search field.
- Select Windows PowerShell from the results.
You will see a command prompt where you can enter commands.
Before you run this, consider whether your terminal can print a Git version.
- Check whether Git is available by running this command:
git --version
What does this command do?
The git --version command asks Git to print its installed version. A version line proves that your terminal can find Git.
✔️ I see a Git version
Good start. The version output confirms that Git is installed.
Your terminal can now run the Git commands used throughout this project.
ⓧ Git is unavailable
Git needs to be installed before the scanner can inspect commits. Choose your operating system below.
macOS
macOS can install Git through Xcode Command Line Tools. The installer may take a few minutes to download the required files.
- Start the installer by running this command:
xcode-select --install
What does this command do?
The xcode-select --install command opens Apple's installer for the command-line tools. That package includes Git.
- Complete the installer prompts that appear.
- Return to Terminal from earlier.
- Confirm the installation by running this command:
git --version
What confirms the installation?
The git --version command prints the installed Git version. That output confirms the installation is ready.
Git still unavailable?
Finish any open installer dialog before checking again. Restart Terminal if the installation completed while it was open.
If the command still fails, help me troubleshoot Git on macOS.
Windows
The official Git website provides the maintained Git for Windows installer. The download can take a few minutes on a slower connection.
- Open the official Git for Windows installation page.
- Download the installer that matches your computer's processor type.
- Run the downloaded installer.
- Complete the installation using the default options.
- Return to Windows PowerShell from earlier.
- Confirm the installation by running this command:
git --version
What confirms the installation?
The git --version command prints the installed Git version. That output confirms that Windows PowerShell can find Git.
Git still unavailable?
Close any terminal windows that were open during installation. Return to Windows PowerShell through search before checking again.
If the command still fails, help me troubleshoot Git on Windows.
Choose a repository for the history scan
A full-history scan checks commits that already exist. Choose a local repository you created or actively maintain so you have permission to investigate any findings.
- Choose one local repository that you own.
macOS
- Locate the repository folder in Finder.
- Switch back to Terminal from earlier.
- Type cd followed by one space.
- Drag the repository folder from Finder into Terminal.
- Press Return to move into the repository folder.
Windows
- Open the repository folder in File Explorer.
- Select the address bar at the top of File Explorer.
- Press Ctrl+C to copy the full folder path.
- Switch back to Windows PowerShell from earlier.
- Type cd followed by one space.
- Paste the copied path between double quotation marks.
- Press Enter to move into the repository folder.
Before you run this, picture the folder path you expect Git to return.
- Confirm the repository's top-level path by running this command:
git rev-parse --show-toplevel
What does this command do?
The git rev-parse --show-toplevel command asks Git for the top-level directory of the current working tree. The absolute path proves that your terminal is inside a Git repository.
You will see the absolute path to the repository folder. This is the path you will supply when you run the full-history scan later.
- Record the absolute path here: path/to/your/repository.
Repository path not appearing?
Confirm that you selected a folder containing an existing Git repository. Move into a different repository folder if Git cannot identify the current one.
If you need help, help me confirm my repository folder.
Your command line is ready. Next, you will create your GitGuardian account and install ggshield so your first secret scan can run locally.
Install and Authenticate ggshield
A local secret scanner can stop a leaked credential before Git records the commit. The ggshield command-line interface provides that checkpoint through GitGuardian.
This step connects your terminal to a GitGuardian account. Your selected repository stays untouched until the later history scan.
In this step, get ready to:
- Install the ggshield command-line tool.
- Create or access a free GitGuardian account.
- Authenticate ggshield with your GitGuardian workspace.
Check and install ggshield
Your terminal may already have ggshield installed. A version check reveals its current state before you change anything.
- Check for an existing ggshield installation by running:
ggshield --version
What does this command do?
The --version option asks ggshield to print its installed version. A version number confirms that your terminal can find the executable.
✔️ I see a version number
Your ggshield installation is ready. Continue to the authentication substep below.
ⓧ Command not found
The official installer adds ggshield to your user account. Choose your operating system below.
macOS
The installation script downloads ggshield for your user account. It may open a browser when installation reaches authentication.
- Install ggshield by running:
curl -sSfL https://raw.githubusercontent.com/GitGuardian/ggshield/main/scripts/install/install.sh | bash
What does this command do?
- The command downloads GitGuardian's official ggshield installation script.
- The shell runs the script for your user account.
- The script starts browser authentication after installation.
- Complete the browser flow if it opens.
- Return to the terminal after the browser confirms authentication.
The terminal reports that the installation has finished. ggshield is now available for the authentication check below.
Installer didn't finish?
Check that your terminal can reach GitHub. Restart the terminal if the installer reports a change to your executable path.
Ask for help with installing ggshield on macOS.
Windows
The PowerShell installation script downloads ggshield for your user account. It may open a browser when installation reaches authentication.
- Install ggshield by running this command in PowerShell:
irm https://raw.githubusercontent.com/GitGuardian/ggshield/main/scripts/install/install.ps1 | iex
What does this command do?
- The command downloads GitGuardian's official PowerShell installation script.
- PowerShell runs the script for your user account.
- The script starts browser authentication after installation.
- Complete the browser flow if it opens.
- Return to PowerShell after the browser confirms authentication.
PowerShell reports that the installation has finished. ggshield is now available for the authentication check below.
Installer didn't finish?
Check that PowerShell can reach GitHub. Restart PowerShell if the installer reports a change to your executable path.
Ask for help with installing ggshield on Windows.
Linux
The installation script downloads ggshield for your user account. It may open a browser when installation reaches authentication.
- Install ggshield by running:
curl -sSfL https://raw.githubusercontent.com/GitGuardian/ggshield/main/scripts/install/install.sh | bash
What does this command do?
- The command downloads GitGuardian's official ggshield installation script.
- The shell runs the script for your user account.
- The script starts browser authentication after installation.
- Complete the browser flow if it opens.
- Return to the terminal after the browser confirms authentication.
The terminal reports that the installation has finished. ggshield is now available for the authentication check below.
Installer didn't finish?
Check that your terminal can reach GitHub. Restart the terminal if the installer reports a change to your executable path.
Ask for help with installing ggshield on Linux.
Authenticate with GitGuardian
ggshield uses a Personal Access Token to connect your workstation to a GitGuardian workspace. The browser login provisions this credential without displaying it in your project files.
The installer may have completed this flow already. Running the login command confirms the stored authentication or starts a new browser flow.
- Start or confirm ggshield authentication by running:
ggshield auth login
What does this command do?
The command starts ggshield's interactive browser login. GitGuardian provisions a personal token for subsequent CLI requests.
- Use the account creation option in the browser if you need a free GitGuardian account.
- Sign in through the browser if you already have a GitGuardian account.
- Return to the terminal after the browser confirms authentication.
Your GitGuardian authentication is now stored for ggshield. That connection lets later scans send findings to your workspace.
Browser login didn't complete?
Check that the browser is using the intended GitGuardian account. Run the login command again if the browser closed before confirmation.
Ask for help with completing ggshield browser authentication.
Verify the installation and connection
The final check covers both parts of the setup. The version proves the executable is available. The API status proves that GitGuardian accepts the stored authentication.
Before you run these checks, what two signals would prove that your local setup is ready?
- Verify the ggshield version and GitGuardian connection by running:
ggshield --version
ggshield api-status
What do these checks prove?
- The first command prints the installed ggshield version.
- The second command contacts the GitGuardian API with your stored authentication.
- A healthy API status confirms that the connection works.
You'll see an installed version number. The API details include Status: healthy when authentication works.
Version or status check failed?
Restart the terminal if it cannot find ggshield after installation. Repeat the browser login if the API status reports an authentication problem.
Ask for help with verifying the ggshield setup.
Your scanner is installed and connected to GitGuardian. Next up, you'll create a practice repository with a fake credential that is safe to test.
Create a Practice Repository
Your GitGuardian account is authenticated. The ggshield CLI is ready in your terminal.
Testing with a live key would create the exact risk this project is designed to prevent. A separate Git practice repository gives you a safe place to trigger the scanner with a fake credential.
In this step, get ready to:
- Initialize a local Git repository named ggshield-secret-scanning-practice on your Desktop.
- Create config.py with a deliberately fake test credential.
- Stage config.py for the first commit.
Initialize the practice repository
A Git repository keeps its history and staging information inside a hidden .git directory. This isolated repository keeps the security test away from your real work.
- Build the isolated repository on your Desktop by running these commands:
cd ~/Desktop
mkdir ggshield-secret-scanning-practice
cd ggshield-secret-scanning-practice
git init
What do these commands do?
- The first cd places your terminal on the Desktop.
- The mkdir command creates the ggshield-secret-scanning-practice directory.
- The second cd moves your terminal into that directory.
- The git command adds the repository metadata inside .git.
You will see a confirmation that Git initialized an empty repository inside ggshield-secret-scanning-practice. That gives you a clean workspace for the intentional leak.
Repository not initialized?
- Inspect the existing folder first if your terminal says the directory name is already in use.
- Rename the existing folder if it contains work you want to keep.
- Check that your terminal prompt shows ggshield-secret-scanning-practice before retrying the initialization.
Help me fix the practice repository setup.
Add a fake test credential
Secret-shaped text lets you test detection without exposing an account. The value below comes from a documented GitGuardian detector example with no live service behind it.
The credential looks convincing on purpose. Your real passwords and API keys stay outside this repository.
- Create config.py inside ggshield-secret-scanning-practice by running this command:
cat > config.py <<'PY'
# Deliberately fake credentials for testing secret detection.
auth_tuple = ("totolao", "mY_s3cr3t_p@ssw0rd")
PY
What does this file contain?
- The quoted PY delimiter keeps the file content literal.
- The comment records why the credential exists.
- The auth_tuple variable holds the test username and password.
- The two values form a detector example that GitGuardian can identify.
- Confirm that Git sees the new file by running:
git status
What should you see?
Git lists config.py as an untracked file. This proves the file exists inside the repository without placing it in the next commit yet.
Don't see config.py?
- Confirm that your terminal prompt is inside ggshield-secret-scanning-practice.
- Make sure the ending PY sits alone on its own line.
- Retry the file creation command if the shell was still waiting for the closing delimiter.
Help me create the fake credential file.
✔️ Awesome, I've got everything!
Great. Double-check that config.py is saved inside ggshield-secret-scanning-practice.
ⓧ I'd like to double check the full code
# Deliberately fake credentials for testing secret detection.
auth_tuple = ("totolao", "mY_s3cr3t_p@ssw0rd")
Stage the fake credential
The staging area holds the exact snapshot Git includes in the next commit. Staging config.py prepares the controlled obstacle that the pre-commit hook will inspect.
Before you run this, consider whether config.py will appear as staged or untracked.
- Prepare the exact snapshot for the next commit by running these commands:
git add config.py
git status
What just changed?
- The staging command copies the current contents of config.py into Git's index.
- The status command reads the index to show what the next commit would contain.
- No commit has been created.
You will now see config.py listed in the staged changes section. You have prepared a safe credential leak for the scanner to catch.
Is config.py still untracked?
- Confirm that the filename is exactly config.py.
- Check that your terminal is still inside ggshield-secret-scanning-practice.
- Run the staging commands again after correcting the filename or directory.
Help me stage config.py correctly.
Your fake credential is staged inside an isolated repository. Next up, you will add the pre-commit hook and watch it stop this snapshot.
Block a Secret Commit
Your fake credential is staged in Git. A normal commit would place that value into the repository history.
A pre-commit hook gives GitGuardian a checkpoint before Git records the snapshot. The hook scans staged changes at the moment they are committed.
You'll install the hook in this practice repository. Then you'll test the guardrail with the staged credential.
In this step, get ready to:
- Install ggshield as a local pre-commit hook for ggshield-secret-scanning-practice.
- Trigger a protected commit to inspect the secret scan report.
Scope the hook to this repository
A local hook belongs only to the current repository. That scope keeps this practice setup isolated from your other Git projects.
- Return to the terminal where you staged config.py in ggshield-secret-scanning-practice.
- Install the local pre-commit hook by running this command:
ggshield install --mode local
What does this command do?
The --mode local option installs the default pre-commit hook in the current repository. The command creates .git/hooks/pre-commit.
Git calls this hook before creating each commit. The hook uses ggshield to scan the staged changes.
- Confirm the terminal reports that the local pre-commit hook was installed.
Your practice repository now has a guardrail attached to every commit. The next command proves that protection runs automatically.
Hook installation failed?
- Check that the terminal path ends with ggshield-secret-scanning-practice.
- Return to the authenticated terminal session from earlier.
- Re-run the installation command from this substep after correcting the repository location.
Help me diagnose the local hook installation.
Challenge the new guardrail
This is a controlled test using the deliberately fake credential from earlier. No live account is at risk.
Before you run the commit, do you think Git records the snapshot or returns control without creating it?
- Attempt the staged commit by running this command:
git commit -m "commit message"
Why did the commit stop?
The hook sends the staged change through ggshield before Git creates the commit. The scan finds the fake credential in config.py.
The output identifies the detected secret type. It also points to the line number.
The hook returns a failure status after the finding. Git leaves config.py staged without creating the commit.
- Find config.py in the reported finding.
- Locate the detected secret type in the output.
- Locate the reported line number in the output.
- Confirm the terminal does not show a successful commit summary.
You've caught the leak at the last safe moment. The fake credential remains outside the repository history.
Did the commit succeed?
- Stop before making another change if Git created the commit.
- Use the help link below to remove that local commit while preserving the staged config.py file.
- Reinstall the local hook with the installation command above before retrying the commit.
Help me restore the blocked-commit practice state.
The hook has proven its value before the credential reached history. Next, you'll remove the hardcoded value. You'll load it from an environment variable before making a clean commit.
Use an Environment Variable Instead
Your GitGuardian pre-commit hook has already stopped the fake credential before it entered your repository. That block proves your safety net is active.
Your application still needs a safe route to the credential. An environment variable supplies the value at runtime without placing it in config.py.
In this step, get ready to:
- Remove the fake credential from config.py.
- Read the credential from an environment variable.
- Commit the safe staged change after ggshield approves it.
Replace the hard-coded credential
Environment variables separate runtime configuration from tracked source code. os.getenv() reads a named value from the process environment.
- Switch back to config.py in your editor from earlier.
- Delete the line containing the fake test credential.
- Replace the file contents by copying the code below:
import os
# Read the credential at runtime without storing it in source control
api_key = os.getenv("API_KEY")
What does this code do?
- The os module gives the file access to environment variables.
- The os.getenv("API_KEY") call reads the value associated with API_KEY.
- The credential stays outside the source file.
- Save config.py.
- Search config.py for the fake credential text you removed.
You should see zero matches for the fake credential. The file should contain only the environment variable lookup.
Still see the fake credential?
Check that you deleted the entire credential value from config.py. Save the file after making the replacement.
Make sure the environment variable name appears inside quotes in the os.getenv() call.
Help me check why my Python configuration still contains a hard-coded credential.
✔️ Awesome, I've got everything!
Great. Double-check that you saved config.py before continuing.
ⓧ I'd like to double check the full code
import os
# Read the credential at runtime without storing it in source control
api_key = os.getenv("API_KEY")
Stage the corrected configuration
The Git staging area still holds the snapshot that contained the fake credential. Staging config.py again replaces that snapshot with your corrected version.
- Stage the corrected config.py file by running this command:
git add config.py
What does this command do?
This command updates the staged copy of config.py. Your next commit now uses the safe version from the editor.
- Inspect the staged snapshot by running this command:
git status
What does this command show?
This command summarizes the repository state. It shows which version of config.py is ready for the next commit.
You should see config.py listed as staged. This confirms the old staged snapshot has been replaced.
Config.py not shown as staged?
Confirm that your terminal is still inside the ggshield-secret-scanning-practice repository. Stage config.py again after saving it.
Help me work out why config.py is not staged in my practice repository.
Commit the safe change
Each commit triggers the installed ggshield hook against the staged content. This attempt tests whether removing the hard-coded credential closes the finding.
Before you run the commit, make a prediction about whether ggshield will block the corrected file again.
- Create the corrected commit by running this command:
git commit -m "Use environment variable for credential"
What happens during this commit?
- The installed hook scans the staged version of config.py before Git creates the commit.
- The -m option supplies the commit message.
- Git records the change only after the hook completes successfully.
You should see the hook complete without a secret finding. Git then prints a summary for the new commit.
Commit still blocked?
The staged snapshot may still contain the earlier credential. Save config.py before staging it again.
Search the current file for the fake credential text. Remove every remaining match before retrying the commit.
Help me diagnose why ggshield still blocks my commit after I removed the fake credential.
- Confirm the commit left no pending changes by running this command:
git status
What does the final check prove?
A clean repository state confirms that the corrected file reached the commit. The installed pre-commit hook remains ready for future changes.
You should see no pending changes for config.py. That confirms the safe configuration has been committed.
Still see pending changes?
Check whether config.py was edited again after the commit. Save any intended correction before staging it for another commit.
Help me understand why Git still shows pending changes after my successful commit.
That is the secure loop working from start to finish. Your code now requests the credential at runtime while the repository stores no hard-coded value.
Your protected commit is recorded. Next up, you will scan the complete history of your selected repository for secrets that may have slipped through earlier.
Scan Your Repository History
Your safe commit now passes the pre-commit hook. New commits in ggshield-secret-scanning-practice now have a guardrail.
Older commits remain in Git history after the current files become safe. The ggshield repository scan checks every commit in the personal repository you selected.
In this step, get ready to:
- Run a full-history scan against the selected personal repository.
- Interpret the terminal report as historical findings or a clean result.
Scan every commit
A repository scan examines committed snapshots across the selected repository. This wider scope can reveal a value that disappeared from the latest files but still exists in an older commit.
- Predict whether the repository's older commits will produce any findings.
- Scan every commit in the selected repository by running this command with its local path in the placeholder:
ggshield secret scan repo "[[REPOSITORY_PATH="path/to/your/repository"]]"
What does this command do?
- The repo subcommand selects repository scanning mode.
- The path tells ggshield which local repository to inspect.
- The scan checks commits across the repository's history.
- Removed values can still appear in older snapshots.
Your terminal now holds evidence from the repository's entire history. You'll see listed findings or a clean result confirming that no secrets were found.
Scan not completing?
Confirm that the placeholder contains the selected repository's local path. The target folder must contain a Git repository.
Ask for help with a repository scan that will not complete.
Confirm the report outcome
The completed report establishes whether the selected repository contains historical findings. A clean result confirms that the scan checked the history without detecting a secret.
- Review the completed report in your terminal.
- Classify the result as historical findings or a clean result.
- Keep the completed report visible for the checkpoint.
The scan leaves ggshield-secret-scanning-practice committed with its hook installed. Your completed terminal report is the visible proof that the selected repository's full history was checked.
Your repository history now has a recorded scan result. Next, you will open the GitGuardian dashboard to review its incident list.
Review Findings in GitGuardian
The full Git history scan from the previous step showed what the selected repository carries across older commits. That terminal report is evidence that now needs a review workflow.
The GitGuardian dashboard gives each finding an incident workflow. In this step, you will match the report to that workflow so every historical finding has a clear next action.
In this step, get ready to:
- Open the GitGuardian incident table for the full available time range.
- Match historical incidents to the findings in your terminal report.
- Confirm when an incident is ready to be marked resolved.
Open the historical incident view
The incident table connects each detected secret to its review status. Older entries can sit outside the dashboard's default time range even when they still require attention.
- Return to your authenticated GitGuardian account in your browser.
- Select Incident in the left sidebar.
- Set the time range to All time.
You will see the incident table for the complete time range. Historical entries can carry the From historical scan tag.
✔️ I see historical incidents
The dashboard has historical findings available for review. Each row represents a secret incident with its own evidence and status.
- Switch back to the history scan report in your terminal.
- Match the repository in each incident to the repository named in the terminal report.
- Select one historical incident from the table.
- Compare its secret type with the terminal report.
- Compare its affected file path with the terminal report.
- Compare its commit date with the terminal report.
The matching details confirm that you are reviewing the same exposure recorded by the full history scan.
ⓧ My scan found no secrets
A clean scan has no historical secret findings to match. The empty result still gives you a baseline for future scans.
- Switch back to the history scan report in your terminal.
- Confirm that the report records a clean result.
- Return to the GitGuardian incident table.
- Confirm that no historical incident matches the scanned repository.
The terminal report and dashboard now agree that this scan produced no incident requiring review.
Don't see a matching historical incident?
Confirm that the dashboard belongs to the same authenticated GitGuardian account used by the scanner. Keep the time range set to All time because older exposures use the date of their original commit.
Use the terminal report as your source for the repository name and finding details. Help me compare my history scan report with my GitGuardian incident table.
Confirm the resolution workflow
An incident reaches Resolved after the underlying exposure has been remediated. A real credential must be revoked before its incident is closed.
What counts as resolved?
Seeing a real credential in history can feel urgent. Revoking it at the provider cuts off the leaked credential's access.
Deleting a commit does not make a pushed credential safe. After revocation, remove the credential from current files and clean historical copies according to your repository policy.
✔️ The incident is remediated
This path applies when the exposed credential has already been revoked and the repository has been cleaned.
- Return to the remediated incident's detail page.
- Select Resolve.
- Choose the resolution reason that matches your remediation.
- Confirm that the incident status now reads Resolved.
The incident now records that its exposure has been addressed.
ⓧ The incident still needs action
An open incident preserves the signal that remediation is incomplete. Keep it open until the credential can no longer provide access.
- Leave the incident open in GitGuardian.
- Revoke the real credential at its provider.
- Remove the credential from the repository's current files.
- Clean its historical copies according to your repository policy.
- Return to the incident after remediation.
- Select Resolve.
- Choose the resolution reason that matches your remediation.
- Confirm that the incident status now reads Resolved.
The status now reflects the credential's actual security state.
Verify the incident review
The final check ties the terminal evidence to the dashboard workflow. It also confirms that a finding cannot be mistaken for a remediated incident.
Before you check, which details do you expect to match between the terminal report and the incident table?
- Return to the Incident table.
- Keep All time selected.
- Compare the history scan report with the listed historical incidents.
- Open a matching incident if the report contains a finding.
- Confirm that the Resolve control is available after remediation.
With findings, you will see matching incident details and a resolution control. With a clean report, you will see no matching historical incident for the scanned repository.
Strong finish. Your history scan now has a dashboard review workflow that keeps unresolved credentials visible until their access has been removed.
Secret mission
Run a Secret Incident Triage Drill
Turn one history-scan result into a professional incident response decision. You will classify the finding. Then you will build a revoke-first remediation plan with clear resolution evidence.
Clean Up Your Resources
Clean Up Your Resources
Choose whether to keep your project ready for future practice, pause your work, or remove the local practice repository. Your local repository and pre-commit hook create no ongoing costs.
Resources you used:
- The local ggshield-secret-scanning-practice repository with its pre-commit hook and safe configuration.
- Your GitGuardian dashboard incidents from the full-history scan.
Revoke Before Cleaning History
If the history scan found a real credential, revoke it with the credential provider before cleaning the repository. Deleting a commit does not make a pushed credential safe.
Keep everything running
No action is required. Choose this if you want to reuse the practice repository or continue reviewing your scan findings.
- Keep the ggshield-secret-scanning-practice folder on your computer.
- Leave the pre-commit hook installed so future commits in the practice repository remain protected.
- Review every unresolved dashboard incident before treating its credential as safe.
- Keep the full-history scan report as evidence of what the scan checked.
Pause - I'll come back to this later
No scanner process needs to stay running. Close your current tools while keeping the repository and scan findings available for your return.
- Revoke any real credential reported by the history scan before pausing.
- Close the GitGuardian dashboard after every urgent credential is revoked.
- Close the terminal session containing the history scan report.
- Keep the ggshield-secret-scanning-practice folder so its hook remains available for later practice.
- Return to unresolved incidents when you are ready to complete their remediation.
Delete - I don't want to use this again
Remove the local practice repository and close out the findings from your scan. Your existing personal repository stays in place.
Check Before Deleting
Deleting the practice folder removes its local files and commit history. Confirm that you do not need anything inside it before continuing.
macOS
- Use Finder to locate the ggshield-secret-scanning-practice folder.
- Drag the ggshield-secret-scanning-practice folder into the Trash.
- Check that the Trash contains the correct folder.
- Empty the Trash.
- Search for ggshield-secret-scanning-practice using Finder.
You should see no remaining copy of the practice folder.
Windows
- Use File Explorer to locate the ggshield-secret-scanning-practice folder.
- Drag the ggshield-secret-scanning-practice folder into the Recycle Bin.
- Check that the Recycle Bin contains the correct folder.
- Empty the Recycle Bin.
- Search for ggshield-secret-scanning-practice using File Explorer.
You should see no remaining copy of the practice folder.
- Return to the authenticated GitGuardian dashboard from earlier.
- Review each incident created by the full-history scan.
- Confirm whether each incident represents a live credential.
- Revoke every live credential with its provider.
- Complete the appropriate repository remediation for each incident.
- Mark each incident resolved after its remediation is complete.
The practice repository is now removed. Your reviewed incidents reflect the remediation work you completed.
Nice Work!
Nice Work!
You did it! You built a secret-scanning workflow with GitGuardian and ggshield that catches exposed credentials before they reach GitHub. You also audited a repository's full history for credentials that may already have leaked.
You've learned how to:
- Protect staged changes with a pre-commit hook that blocks a commit containing a fake credential. The scan identifies the secret type plus its line number before Git creates the commit.
- Remove a hard-coded credential from config.py. Load the value from an environment variable so the clean commit passes the scan.
- Audit a repository's full Git history for past exposure. Review each finding as a GitGuardian incident that can be remediated before it is marked resolved.
- Secret Mission: Complete an optional challenge to push your secret-scanning skills further.
Ready to quiz yourself?