Skip to content

Commit 79965cc

Browse files
Ubuntuclaude
andcommitted
chore: add gitleaks secret scanning (CI workflow + husky pre-commit)
Why: prevent accidental secret commits from a single, well-known scanner (gitleaks). Two layers — server-side via GitHub Action so nothing slips past `git commit --no-verify`, and local via husky pre-commit hook so devs get fast feedback before pushing. Lessons learnt: husky's pre-commit hook gracefully no-ops with a warning if gitleaks isn't installed locally; CI is still the source of truth. The .gitleaks.toml allowlist covers .env.example, CHANGELOG.md, and pnpm-lock.yaml to avoid false positives. Summary: - Add .github/workflows/secret-scan.yml running gitleaks/gitleaks-action@v2 on every PR and push to main. - Add .gitleaks.toml extending default rules with project-specific allowlist paths. - Add husky as a devDependency, .husky/pre-commit running `gitleaks protect --staged`, and update prepare script. - Document setup in README and CHANGELOG. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3589d32 commit 79965cc

7 files changed

Lines changed: 106 additions & 1 deletion

File tree

.github/workflows/secret-scan.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Secret scan
2+
3+
# Server-side secret scan. Runs on every PR and every push to main, so it
4+
# cannot be bypassed by `git commit --no-verify`. The husky pre-commit hook
5+
# (.husky/pre-commit) provides the same check locally for faster feedback.
6+
7+
on:
8+
pull_request:
9+
push:
10+
branches: [main]
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
gitleaks:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
with:
22+
# gitleaks needs full history so it can scan every commit on the
23+
# branch, not just the latest one.
24+
fetch-depth: 0
25+
26+
- name: Run gitleaks
27+
uses: gitleaks/gitleaks-action@v2
28+
env:
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitleaks.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# gitleaks configuration — extends the default ruleset with project-specific
2+
# allowlist entries. See https://github.com/gitleaks/gitleaks#configuration
3+
# for the full reference.
4+
5+
[extend]
6+
# Inherit gitleaks' built-in rules (AWS keys, GitHub tokens, generic
7+
# high-entropy strings, etc.). We only add allowlists below.
8+
useDefault = true
9+
10+
[allowlist]
11+
description = "Project-wide allowlist for files that legitimately contain pattern matches"
12+
13+
paths = [
14+
# .env.example only contains keys (no values) — safe to commit, used as
15+
# a template for local .env files.
16+
'''\.env\.example''',
17+
# CHANGELOG references commit hashes which can match the
18+
# "generic-api-key" pattern at high entropy.
19+
'''CHANGELOG\.md''',
20+
# pnpm-lock.yaml contains content-addressed package hashes that can trip
21+
# entropy-based detection.
22+
'''pnpm-lock\.yaml''',
23+
]

.husky/pre-commit

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env sh
2+
# Pre-commit hook: scan staged changes for secrets via gitleaks.
3+
#
4+
# Skipped (with a warning) if gitleaks is not installed locally — the CI
5+
# secret-scan workflow still runs on every push to enforce coverage. Local
6+
# enforcement just gives faster feedback before the push.
7+
8+
if ! command -v gitleaks >/dev/null 2>&1; then
9+
echo ""
10+
echo " gitleaks not installed locally — skipping pre-commit secret scan."
11+
echo " Install for local enforcement:"
12+
echo " macOS: brew install gitleaks"
13+
echo " other: https://github.com/gitleaks/gitleaks#installing"
14+
echo " CI runs the same scan on every push, so missed catches still fail builds."
15+
echo ""
16+
exit 0
17+
fi
18+
19+
if ! gitleaks protect --staged --no-banner --redact; then
20+
echo ""
21+
echo " gitleaks detected potential secrets in your staged changes."
22+
echo " Resolve the finding above (or add a path to .gitleaks.toml allowlist)"
23+
echo " before committing. To bypass for a known false positive:"
24+
echo " git commit --no-verify"
25+
echo " …but the CI scan will still run, so prefer fixing the allowlist."
26+
echo ""
27+
exit 1
28+
fi

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
## Unreleased
44

55
- Add WalletConnect support so signers can pair mobile wallets via QR (2026-04-27).
6+
- Add gitleaks-based secret scanning: server-side via GitHub Action and local via husky pre-commit hook (2026-04-27).

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ TODO
7575

7676
- Built with Svelte and Viem
7777

78+
# Secret scanning
79+
80+
This repo runs [gitleaks](https://github.com/gitleaks/gitleaks) on every PR and push to `main` ([.github/workflows/secret-scan.yml](.github/workflows/secret-scan.yml)) — that check is the source of truth and cannot be bypassed by `git commit --no-verify`.
81+
82+
For faster local feedback, [husky](https://typicode.github.io/husky) wires the same scan into a pre-commit hook ([.husky/pre-commit](.husky/pre-commit)). It runs automatically after `pnpm install` if `gitleaks` is present on your `PATH`. Install locally with:
83+
84+
```shell
85+
brew install gitleaks # macOS
86+
# or see https://github.com/gitleaks/gitleaks#installing
87+
```
88+
89+
If gitleaks isn't installed, the hook prints a warning and exits cleanly — the CI scan still catches anything missed locally. Project-specific allowlist entries live in [.gitleaks.toml](.gitleaks.toml).
90+
7891
# Support
7992

8093
- [Join Discord for any questions](https://tradingstrategy.ai/community).

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"dev": "vite dev",
99
"build": "vite build",
1010
"preview": "vite preview",
11-
"prepare": "svelte-kit sync || echo ''",
11+
"prepare": "svelte-kit sync || echo '' && husky || echo ''",
1212
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
1313
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
1414
},
@@ -20,6 +20,7 @@
2020
"@tailwindcss/vite": "^4.2.2",
2121
"bits-ui": "^2.17.3",
2222
"clsx": "^2.1.1",
23+
"husky": "^9.1.7",
2324
"svelte": "^5.55.2",
2425
"svelte-check": "^4.4.6",
2526
"tailwind-merge": "^3.5.0",

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)