Add machine-level suppressions to the repo-sourced hooks
The live global pre-push hook was hand-edited to resolve suppressions from a
machine-level file (${SH_SECURITY_SUPPRESSIONS_DIR:-~/.config/sea-haven/security-review}/
<repo-basename>/suppressions.json) kept out of repo history, falling back to a
repo-local .security-review/suppressions.json. The repo-sourced hooks lacked it, so
install-hooks.sh --global would overwrite the live hook and lose the feature.
Port the prefer-machine/fallback-repo-local block into hooks/pre-push, align
hooks/pre-commit to the same (else a machine-suppressed finding passes at push but
blocks at commit), and document the path + SH_SECURITY_SUPPRESSIONS_DIR override +
basename-collision caveat in the README.
This commit is contained in:
parent
f4dd72ced9
commit
c217c5656d
3 changed files with 35 additions and 6 deletions
|
|
@ -32,10 +32,21 @@ security-review/install-hooks.sh --global
|
||||||
security-review/install-hooks.sh /path/to/repo
|
security-review/install-hooks.sh /path/to/repo
|
||||||
```
|
```
|
||||||
The global mode sets `git config --global core.hooksPath ~/.config/git/hooks`. Skip a repo with a
|
The global mode sets `git config --global core.hooksPath ~/.config/git/hooks`. Skip a repo with a
|
||||||
`.security-review-skip` file at its root; suppress a specific false positive in the repo's
|
`.security-review-skip` file at its root; bypass once with `git push --no-verify`. Caveat: a repo with
|
||||||
`.security-review/suppressions.json` (a written justification is required and is surfaced); bypass once
|
its own local `core.hooksPath` overrides the global hook — install per-repo there. See memory
|
||||||
with `git push --no-verify`. Caveat: a repo with its own local `core.hooksPath` overrides the global hook
|
`reference_global_security_review_hook`.
|
||||||
— install per-repo there. See memory `reference_global_security_review_hook`.
|
|
||||||
|
**Suppressing a false positive.** A written justification is required and is surfaced in the report. The
|
||||||
|
hooks resolve a suppressions file in this order:
|
||||||
|
1. **Machine-level (preferred), kept out of repo history:**
|
||||||
|
`${SH_SECURITY_SUPPRESSIONS_DIR:-~/.config/sea-haven/security-review}/<repo-basename>/suppressions.json`
|
||||||
|
(override the base dir with `SH_SECURITY_SUPPRESSIONS_DIR`). Keeps a suppression from becoming a
|
||||||
|
permanent in-history "ignore."
|
||||||
|
2. **Repo-local fallback:** `<repo>/.security-review/suppressions.json` (used only if no machine-level file exists).
|
||||||
|
|
||||||
|
Same JSON either place: `{"suppressions":[{"id":"<review.sh finding id>","justification":"…"}]}`. Caveat:
|
||||||
|
machine-level files are keyed by **repo basename**, so two repos sharing a name collide — fine for the
|
||||||
|
current single-namespace layout under `~/Documents/repositories`.
|
||||||
|
|
||||||
## No CI — by design
|
## No CI — by design
|
||||||
There is **no CI** wiring for this gate. For a solo dev the git hooks + nightly VM sweep are the backstop,
|
There is **no CI** wiring for this gate. For a solo dev the git hooks + nightly VM sweep are the backstop,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,15 @@ fi
|
||||||
# Nothing staged -> nothing to do.
|
# Nothing staged -> nothing to do.
|
||||||
git diff --cached --name-only --diff-filter=ACM | grep -q . || exit 0
|
git diff --cached --name-only --diff-filter=ACM | grep -q . || exit 0
|
||||||
SUP=()
|
SUP=()
|
||||||
[ -f "$REPO_ROOT/.security-review/suppressions.json" ] && SUP=(--suppressions "$REPO_ROOT/.security-review/suppressions.json")
|
# Suppressions: prefer a MACHINE-LEVEL file kept out of repo history
|
||||||
|
# (<dir>/<repo-basename>/suppressions.json), else fall back to a repo-local
|
||||||
|
# .security-review/suppressions.json. Keyed by repo basename — adequate for the
|
||||||
|
# current single-namespace layout under ~/Documents/repositories.
|
||||||
|
MACHINE_SUP="${SH_SECURITY_SUPPRESSIONS_DIR:-$HOME/.config/sea-haven/security-review}/$(basename "$REPO_ROOT")/suppressions.json"
|
||||||
|
if [ -f "$MACHINE_SUP" ]; then
|
||||||
|
SUP=(--suppressions "$MACHINE_SUP")
|
||||||
|
elif [ -f "$REPO_ROOT/.security-review/suppressions.json" ]; then
|
||||||
|
SUP=(--suppressions "$REPO_ROOT/.security-review/suppressions.json")
|
||||||
|
fi
|
||||||
# ${SUP[@]+"${SUP[@]}"} = bash-3.2-safe expansion of a possibly-empty array under set -u.
|
# ${SUP[@]+"${SUP[@]}"} = bash-3.2-safe expansion of a possibly-empty array under set -u.
|
||||||
exec bash "$REVIEW_SH" --scanners-only ${SUP[@]+"${SUP[@]}"} "$REPO_ROOT"
|
exec bash "$REVIEW_SH" --scanners-only ${SUP[@]+"${SUP[@]}"} "$REPO_ROOT"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,16 @@ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 0
|
||||||
REVIEW_SH="${SH_REVIEW_SH:-$HOME/Documents/repositories/orchestrator/security-review/review.sh}"
|
REVIEW_SH="${SH_REVIEW_SH:-$HOME/Documents/repositories/orchestrator/security-review/review.sh}"
|
||||||
if [ -f "$REVIEW_SH" ]; then
|
if [ -f "$REVIEW_SH" ]; then
|
||||||
SUP=()
|
SUP=()
|
||||||
[ -f "$REPO_ROOT/.security-review/suppressions.json" ] && SUP=(--suppressions "$REPO_ROOT/.security-review/suppressions.json")
|
# Suppressions: prefer a MACHINE-LEVEL file kept out of repo history
|
||||||
|
# (<dir>/<repo-basename>/suppressions.json), else fall back to a repo-local
|
||||||
|
# .security-review/suppressions.json. Keyed by repo basename — adequate for the
|
||||||
|
# current single-namespace layout under ~/Documents/repositories.
|
||||||
|
MACHINE_SUP="${SH_SECURITY_SUPPRESSIONS_DIR:-$HOME/.config/sea-haven/security-review}/$(basename "$REPO_ROOT")/suppressions.json"
|
||||||
|
if [ -f "$MACHINE_SUP" ]; then
|
||||||
|
SUP=(--suppressions "$MACHINE_SUP")
|
||||||
|
elif [ -f "$REPO_ROOT/.security-review/suppressions.json" ]; then
|
||||||
|
SUP=(--suppressions "$REPO_ROOT/.security-review/suppressions.json")
|
||||||
|
fi
|
||||||
echo "security-review: scanning $REPO_ROOT (scanners-only) before push..." >&2
|
echo "security-review: scanning $REPO_ROOT (scanners-only) before push..." >&2
|
||||||
# ${SUP[@]+"${SUP[@]}"} = bash-3.2-safe expansion of a possibly-empty array under set -u.
|
# ${SUP[@]+"${SUP[@]}"} = bash-3.2-safe expansion of a possibly-empty array under set -u.
|
||||||
if ! bash "$REVIEW_SH" --scanners-only ${SUP[@]+"${SUP[@]}"} "$REPO_ROOT"; then
|
if ! bash "$REVIEW_SH" --scanners-only ${SUP[@]+"${SUP[@]}"} "$REPO_ROOT"; then
|
||||||
|
|
|
||||||
Reference in a new issue