Git Secret Leak Detection

If you like this project, consider supporting me on Buy Me a Coffee ☕️


tags:


Overview

Git secret leak detection covers the discovery, verification, cleanup, and prevention of credentials accidentally committed to Git history. Обнаружение утечек секретов в Git включает поиск, верификацию, очистку и предотвращение попадания учётных данных в историю Git.

Common use cases / Типовые сценарии:

Status / Актуальность:

[!TIP] Use Gitleaks as the default fast scanner, then add TruffleHog when you need verification, and use a secret manager for long-term remediation rather than storing secrets in Git at all. Используйте Gitleaks как основной быстрый сканер, затем добавляйте TruffleHog для верификации, а для долгосрочного решения храните секреты в менеджере секретов, а не в Git.


Installation & Configuration

Gitleaks —

Default ports: N/A (CLI tool) Config file: .gitleaks.toml (project root)

# macOS
brew install gitleaks  # Install via Homebrew / Установка через Homebrew

# Linux — download binary
wget https://github.com/gitleaks/gitleaks/releases/download/v8.18.2/gitleaks_8.18.2_linux_x64.tar.gz
tar -xzf gitleaks_8.18.2_linux_x64.tar.gz
sudo mv gitleaks /usr/local/bin/

# Docker
docker pull zricethezav/gitleaks:latest  # Pull Docker image / Скачать Docker-образ

# Windows (Scoop)
scoop install gitleaks

TruffleHog —

# Go version (recommended) / Go-версия
brew install truffleHog

# Python legacy version / Python-версия
pip install truffleHog

# Docker
docker pull trufflesecurity/trufflehog:latest

git-secrets (AWS) —

# macOS
brew install git-secrets

# Linux — from source
git clone https://github.com/awslabs/git-secrets.git
cd git-secrets
sudo make install

detect-secrets (Yelp) —

pip install detect-secrets  # Install via pip / Установка через pip

GitGuardian CLI (ggshield) —

# macOS
brew install gitguardian/tap/ggshield

# pip
pip install ggshield

git-filter-repo —

# pip
pip3 install git-filter-repo  # Install via pip / Установка через pip

# macOS
brew install git-filter-repo

# Manual download
wget https://raw.githubusercontent.com/newren/git-filter-repo/main/git-filter-repo
chmod +x git-filter-repo
sudo mv git-filter-repo /usr/local/bin/

BFG Repo-Cleaner —

# macOS
brew install bfg

# Manual (requires Java)
wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar

Scanning Tools Overview

Comparison Table —

Tool Language Method Verified Secrets Baseline Support Best For / Лучше всего для
gitleaks Go Regex + entropy Fast repo scanning, CI/CD integration / Быстрое сканирование, интеграция в CI/CD
TruffleHog Go Regex + entropy + API verification ✅ (active checks) Finding real (verified) secrets / Поиск реальных (верифицированных) секретов
git-secrets Bash Regex (AWS-focused) AWS-centric projects, pre-commit hooks / AWS-проекты, pre-commit хуки
detect-secrets Python Regex + entropy + plugins Incremental scanning with baselines / Инкрементальное сканирование с baseline
GitGuardian Python Cloud ML + regex ✅ (cloud) Enterprise, commercial environments / Корпоративные среды

[!TIP] For most projects, start with gitleaks for speed, and run TruffleHog with --only-verified for a second pass to reduce false positives. Для большинства проектов используйте gitleaks для скорости, а затем TruffleHog с --only-verified для снижения ложных срабатываний.

History Cleaning Methods —

Method Speed Complexity Safety Recommendation / Рекомендация
git-filter-repo ⚡ Fast Medium ✅ Safe ✅ Recommended / Рекомендуется
BFG Repo-Cleaner ⚡ Fast Low ✅ Safe Good for simple cases / Хорош для простых случаев
git filter-branch 🐢 Slow High ⚠️ Risky ❌ Legacy, avoid / Устаревший, избегайте

Automated Scanning

Gitleaks —

gitleaks detect --source . --verbose  # Basic scan / Базовое сканирование

gitleaks detect --source . --report-path gitleaks-report.json  # JSON report / Отчёт в JSON

gitleaks detect --source . --report-format sarif --report-path gitleaks.sarif  # SARIF report (for GitHub) / Отчёт в SARIF (для GitHub)

gitleaks detect --source . --log-opts="origin/main"  # Scan specific branch / Сканирование конкретной ветки

gitleaks detect --source . --config .gitleaks.toml  # Custom config / Пользовательский конфиг

gitleaks detect --source . --no-git  # Scan without Git history / Сканирование без Git-истории

gitleaks detect --source . --log-opts="-- . ':!*.test.js'"  # Ignore specific files / Игнорировать конкретные файлы

gitleaks protect --staged --verbose  # Pre-commit mode (scan staged) / Режим pre-commit (сканировать staged)

Gitleaks Configuration

.gitleaks.toml

title = "gitleaks config"

[extend]
useDefault = true

[allowlist]
description = "Allowlist"
paths = [
    '''\.example$''',
    '''\.sample$''',
    '''test/''',
    '''docs/'''
]
regexes = [
    '''(fake|example|test|dummy)''',
]

[[rules]]
id = "custom-api-key"
description = "Custom API Key"
regex = '''(?i)api[_-]?key[_-]?([a-z0-9]{32,})'''
entropy = 3.5

TruffleHog —

trufflehog git file://. --since-commit HEAD~100 --only-verified  # Scan recent commits (verified only) / Сканирование последних коммитов

trufflehog git file://. --json > trufflehog-report.json  # Full history scan with JSON report / Полное сканирование с отчётом

trufflehog git https://github.com/<USER>/<HOST>  # Scan remote repo / Сканирование удалённого репозитория

trufflehog git file://. --regex --rules custom-rules.json  # Custom regex rules / Пользовательские regex-правила

trufflehog filesystem /path/to/directory  # Scan filesystem (non-Git) / Сканирование файловой системы (не Git)

trufflehog github --org=<HOST> --token=<SECRET_KEY>  # Scan GitHub organization / Сканирование GitHub-организации

git-secrets (AWS) —

git secrets --install  # Install hooks into repo / Установить хуки в репозиторий

# Install globally for all new repos
git secrets --install ~/.git-templates/git-secrets
git config --global init.templateDir ~/.git-templates/git-secrets

git secrets --register-aws  # Register AWS patterns / Зарегистрировать AWS-паттерны

git secrets --add 'password\s*=\s*.+'  # Add custom pattern / Добавить пользовательский паттерн
git secrets --add --allowed 'password\s*=\s*"example"'  # Add allowed exception / Добавить исключение

git secrets --scan-history  # Scan full history / Сканировать всю историю
git secrets --scan  # Scan last commit / Сканировать последний коммит
git secrets --list  # List registered patterns / Список зарегистрированных паттернов

detect-secrets (Yelp) —

detect-secrets scan > .secrets.baseline  # Create baseline / Создать baseline

detect-secrets scan --baseline .secrets.baseline  # Scan against baseline / Сканирование относительно baseline

detect-secrets audit .secrets.baseline  # Interactive audit / Интерактивный аудит

detect-secrets scan file1.py file2.js  # Scan specific files / Сканировать конкретные файлы

detect-secrets scan --baseline .secrets.baseline --update  # Update baseline / Обновить baseline

detect-secrets scan --exclude-files '\.example$' --exclude-files 'test/.*'  # Exclude patterns / Исключить паттерны

GitGuardian CLI (ggshield) —

ggshield auth login  # Authenticate / Авторизация

ggshield secret scan repo .  # Scan repository / Сканирование репозитория

ggshield secret scan pre-commit  # Pre-commit scan / Сканирование pre-commit

ggshield secret scan ci  # CI scan / Сканирование CI

ggshield secret scan docker nginx:latest  # Scan Docker image / Сканирование Docker-образа

Basic Git Commands —

Search by Content

git log -p --all -S "<SEARCH_STRING>"  # Search for string in history / Поиск строки во всей истории

git log -p --all -G "password\s*=\s*['\"].*['\"]"  # Search with regex / Поиск с regex

git log -p --all -S "<SECRET_KEY>" | grep -B 3 -A 3 "<SECRET_KEY>"  # Search with context (±3 lines) / Поиск с контекстом (±3 строки)

git log --all --grep="password"  # Search in commit messages / Поиск в сообщениях коммитов

Search in Specific Files

git log --all --full-history -p -- path/to/file.conf  # File history / История конкретного файла

git log --all --full-history -- "*.env" "*.conf"  # All versions of file types / Все версии файлов по типу

git show <COMMIT_HASH>:path/to/file  # Show file at specific commit / Показать файл в конкретном коммите

git log --diff-filter=D --summary | grep delete  # Find when a file was deleted / Найти когда файл был удалён

Search Deleted Files

git log --diff-filter=D --summary | grep delete | awk '{print $4}'  # List all deleted files / Список всех удалённых файлов

git checkout <COMMIT_HASH>^ -- path/to/deleted/file  # Restore deleted file for review / Восстановить удалённый файл для просмотра

Pattern Search —

Private Keys

git log -p --all | grep -i "BEGIN.*PRIVATE" -B 5 -A 10  # Any private key / Любой приватный ключ
git log -p --all | grep -i "BEGIN RSA PRIVATE KEY"  # RSA key / RSA-ключ
git log -p --all | grep -i "BEGIN OPENSSH PRIVATE KEY"  # OpenSSH key / OpenSSH-ключ

Passwords & Tokens

git log -p --all | grep -Ei "(password|passwd|pwd)\s*[:=]" -B 2 -A 2  # Passwords / Пароли
git log -p --all | grep -Ei "(api[_-]?key|token|secret)\s*[:=]" -B 2 -A 2  # API keys & tokens / API-ключи и токены
git log -p --all | grep -Ei "authorization\s*:\s*bearer" -i  # Bearer tokens / Bearer-токены

Credentials in URLs

git log -p --all | grep -E "https?://[^:]+:[^@]+@" -B 2 -A 2  # URL with embedded credentials / URL со встроенными реквизитами

Email Addresses / Email-адреса

git log -p --all | grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"  # Find email addresses / Поиск email-адресов

IP Addresses / IP-адреса

git log -p --all | grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"  # Find IP addresses / Поиск IP-адресов

AWS Keys / AWS-ключи

git log -p --all | grep -E "AKIA[0-9A-Z]{16}"  # AWS Access Key ID / ID ключа доступа AWS
git log -p --all | grep -E "aws_secret_access_key"  # AWS Secret Key reference / Ссылка на секретный ключ AWS

JWT Tokens / JWT-токены

git log -p --all | grep -E "eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*"  # JWT pattern / JWT-паттерн

Search by File Type

# Config files
git log -p --all -- "*.conf" "*.config" "*.ini" "*.yaml" "*.yml" "*.toml"

# Environment files
git log -p --all -- "*.env" "*.env.*" ".envrc"

# Credential files
git log -p --all -- "*credentials*" "*secret*" "*password*"

# SSH keys / SSH-ключи
git log -p --all -- "*.pem" "*.key" "*id_rsa*" "*id_ed25519*"

# Certificate files
git log -p --all -- "*.p12" "*.pfx" "*.jks" "*.keystore"

# Backup files (often contain secrets)
git log -p --all -- "*.bak" "*.backup" "*.old" "*~"

By Author and Date

git log -p --all --author="<USER>@<HOST>" | grep -i "password"  # Commits by author / Коммиты конкретного автора

git log -p --all --since="2024-01-01" --until="2024-12-31" | grep -i "secret"  # Commits by date range / Коммиты за период

git log --all --shortstat | grep -B 1 "100[0-9]\+ insertion"  # Large commits (potential dumps) / Большие коммиты (потенциальные дампы)

Stash and Reflog / Stash

git stash list  # List stashes / Список сохранённых stash
git stash show -p stash@{0} | grep -i "password"  # Search in stash / Поиск в stash

git reflog show --all | grep -i "sensitive"  # Search in reflog / Поиск в reflog
git show HEAD@{5}:path/to/file  # Show file from reflog entry / Показать файл из reflog

Removing Secrets from History

[!CAUTION] All methods below rewrite Git history. After cleaning, you MUST force push and all collaborators MUST re-clone or git reset --hard. Coordinate with your team before proceeding! Все методы ниже перезаписывают историю Git. После очистки необходим force push, и все участники ДОЛЖНЫ заново клонировать репозиторий или выполнить git reset --hard. Согласуйте с командой перед началом!

Remove Files

git filter-repo --path path/to/secret.conf --invert-paths  # Remove single file / Удалить один файл

git filter-repo --path secret1.conf --path secret2.key --invert-paths  # Remove multiple files / Удалить несколько файлов

git filter-repo --path-glob '*.env' --invert-paths  # Remove by pattern / Удалить по паттерну

git filter-repo --path secrets/ --invert-paths  # Remove entire directory / Удалить целую директорию

Replace Content

# Create expressions file
# Format: literal:old_text==>new_text or regex:pattern==>replacement

expressions.txt

literal:<PASSWORD>==>REDACTED
regex:api[_-]?key\s*=\s*['"]([^'"]+)['"]==>api_key="<SECRET_KEY>"
literal:smtp.gmail.com==>smtp.example.com
git filter-repo --replace-text expressions.txt  # Apply replacements / Применить замены

Remove Large Files

git filter-repo --strip-blobs-bigger-than 10M  # Remove files > 10MB / Удалить файлы больше 10MB

Fix Author Info

mailmap.txt

Correct Name <USER>@<HOST> <USER>@<HOST>
Correct Name <USER>@<HOST> Old Name <USER>@<HOST>
git filter-repo --mailmap mailmap.txt  # Apply mailmap / Применить mailmap

Combined Operations

git filter-repo \
  --path secrets/ --invert-paths \
  --path '*.env' --invert-paths \
  --replace-text expressions.txt \
  --strip-blobs-bigger-than 10M

Method 2: BFG Repo-Cleaner / BFG Repo-Cleaner

Remove Files

bfg --delete-files secret.conf  # Single file / Один файл
bfg --delete-files "{secret.conf,password.txt,api_key.json}"  # Multiple files / Несколько файлов
bfg --delete-files "*.env"  # By pattern / По паттерну
bfg --delete-folders secrets  # Delete folders / Удалить папки
bfg --delete-folders "{logs,temp,cache}"  # Multiple folders / Несколько папок

Replace Strings

# Create file with secrets (one per line)
echo "<PASSWORD>" > passwords.txt
echo "<SECRET_KEY>" >> passwords.txt
echo "<SECRET_KEY>" >> passwords.txt

bfg --replace-text passwords.txt  # Replace with ***REMOVED*** / Заменить на ***REMOVED***

Remove Large Files

bfg --strip-blobs-bigger-than 10M  # Remove files > 10MB / Удалить файлы больше 10MB

[!IMPORTANT] After BFG, always run cleanup / После BFG всегда выполняйте очистку:

git reflog expire --expire=now --all
git gc --prune=now --aggressive

[!WARNING] git filter-branch is slow, error-prone, and officially deprecated. Use git-filter-repo instead. git filter-branch медленный, подвержен ошибкам и официально устарел. Используйте git-filter-repo.

Remove File

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/secret.conf' \
  --prune-empty --tag-name-filter cat -- --all

Remove Directory

git filter-branch --force --index-filter \
  'git rm -r --cached --ignore-unmatch secrets/' \
  --prune-empty --tag-name-filter cat -- --all

Replace Content

git filter-branch --tree-filter \
  'find . -name "*.conf" -exec sed -i "s/<PASSWORD>/REDACTED/g" {} \;' \
  --prune-empty --tag-name-filter cat -- --all

Cleanup after filter-branch

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now --aggressive

Post-Cleanup Finalization

[!CAUTION] --force push will overwrite remote history. Ensure all collaborators are notified! --force push перезапишет удалённую историю. Убедитесь что все участники уведомлены!

# 1. Verify result
gitleaks detect --source . --verbose
git log --all --oneline | head -20

# 2. Force push (CAREFUL!) / Force push
git push origin --force --all
git push origin --force --tags

# 3. Collaborators must re-clone
rm -rf local-repo
git clone https://github.com/<USER>/<HOST>.git

# Or reset
cd local-repo
git fetch origin
git reset --hard origin/main
git clean -fdx

Revoking Compromised Secrets

[!WARNING] Removing secrets from Git history is NOT enough. Always revoke and rotate the compromised credentials immediately. Удаление секретов из истории Git НЕДОСТАТОЧНО. Всегда отзывайте и ротируйте скомпрометированные реквизиты немедленно.

AWS Keys / AWS-ключи

aws iam list-access-keys  # List keys / Список ключей

aws iam update-access-key --access-key-id <SECRET_KEY> --status Inactive  # Deactivate / Деактивировать

aws iam delete-access-key --access-key-id <SECRET_KEY>  # Delete key / Удалить ключ

aws iam create-access-key  # Create new / Создать новый

# Key rotation (best practice)
aws iam create-access-key --user-name <USER>
# Update applications with the new key
aws iam update-access-key --access-key-id <SECRET_KEY> --status Inactive
# Test
aws iam delete-access-key --access-key-id <SECRET_KEY>

GitHub Personal Access Token / GitHub Personal Access Token

# Web UI:
# Settings → Developer settings → Personal access tokens → Revoke

# Or via API
curl -X DELETE \
  -H "Authorization: token <SECRET_KEY>" \
  https://api.github.com/applications/<SECRET_KEY>/token

# Create new
# Settings → Developer settings → Personal access tokens → Generate new token

Telegram Bot Token

# @BotFather
/mybots
# Select bot
# API Token → Revoke current token
# Generate new

Google Cloud / OAuth

# Web UI:
# Google Cloud Console → APIs & Services → Credentials
# Find compromised credential → Delete

# gcloud CLI
gcloud auth revoke <USER>@<HOST>  # Revoke auth / Отозвать авторизацию
gcloud iam service-accounts keys delete <SECRET_KEY> \
  --iam-account=<USER>@<HOST>.iam.gserviceaccount.com  # Delete key / Удалить ключ

gcloud iam service-accounts keys create key.json \
  --iam-account=<USER>@<HOST>.iam.gserviceaccount.com  # Create new key / Создать новый ключ

SSH Keys / SSH-ключи

# GitHub: Settings → SSH and GPG keys → Delete

ssh-keygen -R <HOST>  # Remove from known_hosts / Удалить из known_hosts
vim ~/.ssh/authorized_keys  # Remove public key / Удалить публичный ключ

ssh-keygen -t ed25519 -C "<USER>@<HOST>"  # Generate new key pair / Создать новую пару ключей

Database Passwords

-- MySQL/MariaDB
ALTER USER '<USER>'@'<HOST>' IDENTIFIED BY '<PASSWORD>';
FLUSH PRIVILEGES;

-- PostgreSQL
ALTER USER <USER> WITH PASSWORD '<PASSWORD>';

-- MongoDB
db.updateUser("<USER>", {pwd: "<PASSWORD>"})

Docker Registry Tokens

# Docker Hub: Account Settings → Security → Access Tokens → Revoke

# Harbor / Private registry:
# Delete robot account and recreate

NPM Token / NPM-токен

npm token revoke <SECRET_KEY>  # Revoke / Отозвать
npm token create --read-only  # Create new (read-only) / Создать (только чтение)
npm token create --publish  # Create new (publish) / Создать (publish)

Prevention & Best Practices

Pre-commit Hooks / Pre-commit

Using pre-commit Framework

pip install pre-commit  # Install / Установка

.pre-commit-config.yaml

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.2
    hooks:
      - id: gitleaks

  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: detect-private-key
      - id: check-added-large-files
        args: ['--maxkb=1000']
      - id: check-merge-conflict
      - id: trailing-whitespace
pre-commit install  # Install hooks / Установить хуки
pre-commit run --all-files  # Run manually / Запустить вручную

Custom Bash Pre-commit Hook

.git/hooks/pre-commit

#!/bin/bash

# Check for gitleaks
if command -v gitleaks &> /dev/null; then
    gitleaks protect --staged --verbose
    if [ $? -ne 0 ]; then
        echo "❌ Gitleaks found secrets! Commit rejected."
        exit 1
    fi
fi

# Check for large files
MAX_SIZE=1048576  # 1MB in bytes / 1MB в байтах
for file in $(git diff --cached --name-only); do
    if [ -f "$file" ]; then
        size=$(wc -c < "$file")
        if [ $size -gt $MAX_SIZE ]; then
            echo "❌ File $file is too large: $size bytes"
            exit 1
        fi
    fi
done

# Check for private keys
if git diff --cached | grep -E "BEGIN.*PRIVATE KEY"; then
    echo "❌ Private key detected in commit!"
    exit 1
fi

echo "✅ Pre-commit checks passed"
exit 0
chmod +x .git/hooks/pre-commit  # Make executable / Сделать исполняемым

.gitignore

# Secrets and credentials
.env
.env.*
!.env.example
*.pem
*.key
*.p12
*.pfx
*.jks
*.keystore
id_rsa*
id_ed25519*
id_ecdsa*

# Configs with secrets
*secret*
*password*
*credential*
config/secrets.yml
config/database.yml
!config/database.yml.example

# Cloud provider configs
.aws/
.azure/
.gcloud/
credentials.json
service-account.json

# Logs (may contain secrets)
*.log
logs/
*.log.*

# Backups
*.bak
*.backup
*.old
*~
*.swp
*.swo

# Directories
secrets/
private/
.secrets/
tmp/
temp/

# IDE
.vscode/
.idea/
*.iml

# OS
.DS_Store
Thumbs.db

Git Attributes for Sensitive Files / Git Attributes

.gitattributes

# Never show diff for these files
*.pem diff=secret
*.key diff=secret
*secret* diff=secret
.env* diff=secret

~/.gitconfig or .git/config

[diff "secret"]
    textconv = echo "REDACTED"

Environment-Based Configuration

Using dotenv

.env (add to .gitignore)

DATABASE_PASSWORD=<PASSWORD>
API_KEY=<SECRET_KEY>

.env.example (safe to commit / безопасно коммитить)

DATABASE_PASSWORD=your_password_here
API_KEY=your_api_key_here

Docker Secrets / Docker-секреты

docker-compose.yml

version: '3.8'
services:
  app:
    image: myapp
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

Kubernetes Secrets / Kubernetes-секреты

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: <BASE64_ENCODED_PASSWORD>  # base64 encoded / в кодировке base64
kubectl create secret generic mysecret --from-literal=password=<PASSWORD>  # Create secret / Создать секрет

GitHub-Specific Tools

GitHub Secret Scanning

Automatically active for public repositories / Автоматически активно для публичных репозиториев.

For private repos (requires GitHub Advanced Security) / Для приватных (требует GitHub Advanced Security):

Repository → Settings → Code security and analysis
→ Enable Secret scanning
→ Enable Push protection

GitHub Advanced Security API / GitHub Advanced Security API

curl -X PUT \
  -H "Authorization: token <SECRET_KEY>" \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/<USER>/<HOST>/vulnerability-alerts  # Enable vulnerability alerts / Включить оповещения об уязвимостях

CI/CD Integration

GitHub Actions Secret Scanning Workflow / GitHub Actions

.github/workflows/secret-scan.yml

name: Secret Scanning

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Run Gitleaks
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  trufflehog:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: TruffleHog OSS
        uses: trufflesecurity/trufflehog@main
        with:
          path: ./
          base: main
          head: HEAD

  detect-secrets:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'

      - name: Install detect-secrets
        run: pip install detect-secrets

      - name: Run detect-secrets
        run: |
          detect-secrets scan --baseline .secrets.baseline
          detect-secrets audit .secrets.baseline

Secret Managers

HashiCorp Vault

Default port: 8200

brew install vault  # Install / Установка

vault server -dev  # Start dev server / Запуск dev-сервера

vault kv put secret/myapp password=<PASSWORD>  # Store secret / Сохранить секрет

vault kv get secret/myapp  # Retrieve secret / Получить секрет

AWS Secrets Manager

# Create secret
aws secretsmanager create-secret \
    --name MySecret \
    --secret-string '{"username":"<USER>","password":"<PASSWORD>"}'

# Retrieve secret
aws secretsmanager get-secret-value --secret-id MySecret

SOPS (Secrets OPerationS)

brew install sops  # Install / Установка

sops secrets.yaml  # Create/edit encrypted file / Создать/редактировать зашифрованный файл

sops -d secrets.yaml  # Decrypt / Расшифровать

Language-Specific Examples

Python (Django/Flask)

# settings.py
import os
from dotenv import load_dotenv

load_dotenv()

SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
DATABASE_PASSWORD = os.getenv('DB_PASSWORD')

# NEVER
# SECRET_KEY = 'django-insecure-hardcoded-key-123'

Node.js

// config.js
require('dotenv').config();

module.exports = {
    apiKey: process.env.API_KEY,
    dbPassword: process.env.DB_PASSWORD
};

// NEVER / НИКОГДА:
// const API_KEY = 'hardcoded-api-key-123';

Go

package main

import (
    "os"
    "github.com/joho/godotenv"
)

func main() {
    godotenv.Load()
    apiKey := os.Getenv("API_KEY")

    // NEVER / НИКОГДА:
    // apiKey := "hardcoded-api-key-123"
}

Ruby (Rails)

# config/database.yml
production:
  password: <%= ENV['DATABASE_PASSWORD'] %>

# NEVER
# password: hardcoded_password_123

PHP

<?php
// config.php
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

$apiKey = $_ENV['API_KEY'];

// NEVER / НИКОГДА:
// $apiKey = 'hardcoded-api-key-123';
?>

Pre-Publication Checklist

Minimal Checklist

# 1. Scan
gitleaks detect --source . --verbose
trufflehog git file://. --only-verified

# 2. Manual check critical files
git log -p --all -- "*.env" "*.conf" "*.yaml"
git log -p --all -- "*secret*" "*password*" "*credential*"

# 3. Verify .gitignore
cat .gitignore | grep -E "(env|secret|password|key|credential)"

# 4. Remove temporary files and logs
git clean -fdx
rm -rf logs/ *.log tmp/ temp/

# 5. Create example files
cp .env .env.example
# Replace real values with placeholders

# 6. Commit changes
git add .gitignore *.example
git commit -m "Prepare for public release"

# 7. Final scan
gitleaks detect --source . --verbose

Extended Checklist


Emergency Incident Runbook

Production Runbook: Secret Leak Response

[!CAUTION] If secrets have been pushed to a public repository, they are already compromised. Bots continuously scan GitHub for leaked credentials. Revoke and rotate ALL exposed secrets immediately — do NOT rely solely on history cleanup. Если секреты были запушены в публичный репозиторий, они уже скомпрометированы. Боты непрерывно сканируют GitHub на утечки. Отзовите и ротируйте ВСЕ раскрытые секреты немедленно — НЕ полагайтесь только на очистку истории.

  1. Immediately (0-1 min) — Make the repository private / Немедленно сделать репозиторий приватным

    GitHub: Repository → Settings → Danger Zone → Change visibility → Private
  2. Within 5 minutes — Revoke ALL compromised secrets / Отозвать ВСЕ скомпрометированные секреты

    # AWS
    aws iam update-access-key --access-key-id <SECRET_KEY> --status Inactive
    
    # GitHub Token
    # Settings → Developer settings → Tokens → Revoke
    
    # Database — change passwords immediately / Сменить пароли немедленно
  3. Within 15 minutes — Clean Git history / Очистить историю Git

    git filter-repo --path path/to/secret.conf --invert-paths
    git push --force --all
  4. Within 1 hour — Full audit / Полный аудит

    # Check access logs / Проверить логи доступа
    # Check for unusual activity / Проверить необычную активность
    # Notify the team / Уведомить команду
  5. Within 1 day — Post-mortem / Постмортем

    • Document the incident / Документировать инцидент
    • Update procedures / Обновить процедуры
    • Set up automation to prevent recurrence / Настроить автоматизацию для предотвращения

Minimal Cleanup Workflow

Exact Short Steps

Use this flow when a secret has already landed in Git history and you need a fast, practical cleanup sequence. Используйте этот сценарий, когда секрет уже попал в историю Git и нужен быстрый практический порядок действий.

[!CAUTION] Revoke and rotate leaked credentials first. History cleanup alone does not make an exposed secret safe again. Сначала отзовите и ротируйте утёкшие реквизиты. Одна только очистка истории не делает секрет снова безопасным.

  1. Scan the repository and confirm the leak / Просканируйте репозиторий и подтвердите утечку
gitleaks detect -v  # Quick scan / Быстрое сканирование
  1. Create a fresh working copy for cleanup / Создайте отдельную рабочую копию для очистки
git clone [email protected]:<USER>/<HOST>.git clean-repo  # Clone repo for cleanup / Клонировать репозиторий для очистки
cd clean-repo  # Enter cleanup clone / Перейти в клон для очистки
  1. Remove the leaked file from history if the problem is the whole file / Удалите файл из истории, если проблема во всём файле
git filter-repo --path FILE-with-leaks --invert-paths  # Remove file from all history / Удалить файл из всей истории
  1. Or replace only the secret text if you need to keep the file / Или замените только секретный текст, если файл нужно сохранить
echo "<SECRET_KEY>==>REMOVED" > replacements.txt  # Create replacement rules / Создать правила замены
git filter-repo --replace-text replacements.txt  # Rewrite matching content / Переписать совпадающее содержимое
  1. Push rewritten history to the remote / Отправьте переписанную историю в удалённый репозиторий
git push --force --all  # Push all rewritten branches / Отправить все переписанные ветки
git push --force --tags  # Push rewritten tags / Отправить переписанные теги
  1. On the main local repository, resync to the cleaned branch / В основном локальном репозитории синхронизируйтесь с очищенной веткой
git fetch origin  # Fetch updated remote history / Получить обновлённую историю
git reset --hard origin/<branch>  # Reset to cleaned remote branch / Сброситься к очищенной ветке

[!WARNING] git reset --hard discards uncommitted local changes. Save or stash anything important before running it. git reset --hard удаляет незакоммиченные локальные изменения. Сохраните или уберите в stash всё важное перед запуском.

  1. Verify the cleanup / Проверьте результат
gitleaks detect -v  # Re-scan after rewrite / Повторно просканировать после переписывания

Quick Reference

Scan (pick one)

gitleaks detect --source . --verbose  # Fastest / Самый быстрый
# or
trufflehog git file://. --only-verified  # Most accurate / Самый точный
# or
detect-secrets scan  # Baseline support / Поддержка baseline

Clean History (pick one)

# Modern (recommended)
git filter-repo --path secret.conf --invert-paths

# Simple
bfg --delete-files secret.conf
git reflog expire --expire=now --all && git gc --prune=now --aggressive

# Legacy (not recommended)
git filter-branch --index-filter 'git rm --cached --ignore-unmatch secret.conf' --prune-empty -- --all

After Cleanup

gitleaks detect --source . --verbose  # Verify / Проверка

# Force push (CAREFUL!) / Force push
git push origin --force --all
git push origin --force --tags

Prevention

pip install pre-commit  # Install pre-commit / Установить pre-commit
pre-commit install  # Activate hooks / Активировать хуки

# Add to .gitignore
echo ".env" >> .gitignore
echo "*.log" >> .gitignore
echo "*secret*" >> .gitignore

Sysadmin Operations

Default Ports

Tool / Service Default Port / Порт по умолчанию Notes / Примечания
Gitleaks N/A CLI tool, no listening socket / CLI-утилита, не открывает порт
TruffleHog N/A CLI tool, no listening socket / CLI-утилита, не открывает порт
git-secrets N/A Git hook utility / Git hook утилита
detect-secrets N/A CLI tool / CLI-утилита
GitHub Secret Scanning N/A SaaS feature in GitHub / SaaS-функция GitHub
HashiCorp Vault 8200/tcp API and UI / API и UI

Log Locations

Tool Log Location / Расположение лога
gitleaks stdout / report file (--report-path)
TruffleHog stdout / JSON (--json)
git-secrets stdout
detect-secrets .secrets.baseline
pre-commit stdout
GitHub Actions GitHub UI → Actions tab
Vault /var/log/vault/vault_audit.log (when configured)

Service Control

/etc/systemd/system/vault.service or /lib/systemd/system/vault.service

systemctl status vault  # Check status / Проверить статус
systemctl restart vault  # Restart service / Перезапустить сервис
systemctl reload vault  # Reload config if supported / Перечитать конфиг если поддерживается
journalctl -u vault -n 100 --no-pager  # Recent logs / Последние логи

Logrotate Configuration

/etc/logrotate.d/vault

/var/log/vault/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 vault vault
    sharedscripts
    postrotate
        systemctl reload vault 2>/dev/null || true
    endscript
}

[!NOTE] Most secret scanning tools (gitleaks, TruffleHog, detect-secrets) are CLI tools that write to stdout or report files. They don't typically require logrotate. Configure logrotate only for long-running services like HashiCorp Vault. Большинство инструментов сканирования (gitleaks, TruffleHog, detect-secrets) — CLI утилиты, пишущие в stdout или файлы отчётов. Logrotate обычно не нужен. Настраивайте logrotate только для долгоживущих сервисов вроде HashiCorp Vault.


Tools

Documentation

Secret Pattern Lists


Last Updated / Последнее обновление: April 2026 Version / Версия: 2.0

[!WARNING] Always treat a secret leak as a serious security incident. Even after removing from Git history, secrets may have been indexed by search engines or cloned by attackers. ALWAYS revoke and recreate compromised secrets. Всегда считайте утечку секретов серьёзным инцидентом безопасности. Даже после удаления из истории Git, секреты могли быть проиндексированы поисковиками или склонированы злоумышленниками. ВСЕГДА отзывайте и пересоздавайте скомпрометированные секреты.

On this page

linux Overview Installation &amp; Configuration Gitleaks — TruffleHog — git-secrets (AWS) — detect-secrets (Yelp) — GitGuardian CLI (ggshield) — git-filter-repo — BFG Repo-Cleaner — Scanning Tools Overview Comparison Table — History Cleaning Methods — Automated Scanning Gitleaks — Gitleaks Configuration TruffleHog — git-secrets (AWS) — detect-secrets (Yelp) — GitGuardian CLI (ggshield) — Manual Search Basic Git Commands — Search by Content Search in Specific Files Search Deleted Files Pattern Search — Private Keys Passwords &amp; Tokens Credentials in URLs Email Addresses / Email-адреса IP Addresses / IP-адреса AWS Keys / AWS-ключи JWT Tokens / JWT-токены Search by File Type Advanced Search By Author and Date Stash and Reflog / Stash Removing Secrets from History Method 1: git-filter-repo (Recommended) / git-filter-repo Remove Files Replace Content Remove Large Files Fix Author Info Combined Operations Method 2: BFG Repo-Cleaner / BFG Repo-Cleaner Remove Files Replace Strings Remove Large Files Method 3: git filter-branch (Legacy — Not Recommended) / git filter-branch Remove File Remove Directory Replace Content Cleanup after filter-branch Post-Cleanup Finalization Revoking Compromised Secrets AWS Keys / AWS-ключи GitHub Personal Access Token / GitHub Personal Access Token Telegram Bot Token Google Cloud / OAuth SSH Keys / SSH-ключи Database Passwords Docker Registry Tokens NPM Token / NPM-токен Prevention &amp; Best Practices Pre-commit Hooks / Pre-commit Using pre-commit Framework Custom Bash Pre-commit Hook .gitignore — Recommended Template Git Attributes for Sensitive Files / Git Attributes Environment-Based Configuration Using dotenv Docker Secrets / Docker-секреты Kubernetes Secrets / Kubernetes-секреты GitHub-Specific Tools GitHub Secret Scanning GitHub Advanced Security API / GitHub Advanced Security API CI/CD Integration GitHub Actions Secret Scanning Workflow / GitHub Actions Secret Managers HashiCorp Vault AWS Secrets Manager SOPS (Secrets OPerationS) Language-Specific Examples Python (Django/Flask) Node.js Go Ruby (Rails) PHP Pre-Publication Checklist Minimal Checklist Extended Checklist Emergency Incident Runbook Production Runbook: Secret Leak Response Minimal Cleanup Workflow Exact Short Steps Quick Reference Scan (pick one) Clean History (pick one) After Cleanup Prevention Sysadmin Operations Default Ports Log Locations Service Control Logrotate Configuration Resources &amp; Links Tools Documentation Secret Pattern Lists