improved precommit hook, to allow global installation

This commit is contained in:
Mick Grove 2025-07-28 10:25:11 -07:00
commit 787a5aaf22
4 changed files with 61 additions and 17 deletions

View file

@ -12,13 +12,13 @@ Kingfisher is a blazingly fast secretscanning and validation tool built in Ru
Kingfisher originated as a fork of [Nosey Parker](https://github.com/praetorian-inc/noseyparker) by Praetorian Security, Inc, and is built atop their incredible work and the work contributed by the Nosey Parker community.
Kingfisher extends Nosey Parker by:
1. Validating secrets in real time via cloud-provider APIs
2. Enhancing regex-based detection with source-code parsing for improved accuracy
3. Adding GitLab repository scanning support
4. Adding support for scanning Docker images via `--docker-image`
5. Providing Jira scanning capabilities
1. **Validating secrets** in real time via cloud-provider APIs
2. Enhancing regex-based detection with **source-code parsing** for improved accuracy
3. Adding **GitLab** repository scanning support
4. Adding support for scanning **Docker** images via `--docker-image`
5. Providing **Jira** scanning capabilities
6. Introducing a baseline feature that suppresses known secrets and reports only newly introduced ones
7. Offering native Windows support
7. Offering native **Windows** support
**MongoDB Blog**: [Introducing Kingfisher: Real-Time Secret Detection and Validation](https://www.mongodb.com/blog/post/product-release-announcements/introducing-kingfisher-real-time-secret-detection-validation)
@ -387,12 +387,19 @@ _If no token is provided Kingfisher still works for public repositories._
Run the provided helper script to add a hook that scans staged files before each commit:
```bash
./install-precommit-hook.sh
# local (current repo only ─ default)
./install-kingfisher-hook.sh
```
This creates `.git/hooks/pre-commit` that scans the files staged for commit with `kingfisher scan --no-update-check` and blocks the commit if any secrets are found.
```bash
# global (every repo on this machine)
./install-kingfisher-hook.sh --global
### Install a Pre-Receive Hook
```
Installs a global pre-commit hook at `$HOME/.git/hooks/pre-commit`; for every Git repository you use, it runs `kingfisher scan --no-update-check` on the staged files and cancels the commit if any secrets are detected.
To check incoming pushes on a server-side repository, install the pre-receive hook:

53
install-precommit-hook.sh Normal file → Executable file
View file

@ -1,17 +1,54 @@
#!/usr/bin/env bash
#
# Install a Git pre-commit hook that runs `kingfisher scan`.
# --global → install once for all repos using core.hooksPath
# --force → overwrite an existing pre-commit hook
#
set -euo pipefail
HOOK_DIR="$(git rev-parse --git-dir)/hooks"
MODE="local"
FORCE=0
while [[ $# -gt 0 ]]; do
case "$1" in
-g|--global) MODE="global" ;;
-f|--force) FORCE=1 ;;
-h|--help)
echo "Usage: $0 [--global] [--force]" && exit 0
;;
*) echo "Unknown flag: $1" >&2; exit 1 ;;
esac
shift
done
if [[ "$MODE" == "local" ]]; then
# ensure we're inside a Git repo
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) \
|| { echo "Not inside a Git repository" >&2; exit 1; }
HOOK_DIR="$(git rev-parse --git-dir)/hooks"
else
# global: honour existing core.hooksPath or default to ~/.git-hooks
HOOK_DIR=$(git config --global --get core.hooksPath || echo "$HOME/.git-hooks")
mkdir -p "$HOOK_DIR"
# if the user hasnt set core.hooksPath, do it now
if ! git config --global --get core.hooksPath >/dev/null; then
git config --global core.hooksPath "$HOOK_DIR"
echo "Set git config --global core.hooksPath to $HOOK_DIR"
fi
fi
HOOK_PATH="$HOOK_DIR/pre-commit"
if [ -e "$HOOK_PATH" ]; then
echo "Error: $HOOK_PATH already exists. Move or remove the existing hook to continue." >&2
if [[ -e "$HOOK_PATH" && $FORCE -eq 0 ]]; then
echo "Error: $HOOK_PATH already exists. Use --force to overwrite." >&2
exit 1
fi
cat > "$HOOK_PATH" <<'HOOK'
cat >"$HOOK_PATH" <<'HOOK'
#!/usr/bin/env bash
# Pre-commit hook to run Kingfisher scan on staged changes
# Git pre-commit hook to run Kingfisher on staged changes
set -euo pipefail
if ! command -v kingfisher >/dev/null 2>&1; then
@ -22,11 +59,11 @@ fi
git diff --cached --name-only -z | \
xargs -0 --no-run-if-empty kingfisher scan --no-update-check
status=$?
if [ "$status" -ne 0 ]; then
if [[ $status -ne 0 ]]; then
echo "Kingfisher detected secrets in staged files. Commit aborted." >&2
exit "$status"
exit $status
fi
HOOK
chmod +x "$HOOK_PATH"
echo "Pre-commit hook installed to $HOOK_PATH"
echo "Pre-commit hook installed to $HOOK_PATH ($MODE mode)"

0
install-prereceive-hook.sh Normal file → Executable file
View file

View file

@ -140,7 +140,7 @@ impl Docker {
std::fs::create_dir_all(out_dir)?;
let tar_path = out_dir.join("local_image.tar");
let status = Command::new("docker")
.args(["image", "save", image, "-o", tar_path.to_str().unwrap()])
.args(["image", "save", image, "-o", &tar_path.to_string_lossy()])
.status()
.with_context(|| "running docker save")?;
if !status.success() {
@ -202,7 +202,7 @@ impl Docker {
platform_resolver: Some(Box::new(linux_amd64_resolver)),
..Default::default()
});
let mut client = client;
let client = client;
let auth = registry_auth(&reference);
let accepted = vec![
oci_client::manifest::IMAGE_LAYER_MEDIA_TYPE,