Skip to content
Merged
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
48 changes: 48 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh
echo "Running Gitleaks pre-commit scan on staged changes (Peer-rust-backend)..."

mkdir -p .gitleaks_out
touch .gitleaks_out/gitleaks-precommit.json

# Prefer local gitleaks if available, fallback to Docker
if command -v gitleaks >/dev/null 2>&1; then
echo "⚡ Using local gitleaks binary"
SCAN_CMD="gitleaks detect \
--pipe \
--config=gitleaks.toml \
--report-format=json \
--report-path=.gitleaks_out/gitleaks-precommit.json \
--no-banner"
else
echo "Local gitleaks not found, using Docker fallback"
SCAN_CMD="docker run --rm -i -v \"$(pwd)\":/repo ghcr.io/gitleaks/gitleaks:v8.28.0 detect \
--pipe \
--config=/repo/gitleaks.toml \
--report-format=json \
--report-path=/repo/.gitleaks_out/gitleaks-precommit.json \
--no-banner"
fi

# Run scan on staged diff only
git diff --cached --unified=0 --no-color \
| grep '^+' \
| grep -v '^+++' \
| sh -c "$SCAN_CMD"
status=$?
if [ $status -ne 0 ]; then
echo "Possible secrets detected in staged changes!"
echo " See .gitleaks_out/gitleaks-precommit.json for details."
echo ""
echo "Commit aborted."
echo ""
echo "Reminder: Do NOT bypass with 'git commit --no-verify'."
echo "CI will still block your PR even if you bypass locally."
echo ""
echo "If this secret is actually required in the repo (false positive or approved usage),"
echo "you MUST meet with the CTO / Team Lead / DevOps to approve"
echo "and add it to the gitleaks ignore list."
exit 1
fi

echo "No secrets found. Commit allowed."
exit 0
20 changes: 20 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Security Scan

on:
pull_request:
branches:
- development
- Test
- main
push:
branches:
- development
- Test
- main

jobs:
gitleaks:
name: Run Gitleaks Scan
uses: peer-network/peer_global_security/.github/workflows/gitleaks.yml@main
with:
config: gitleaks.toml
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ dist
build

# Logs
*.log
*.log

# Gitleaks log
.gitleaks_out/
73 changes: 73 additions & 0 deletions README_gitleaks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# 🔒 Gitleaks Pre-Commit Hook (Peer-rust-backend)

This repository uses **[Gitleaks](https://github.com/gitleaks/gitleaks)** to prevent secrets (API keys, passwords, tokens, etc.) from being committed.

---

## 🚀 Setup

Run the setup script once:

```bash
chmod +x setup-hooks.sh
./setup-hooks.sh
```

This will:

- Configure Git to use .githooks/ as the hooks directory.
- Make .githooks/pre-commit executable.
- Ensure gitleaks is installed (v8.28.0).

If missing, the script will download the correct binary for your OS/architecture.

Confirm the hook is ready.

🛡️ Pre-Commit Scan
On every git commit, the hook will:

- Run a Gitleaks scan on staged changes only.
- Block the commit if potential secrets are detected.
- Write results to .gitleaks_out/gitleaks-precommit.json.

If a commit is blocked:

- Check .gitleaks_out/gitleaks-precommit.json for details.
- Remove or mask the secret before retrying.

Do not bypass with git commit --no-verify — CI will still block your PR.

---

###

Docker Fallback

If a local Gitleaks binary is missing, the pre-commit hook will fall back to Docker:

docker run --rm -i -v "$(pwd)":/repo ghcr.io/gitleaks/gitleaks:v8.28.0 detect ...

---

###
✅ Verifying Installation
To check that everything is set up correctly:

```
gitleaks version
```
# should print: 8.28.0

---

###
🧹 Ignore False Positives
If Gitleaks flags something that is not a real secret:

Talk to your Team Lead / DevOps.

They can add an exception to gitleaks.toml.

With this setup, secrets are scanned locally before every commit and again in CI, ensuring strong security across the repo. 🔐

Gitleaks is set 🚀
61 changes: 61 additions & 0 deletions gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
title = "Peer Rust Backend Gitleaks Config"

[[rules]]
id = "rust-backend-catch-common-secrets"
description = "Catch common secrets in Rust backend (API keys, JWTs, database passwords, tokens, private keys)"
regex = '''(?i)(ghp_[0-9A-Za-z]{36}|github_pat_[0-9A-Za-z_]{20,}|glpat-[0-9A-Za-z\-_]{20}|AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+|-----BEGIN( RSA| DSA| EC| OPENSSH)? PRIVATE KEY-----|token\s*=\s*["'][A-Za-z0-9_\-]{10,}["']|password\s*=\s*["'][^"']{6,}["']|api[_-]?key\s*[:=]\s*["'][A-Za-z0-9_\-]{10,}["'])'''
tags = ["rust", "backend", "api", "key", "secret"]

[[rules]]
id = "jwt-and-oauth-tokens"
description = "Detect JWTs, OAuth tokens, or long Base64-like secrets"
regex = '''eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+'''
tags = ["jwt", "token", "auth"]

[[rules]]
id = "database-and-service-creds"
description = "Detect Postgres, Redis, or service connection strings"
regex = '''(?i)(postgres(?:ql)?:\/\/[A-Za-z0-9:_@.\-\/]+|redis:\/\/[A-Za-z0-9:_@.\-\/]+|mongodb:\/\/[A-Za-z0-9:_@.\-\/]+)'''
tags = ["database", "rust", "service"]

[[rules]]
id = "aws-and-cloud-creds"
description = "Detect AWS, GCP, or generic cloud provider credentials"
regex = '''(?i)(AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|GOOG1E[A-Za-z0-9_-]{30,}|gcp_project_id\s*[:=]\s*["'][A-Za-z0-9_\-]{5,}["'])'''
tags = ["cloud", "aws", "gcp"]

[[rules]]
id = "rust-env-files"
description = "Detect sensitive environment variable values in .env or config.rs"
regex = '''(?i)(DATABASE_URL\s*=\s*["'][^"']+["']|JWT_SECRET\s*=\s*["'][^"']+["']|API_KEY\s*=\s*["'][A-Za-z0-9_\-]{10,}["']|SECRET_KEY\s*=\s*["'][A-Za-z0-9_\-]{10,}["'])'''
tags = ["rust", "dotenv", "config", "key"]

[rules.allowlist]
description = "Allow safe constants and test patterns"
regexes = [
'''(?i)test_(user|token|api|key|password)''',
'''(?i)example\.com''',
'''(?i)localhost''',
'''(?i)127\.0\.0\.1''',
'''(?i)env::var''',
'''(?i)std::env''',
'''(?i)println!''',
'''(?i)mock(|_data|_value)''',
'''(?i)sample(|_key|_token)''',
'''(?i)fake(|_jwt|_uuid|_token)'''
]

[pathDenylist]
description = "Exclude irrelevant or generated files"
regexes = [
'''^target/.*''',
'''^dist/.*''',
'''^build/.*''',
'''^logs?/.*''',
'''^tmp/.*''',
'''^\.env.*$''',
'''^\.github/workflows/.*''',
'''^\.git/.*''',
'''^node_modules/.*''',
'''^tests?/.*'''
]
52 changes: 52 additions & 0 deletions setup-hooks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/sh
set -e

echo "Setting up Git hooks..."

# Point Git to .githooks directory
git config core.hooksPath .githooks

# Ensure pre-commit is executable
chmod +x .githooks/pre-commit

echo "Git hooks installed. Pre-commit scan will now run automatically."

# Check if gitleaks is installed
if command -v gitleaks >/dev/null 2>&1; then
echo "⚡ Gitleaks already installed: $(gitleaks version)"
exit 0
fi

# Install Gitleaks if missing
VERSION="8.28.0"
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)

echo "Installing Gitleaks v$VERSION for $OS-$ARCH..."

case "$OS-$ARCH" in
linux-x86_64)
URL="https://github.com/gitleaks/gitleaks/releases/download/v$VERSION/gitleaks_${VERSION}_linux_x64.tar.gz"
;;
linux-aarch64)
URL="https://github.com/gitleaks/gitleaks/releases/download/v$VERSION/gitleaks_${VERSION}_linux_arm64.tar.gz"
;;
darwin-arm64)
URL="https://github.com/gitleaks/gitleaks/releases/download/v$VERSION/gitleaks_${VERSION}_darwin_arm64.tar.gz"
;;
darwin-x86_64)
URL="https://github.com/gitleaks/gitleaks/releases/download/v$VERSION/gitleaks_${VERSION}_darwin_x64.tar.gz"
;;
*)
echo "Unsupported OS/Arch ($OS-$ARCH). Please install manually:"
echo "https://github.com/gitleaks/gitleaks/releases/tag/v$VERSION"
exit 1
;;
esac

curl -sSL "$URL" -o gitleaks.tar.gz
tar -xvzf gitleaks.tar.gz gitleaks
sudo mv gitleaks /usr/local/bin/
rm -f gitleaks.tar.gz

echo "Installed Gitleaks v$(gitleaks version)"