Git pre-commit hook for preventing accidental secret commits
Project description
keygate
A Git pre-commit hook that prevents accidental commits of API keys and passwords.
Why you need this
During development, it's easy to write API keys or passwords directly in code. Once committed with git commit, they become permanently embedded in the repository history.
Even if you delete them later, they remain accessible from past commits — and once exposed on GitHub or similar platforms, they can be exploited almost immediately. There are countless cases of AWS key leaks resulting in massive unexpected bills.
keygate automatically checks before every commit and blocks anything that looks dangerous.
What it detects
- AWS Access Keys
- OpenAI API Keys
- GitHub Tokens
- Slack Tokens
- Private Keys (PEM format)
- JWT Tokens
- Long random-looking strings (high-entropy detection)
- Variable names like
api_key,password,secretpaired with values
Getting started
Step 1: Install
keygate is a Python CLI tool. The easiest way to install it is via pipx.
pipx install keygate
If you don't have
pipx, install it withpip install pipx. Usingpipxmakes thekeygatecommand available from any project directory.
Step 2: Enable the hook
A "hook" is a script Git runs automatically at certain points. Running keygate install-hook makes keygate run automatically on every git commit.
cd path/to/your-project
keygate install-hook
That's all the setup you need.
Step 3: Use it
Just run git add and git commit as usual. If nothing dangerous is found, nothing happens.
If a secret is detected, the commit is blocked like this:
[BLOCK] High confidence secret detected
File: config.py:12
Rule: aws-access-key
Score: 100
Reason:
AWS Access Key detected; sensitive context detected
Remediation:
- Remove the key from the code
- Rotate the AWS credentials immediately
- Use environment variables or AWS IAM roles instead
To ignore:
Add comment: # keygate: ignore reason="..."
How to read the output:
File: config.py:12— the file and line number where the issue was foundRule: aws-access-key— what was detectedScore: 100— severity (70+ blocks the commit; 40–69 warns only)Reason— why it was flaggedRemediation— suggested fixes
Manual scan
You can also scan without using the hook.
git add .
keygate scan
This scans git diff --cached (staged changes only).
Handling false positives
keygate errs on the side of caution, so it may occasionally flag things that aren't real secrets. There are three ways to deal with this.
Option 1: Inline ignore comment
Suppresses detection for that specific line. A reason is required.
api_key = "dummy-key-for-testing" # keygate: ignore reason="test data"
Option 2: Allowlist paths or patterns
Create a keygate.toml file in your project root and specify paths or patterns to exclude.
[allowlist]
paths = ["vendor/*", "third_party/*"] # ignore code you don't own
patterns = ["dummy", "example"] # ignore lines containing these words
Note: Adding
tests/*to the allowlist globally will cause keygate to miss real secrets embedded in test code. Use option 1 (inline ignore) or option 3 (baseline) for false positives in tests.
Option 3: Baseline — register existing findings to ignore
Useful when you only want to catch newly added secrets, not existing ones.
keygate baseline create
The current findings are saved to .keygate.baseline.json. From that point on, the same findings are ignored. The file looks like this:
{
"version": 1,
"entries": [
{
"fingerprint": "e5282a7860678bc768d280eb3e77d2ca8a44286357c743dd024d74fe0605fe09",
"file_path": "src/app/config.py",
"line_number": 42,
"rule_id": "url-credentials",
"created_at": "2026-04-22T09:30:00+00:00"
}
]
}
The fingerprint is a SHA256 hash of file_path + line_number + matched string. The actual secret value is never stored, so committing the baseline file to Git is safe.
To add newly discovered findings to the baseline:
keygate baseline update
Sharing with your team
We recommend committing .keygate.baseline.json to Git so the whole team uses the same ignore list.
git add .keygate.baseline.json
git commit -m "Add keygate baseline"
New team members only need to run pipx install keygate and keygate install-hook — the shared baseline is picked up automatically.
Configuration (optional)
The defaults work well out of the box, but you can customize behavior by creating keygate.toml in your project root.
[scan]
entropy_threshold = 4.2 # threshold for random-looking strings (lower = stricter)
block_score = 70 # commits are blocked at this score or above
[allowlist]
paths = ["vendor/*"]
patterns = ["dummy", "example"]
[baseline]
path = ".keygate.baseline.json"
If no config file is present, defaults are used.
FAQ
Q. I accidentally committed a secret. What should I do?
A. Revoke (rotate) the key immediately. Removing it from Git history is not enough. Assume any leaked key has already reached an attacker.
Q. How do I temporarily disable the hook?
A. Use git commit --no-verify to skip all hooks including keygate. Not recommended for regular use.
Q. How do we share this across a team?
A. Commit keygate.toml and .keygate.baseline.json to Git. Each team member needs to run keygate install-hook individually.
Disclaimer
keygate is a best-effort detection tool. Please understand the following before use.
- Detection is not guaranteed: Unknown secret formats, obfuscated values, or custom formats may not be detected (false negatives).
- False positives can occur: Non-secret strings may be flagged. Use allowlist / baseline / inline ignore to address them.
- Not a replacement for proper secret management: This tool is an additional safeguard at commit time. Secrets should be managed via environment variables, secret managers, or KMS — never stored in the repository.
- Hooks can be bypassed:
git commit --no-verifyskips all hooks. For organizational enforcement, combine with server-side checks (pre-receive hooks, CI scanning, etc.). - You are responsible for any leaks caused by missed detections: The authors and contributors accept no liability for damages arising from use of this tool (see LICENSE for details).
- If a secret is detected, rotate the key promptly: Even if the commit was blocked, the value may remain in local files, editor history, clipboard, or other devices.
This tool is designed as a last-resort safety net to catch human mistakes — not as a substitute for doing secret management correctly.
License
Distributed under the MIT License. Free to use, modify, and redistribute, including for commercial use. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keygate-0.1.2.tar.gz.
File metadata
- Download URL: keygate-0.1.2.tar.gz
- Upload date:
- Size: 23.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
428817e37cd78c86497cee1ad816679940f9cad8f3217a2bfe1f9a9d08a6ca03
|
|
| MD5 |
aea86f0d0f36caaf1b22da13a826abeb
|
|
| BLAKE2b-256 |
2a3e61fc151fe8a7c392562e22da85ea66f0e6db263cbf04f6edff1148eb3f3b
|
Provenance
The following attestation bundles were made for keygate-0.1.2.tar.gz:
Publisher:
publish.yml on kanekoyuichi/keygate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keygate-0.1.2.tar.gz -
Subject digest:
428817e37cd78c86497cee1ad816679940f9cad8f3217a2bfe1f9a9d08a6ca03 - Sigstore transparency entry: 1361150986
- Sigstore integration time:
-
Permalink:
kanekoyuichi/keygate@9f2e98fd67348bd825cc4fce4171844191c522de -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/kanekoyuichi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9f2e98fd67348bd825cc4fce4171844191c522de -
Trigger Event:
push
-
Statement type:
File details
Details for the file keygate-0.1.2-py3-none-any.whl.
File metadata
- Download URL: keygate-0.1.2-py3-none-any.whl
- Upload date:
- Size: 16.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3167d6d64fa1022544eb3e049c09de9240baa11ef08090756f1615e7dcd0a45
|
|
| MD5 |
3f912c2912fb7ba5d83d37fd86fbeafc
|
|
| BLAKE2b-256 |
401aaa9f41056e8bd9a168890a4bf3e6ca43a0b969fff3251df8c4cf36d99dfe
|
Provenance
The following attestation bundles were made for keygate-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on kanekoyuichi/keygate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keygate-0.1.2-py3-none-any.whl -
Subject digest:
a3167d6d64fa1022544eb3e049c09de9240baa11ef08090756f1615e7dcd0a45 - Sigstore transparency entry: 1361150989
- Sigstore integration time:
-
Permalink:
kanekoyuichi/keygate@9f2e98fd67348bd825cc4fce4171844191c522de -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/kanekoyuichi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9f2e98fd67348bd825cc4fce4171844191c522de -
Trigger Event:
push
-
Statement type: