How git-secrets Uses Git Hooks to Stop Credential Leaks Before They Happen
Hook
Every 30 seconds, someone commits AWS credentials to a public GitHub repository. git-secrets exists because the human cost of ‘just being careful’ is measurably, catastrophically insufficient.
Context
The problem of accidentally committed secrets is as old as version control itself. Developers work with credentials locally, copy-paste from documentation, hardcode values during debugging, and inevitably forget to remove them before committing. By the time you realize an AWS access key made it into your repository history, it’s too late—even if you rewrite history, GitHub has already indexed it, security researchers have scraped it, and automated bots are actively scanning for exactly this mistake. Traditional solutions like manual code review or post-commit scanning address the problem too late. AWS Labs created git-secrets to solve this at the source: preventing the commit from happening in the first place. Rather than building a complex daemon or requiring server-side infrastructure, the tool takes advantage of Git’s native hook system—a lightweight, client-side mechanism that already exists in every Git repository. This architectural choice makes git-secrets simple to understand, easy to install, and invisible during normal development workflows.
Technical Insight
git-secrets works by installing three Git hooks: pre-commit, commit-msg, and prepare-commit-msg. When you run git secrets --install in a repository, it creates these hook scripts that intercept your commit operations. Before Git finalizes a commit, the pre-commit hook invokes git secrets --scan against all staged files, scanning for patterns that match prohibited secrets.
The pattern matching system uses two types of regular expressions stored in your Git config: prohibited patterns (things that should never appear) and allowed patterns (exceptions to prohibited patterns). When you run git secrets --register-aws, it adds patterns like (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16} to catch AWS Access Key IDs. If a match is found, git-secrets checks whether it also matches an allowed pattern—for example, the documentation example key AKIAIOSFODNN7EXAMPLE is explicitly allowed to prevent false positives.
Here’s what a typical setup looks like:
cd /path/to/my/repo
git secrets --install
git secrets --register-aws
After installation, your .git/hooks/pre-commit file contains a script that executes git-secrets scanning. When you attempt to commit, the hook runs:
git secrets --scan
If you want to add custom patterns for your organization’s internal secrets, you can extend the configuration:
git secrets --add 'my-company-secret-[A-Z0-9]{20}'
git secrets --add --allowed 'my-company-secret-EXAMPLE'
One of git-secrets’ most powerful features is the provider system. Providers are external executables that dynamically generate prohibited patterns at scan time. The built-in AWS provider reads your ~/.aws/credentials file and outputs your actual credentials as patterns to detect:
git secrets --add-provider -- git secrets --aws-provider
This means if your real AWS secret access key is in your credentials file, git-secrets will prevent you from committing it even if it doesn’t match the general AWS pattern regex. The provider concept allows for sophisticated integrations—you could write a provider that queries your organization’s secret management system and outputs currently-active API keys.
For repositories with existing history, git-secrets provides a way to audit all commits retroactively:
git secrets --scan-history
This is invaluable before open-sourcing a private repository or conducting security audits. The scan walks through every revision in your Git history and applies the same pattern matching, reporting any secrets found with file names, line numbers, and the matched text.
The architecture’s elegance lies in its simplicity: it’s a shell script that leverages Git’s existing infrastructure rather than reinventing it. All configuration lives in Git’s config system (accessible via git config), patterns are standard regular expressions, and the hooks use the same mechanism that developers already understand from Git’s built-in hook system.
Gotcha
The fundamental limitation of git-secrets is right there in the README’s warning: these patterns are “not guaranteed to catch them all.” Pattern-based detection is inherently reactive—you can only detect what you know to look for. If your secrets don’t match the regex patterns you’ve configured, they’ll sail right through. Base64-encoded secrets, obfuscated credentials, or novel secret formats won’t be caught unless you’ve explicitly added patterns for them. Additionally, git-secrets only protects the repositories where you’ve manually installed it. If you clone a new repository and forget to run git secrets --install, you’re working without protection. The global template approach helps (git config --global init.templateDir ~/.git-templates/git-secrets), but it requires every developer to configure it—there’s no organizational enforcement mechanism. If one team member doesn’t install it, they become the weak link. Being written as a shell script also creates portability challenges. While it works on Linux and macOS out of the box, Windows users need PowerShell or a Unix-like environment (the repository provides an install.ps1 script for Windows installation). More importantly, the shell implementation may make extending git-secrets more difficult than if it were written in a modern language with proper testing infrastructure.
Verdict
Use git-secrets if you’re working with AWS credentials in local development and want a lightweight, zero-configuration-after-install safety net that lives entirely in your Git workflow. It’s perfect for teams that prefer simple, transparent tools over complex infrastructure, and it’s particularly valuable when combined with the global template setup to protect all future repositories automatically. The AWS pattern detection is mature and well-tested, and the provider system offers genuine extensibility for teams with custom secrets. Skip it if you need guaranteed detection (nothing pattern-based can offer this—pair it with server-side scanning), if you’re in a Windows-heavy environment where shell scripts are problematic, or if you need centralized enforcement across an organization where individual installation is a non-starter. In those cases, consider server-side secret scanning solutions that don’t depend on individual developer installation and configuration.