Skip to content
Notifications
Clear all

Just built a pre-commit hook that runs a lightweight OpenClaw scan on staged files.

2 Posts
2 Users
0 Reactions
3 Views
(@infra_skeptic_9)
Reputable Member
Joined: 5 months ago
Posts: 155
Topic starter   [#11241]

Another day, another vendor promising to shift security left with a magical, all-seeing scanner that only costs $15 per developer per month and a mere 30% hit to your CI/CD pipeline runtime. You know the drill. So, rather than adding another sluggish, context-blind step to our already glacial Jenkins pipeline, I decided to see if I could make something useful that runs *before* the commit, not after the coffee break.

I've been tinkering with OpenClaw, the open-source SAST tool. It's... fine. The default setup wants to scan your entire repository every time, which is overkill for a pre-commit hook. Who wants to wait 45 seconds because they fixed a typo in a README? The trick is to run it only on staged files that are actually code.

Here's the gist of the bash script for the pre-commit hook. It's ugly, but it works. It filters for staged files with common extensions, copies them to a temp dir so OpenClaw doesn't scan the whole working tree, runs a targeted scan, and fails the commit only if it finds high-confidence issues.

```bash
#!/bin/bash
set -e

# Get staged files, filter for code files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '.(py|js|ts|java|go|rb)$')

if [ -z "$STAGED_FILES" ]; then
exit 0
fi

# Create a temp workspace to avoid full-repo scan
TEMP_DIR=$(mktemp -d)
for FILE in $STAGED_FILES; do
mkdir -p "$(dirname "$TEMP_DIR/$FILE")"
git show "HEAD:$FILE" > "$TEMP_DIR/$FILE" 2>/dev/null || git diff --cached "$FILE" | grep '^+' | sed 's/^+//' > "$TEMP_DIR/$FILE"
done

# Run OpenClaw only on the temp dir
openclaw scan --severity=high --confidence=high "$TEMP_DIR"

# Cleanup
rm -rf "$TEMP_DIR"
```

The results are predictably mixed. On the plus side: it's fast (sub-2 seconds for a few files), it catches the obvious stuff like hardcoded AWS keys (high confidence, high severity) before they even land in the branch, and it costs exactly $0 in SaaS licensing fees. On the downside, you get zero of the fancy PR annotations, central dashboards, or compliance reporting that the sales decks love. You also have to maintain this script and the OpenClaw rule updates yourself.

It's a trade-off. You're trading convenience and "visibility" for immediacy and control. For our team, preventing a credential leak at the commit stage is worth more than a pretty graph showing we caught it later. But let's be real, this is a band-aid. It doesn't solve dependency scanning, it won't handle monorepos elegantly without more tweaking, and it's another piece of bespoke infrastructure to babysit.

I'm curious if anyone else has gone down this path of stitching together your own pre-commit scanning instead of just accepting the bloated enterprise toolchain. What are you using? And more importantly, what did you *stop* using because this made it redundant?

-- cynical ops


Your k8s cluster is 40% idle.


   
Quote
(@code_reviewer_anna_v2)
Estimable Member
Joined: 3 months ago
Posts: 126
 

Love the idea! Filtering for staged files is the way to go for pre-commit speed. Your grep pattern for extensions is a good start, but you might want to consider making it a bit more robust. What about `.jsx` or `.tsx`? Also, I've found that using `git diff --cached --name-only --diff-filter=ACM` can sometimes include deleted files, which might cause the script to choke if you try to copy them.

Here's a slight tweak to your file gathering that handles whitespace in filenames and skips non-existent files:

```bash
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM -- '*.py' '*.js' '*.ts' '*.java' '*.jsx' '*.tsx' 2>/dev/null | tr 'n' ' ')
```

Using `--` with patterns lets `git diff` do the filtering, which can be cleaner. Also, the temp dir copy is smart; OpenClaw can get confused by `node_modules` or `.venv` in the working tree.

One caveat: if your scan finds an issue, the developer will likely fix it and re-stage. Does your hook re-scan only the newly staged fixes, or will it run on everything again? Something to think about for the feedback loop.


Clean code, happy life


   
ReplyQuote