Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env sh
# Secret scanner — LAC-2555
#
# Blocks commits that introduce plaintext credentials.
# Requires `gitleaks` locally; if not installed we print a warning and
# fall through — CI still runs the same scan on the PR, so this is
# defense-in-depth, not the only gate.
#
# Install:
# macOS → brew install gitleaks
# linux → https://github.com/gitleaks/gitleaks/releases

if command -v gitleaks >/dev/null 2>&1; then
if ! gitleaks protect --staged --redact --no-banner; then
echo ""
echo "gitleaks found a potential secret in staged changes."
echo "If real: rotate the credential first, then remove it from the diff."
echo "If a false positive: extend .gitleaks.toml allowlist or add an inline"
echo "'gitleaks:allow' comment. Do not disable the hook."
exit 1
fi
else
echo "gitleaks not installed — skipping local secret scan (CI still runs)."
echo " install: brew install gitleaks"
fi
30 changes: 30 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Secret scan — LAC-2555
#
# Fails the PR/push if plaintext credentials appear in the diff.
# Config lives in .gitleaks.toml at the repo root.
#
# Local defense-in-depth: .husky/pre-commit runs the same tool on staged
# changes when the gitleaks binary is installed.

name: gitleaks

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
gitleaks:
name: gitleaks
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 changes: 23 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# gitleaks config — LAC-2555
#
# Extends the built-in rule set. Allowlist covers files that legitimately
# contain placeholder credentials (example env files, docs, changelogs).
# When you add a new placeholder file that trips gitleaks, extend the
# `paths` list here rather than removing the scan.

[extend]
useDefault = true

[allowlist]
description = "Placeholder-credential files and generated docs"
paths = [
'''(^|/)\.env\.example(\..+)?$''',
'''(^|/)\.env\.example\.local$''',
'''(^|/)\.env\.test$''',
'''(^|/)\.env\.example\.production$''',
'''(^|/)README\.md$''',
'''(^|/)CHANGELOG\.md$''',
'''(^|/)LICENSE$''',
'''(^|/)docs/''',
'''(^|/)public/llms(-full)?\.txt$''',
]
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"test:coverage": "vitest run --coverage",
"test:browser": "vitest --config=vitest.config.browser.ts",
"test:node": "vitest --config=vitest.config.node.ts",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"postinstall": "git config core.hooksPath .githooks 2>/dev/null || true"
},
"dependencies": {
"@auth/drizzle-adapter": "1.11.1",
Expand Down
Loading