diff --git a/.github/workflows/leaks.yml b/.github/workflows/leaks.yml new file mode 100644 index 0000000..cb31c43 --- /dev/null +++ b/.github/workflows/leaks.yml @@ -0,0 +1,48 @@ +name: leaks + +# Secrets, private AI session links and local workstation paths stay out of +# this public repository. The rules live in .gitleaks.toml. +on: + push: + branches: [main] + pull_request: + types: [opened, edited, synchronize, reopened] + +permissions: + contents: read + +env: + GITLEAKS_VERSION: 8.30.1 + GITLEAKS_SHA256: 551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb + +jobs: + leaks: + name: leaks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Install gitleaks + run: | + archive="$RUNNER_TEMP/gitleaks.tar.gz" + curl -fsSLo "$archive" "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" + echo "${GITLEAKS_SHA256} $archive" | sha256sum -c - + tar -xzf "$archive" -C "$RUNNER_TEMP" gitleaks + + - name: Scan files + run: '"$RUNNER_TEMP/gitleaks" dir . --redact --no-banner' + + # Edits to the description rerun this job, so the text is checked as posted. + - name: Scan pull request text and commit messages + if: github.event_name == 'pull_request' + env: + TITLE: ${{ github.event.pull_request.title }} + BODY: ${{ github.event.pull_request.body }} + BASE: ${{ github.event.pull_request.base.sha }} + HEAD: ${{ github.event.pull_request.head.sha }} + run: | + { printf '%s\n%s\n' "$TITLE" "$BODY"; git log --format=%B "$BASE..$HEAD"; } | + "$RUNNER_TEMP/gitleaks" stdin --redact --no-banner diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..0a72adf --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,17 @@ +# Secret and privacy rules for this public repository: gitleaks's default +# secret rules plus links and paths that must never be published. Add a rule +# here to extend every check (lefthook and CI read this file). +[extend] +useDefault = true + +[[rules]] +id = "private-ai-session-link" +description = "Private AI session link or session trailer" +regex = '''(?i)(claude\.ai/(code|chat|share|project)/|Claude-Session:|chatgpt\.com/(c|share|codex)/)''' +keywords = ["claude", "chatgpt"] + +[[rules]] +id = "local-workstation-path" +description = "Local workstation home directory path" +regex = '''(/Users|/home)/[A-Za-z0-9_.-]+/''' +keywords = ["/users/", "/home/"] diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..99e289e --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,11 @@ +# Secrets, private AI session links and local paths, by .gitleaks.toml. +# Install with `lefthook install`; CI runs the same rules. +pre-commit: + jobs: + - name: leaks + run: gitleaks git --pre-commit --staged --redact --no-banner + +commit-msg: + jobs: + - name: leaks + run: gitleaks stdin --redact --no-banner < {1}