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
|
||||
```
|
||||
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/suppressions.json` (a written justification is required and is surfaced); bypass once
|
||||
with `git push --no-verify`. Caveat: a repo with its own local `core.hooksPath` overrides the global hook
|
||||
— install per-repo there. See memory `reference_global_security_review_hook`.
|
||||
`.security-review-skip` file at its root; bypass once with `git push --no-verify`. Caveat: a repo with
|
||||
its own local `core.hooksPath` overrides the global 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
|
||||
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.
|
||||
git diff --cached --name-only --diff-filter=ACM | grep -q . || exit 0
|
||||
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.
|
||||
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}"
|
||||
if [ -f "$REVIEW_SH" ]; then
|
||||
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
|
||||
# ${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
|
||||
|
|
|
|||
Reference in a new issue