Git Secret Leak Detection
If you like this project, consider supporting me on Buy Me a Coffee ☕️
tags:
- security
- crypto
- sysadmin
-
linux
Complete guide for detecting, removing, and preventing sensitive data leaks in Git repositories. Полное руководство по обнаружению, удалению и предотвращению утечек чувствительных данных в Git-репозиториях.
Overview
Git secret leak detection covers the discovery, verification, cleanup, and prevention of credentials accidentally committed to Git history. Обнаружение утечек секретов в Git включает поиск, верификацию, очистку и предотвращение попадания учётных данных в историю Git.
Common use cases / Типовые сценарии:
- Pre-commit and CI/CD scanning before code reaches shared branches / Проверка до попадания кода в общие ветки
- Incident response after leaked API keys, tokens, certificates, or
.envfiles / Реагирование на утечки API-ключей, токенов, сертификатов или.env - Repository hygiene before open-sourcing, audits, or M&A due diligence / Гигиена репозитория перед open-source, аудитами или due diligence
Status / Актуальность:
- Gitleaks is actively used and remains one of the most practical open-source scanners for local runs and CI/CD.
- TruffleHog is a modern companion tool when you want verification and higher confidence on live credentials.
- git-secrets is still useful for AWS-focused hook-based workflows, but it is narrower and more legacy in scope than Gitleaks or TruffleHog.
- Modern alternatives and complements / Современные альтернативы и дополнения: GitHub Secret Scanning, GitLab Secret Detection, GitGuardian, SOPS, HashiCorp Vault, AWS Secrets Manager.
[!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-verifiedfor 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-образа
Manual Search
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" "*~"
Advanced Search
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 pushand all collaborators MUST re-clone orgit reset --hard. Coordinate with your team before proceeding! Все методы ниже перезаписывают историю Git. После очистки необходимforce push, и все участники ДОЛЖНЫ заново клонировать репозиторий или выполнитьgit reset --hard. Согласуйте с командой перед началом!
Method 1: git-filter-repo (Recommended) / git-filter-repo
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
Method 3: git filter-branch (Legacy — Not Recommended) / git filter-branch
[!WARNING]
git filter-branchis slow, error-prone, and officially deprecated. Usegit-filter-repoinstead.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]
--forcepush will overwrite remote history. Ensure all collaborators are notified!--forcepush перезапишет удалённую историю. Убедитесь что все участники уведомлены!
# 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 — Recommended Template
.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
- [ ] Run
gitleaks detect/ Запуститьgitleaks detect - [ ] Run
trufflehog/ Запуститьtrufflehog - [ ] Check all
*.env,*.conf,*.yamlfiles / Проверить все*.env,*.conf,*.yaml - [ ] Check logs and temp files / Проверить логи и временные файлы
- [ ] Verify
.gitignoreis up-to-date / Убедиться что.gitignoreактуален - [ ] Create
.env.example,config.example, etc. / Создать.env.example,config.exampleи т.д. - [ ] Remove all
*.log,*.bak,*.oldfiles / Удалить все*.log,*.bak,*.oldфайлы - [ ] Check code comments for TODO with secrets / Проверить комментарии на TODO с секретами
- [ ] Check
docker-compose.ymlfor hardcoded values / Проверитьdocker-compose.ymlна hardcoded значения - [ ] Check
READMEfor real data examples / ПроверитьREADMEна примеры с реальными данными - [ ] Check CI/CD configs (
.github,.gitlab-ci.yml) / Проверить CI/CD конфиги - [ ] Install pre-commit hooks / Установить pre-commit хуки
- [ ] Add secret files to
.gitignore/ Добавить секретные файлы в.gitignore - [ ] Add
.gitattributesfor diff filtering / Добавить.gitattributesдля diff-фильтрации - [ ] Verify all secrets are in env variables / Проверить что все секреты в переменных окружения
- [ ] Update documentation with secret instructions / Обновить документацию с инструкциями по секретам
- [ ] Enable GitHub Secret Scanning (if available) / Настроить GitHub Secret Scanning (если доступно)
- [ ] Create GitHub Actions for auto scanning / Создать GitHub Actions для автосканирования
- [ ] Check all branches and tags / Проверить все branches и tags
- [ ] Verify
node_modules/,vendor/are in.gitignore/ Убедиться чтоnode_modules/,vendor/в.gitignore - [ ] Final scan with all tools / Финальное сканирование всеми инструментами
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 на утечки. Отзовите и ротируйте ВСЕ раскрытые секреты немедленно — НЕ полагайтесь только на очистку истории.
-
Immediately (0-1 min) — Make the repository private / Немедленно сделать репозиторий приватным
GitHub: Repository → Settings → Danger Zone → Change visibility → Private -
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 / Сменить пароли немедленно -
Within 15 minutes — Clean Git history / Очистить историю Git
git filter-repo --path path/to/secret.conf --invert-paths git push --force --all -
Within 1 hour — Full audit / Полный аудит
# Check access logs / Проверить логи доступа # Check for unusual activity / Проверить необычную активность # Notify the team / Уведомить команду -
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. Сначала отзовите и ротируйте утёкшие реквизиты. Одна только очистка истории не делает секрет снова безопасным.
- Scan the repository and confirm the leak / Просканируйте репозиторий и подтвердите утечку
gitleaks detect -v # Quick scan / Быстрое сканирование
- 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 / Перейти в клон для очистки
- 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 / Удалить файл из всей истории
- 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 / Переписать совпадающее содержимое
- Push rewritten history to the remote / Отправьте переписанную историю в удалённый репозиторий
git push --force --all # Push all rewritten branches / Отправить все переписанные ветки
git push --force --tags # Push rewritten tags / Отправить переписанные теги
- 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 --harddiscards uncommitted local changes. Save or stash anything important before running it.git reset --hardудаляет незакоммиченные локальные изменения. Сохраните или уберите в stash всё важное перед запуском.
- 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.
Resources & Links
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, секреты могли быть проиндексированы поисковиками или склонированы злоумышленниками. ВСЕГДА отзывайте и пересоздавайте скомпрометированные секреты.