Секрети — це токени, ключі доступу, паролі й інші чутливі дані, які іноді випадково потрапляють у репозиторій. Добра новина: це можна зупинити до того, як секрети полетять на ремоут. У цьому гайді я покажу, як налаштувати pre-commit hooks у Git з git-secrets та TruffleHog, а ще увімкнути CI-сканування історії — усе на Linux. Працюємо через термінал Linux, пишемо прості bash скрипти, і будуємо корисну автоматизацію задач для команди, що займається розробка на Linux. 🎯
Підготовка: встановлення інструментів
Нам знадобляться Git, git-secrets і TruffleHog. Ви можете встановити їх через пакети або з вихідних. Нижче — універсальні варіанти для Linux.
# 1) Встановити git-secrets зі сховища вихідних
sudo apt-get update -y
sudo apt-get install -y git make
rm -rf /tmp/git-secrets \
&& git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets \
&& cd /tmp/git-secrets \
&& sudo make install
# 2) Встановити TruffleHog (через pipx) або використати Docker
python3 -m pip install --user pipx
python3 -m pipx ensurepath
pipx install trufflehog
# альтернативно: Docker-образ (не потребує локальної установки)
docker pull ghcr.io/trufflesecurity/trufflehog:latest
Налаштування pre-commit hooks у Git
Зупиняти витік треба ще на вашій машині: hook спрацює перед комітом і заблокує його, якщо знайде секрети.
Увімкнення git-secrets у репозиторії
Спочатку додамо готові сигнатури та вмикаємо перевірку staged-змін:
# Перейдіть у свій репозиторій
git -C /path/to/your/repo status || cd /path/to/your/repo
# Встановити hook-и git-secrets у поточний репозиторій
git secrets --install
# Додати готові патерни AWS (access key, secret key)
git secrets --register-aws
# Додати типові патерни GitHub та Slack токенів (приклад)
git secrets --add -g 'gh[pousr]_[A-Za-z0-9]{36}'
git secrets --add -g 'xox[baprs]-[A-Za-z0-9-]+'
# Необов'язково: автододавання у всі нові репозиторії
git secrets --install ~/.git-templates/git-secrets
git config --global init.templateDir ~/.git-templates/git-secrets
Якщо знаєте легальні рядки, які не слід вважати секретами (наприклад, публічні ключі тестових сервісів), додайте їх у allowlist:
# Дозволити безпечний патерн у поточному репозиторії (запишеться у .gitallowed)
git secrets --add -l 'https://api.example.com/public-key'
Єдиний глобальний pre-commit з TruffleHog
Тепер підключимо TruffleHog, щоб перевіряти секрети ще ретельніше. Зручно мати один глобальний hook для всіх репозиторіїв:
# Створюємо директорію для глобальних hook-ів
mkdir -p ~/.git-hooks
# Пишемо pre-commit, який спершу запускає git-secrets, а потім TruffleHog
cat > ~/.git-hooks/pre-commit << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
# 1) git-secrets на staged-змінах (якщо інстальовано)
if command -v git-secrets >/dev/null 2>&1; then
git secrets --pre_commit_hook -- "$@"
fi
# 2) TruffleHog на staged-файлах (швидка перевірка)
CHANGED="$(git diff --cached --name-only --diff-filter=ACMR)"
if [ -n "$CHANGED" ] && command -v trufflehog >/dev/null 2>&1; then
echo "[pre-commit] TruffleHog: сканую змінені файли..."
rc=0
while IFS= read -r f; do
[ -f "$f" ] || continue
if [ -f .trufflehog-exclude ]; then
trufflehog filesystem --fail --only-verified --no-update --exclude-paths .trufflehog-exclude "$f" >/dev/null || rc=1
else
trufflehog filesystem --fail --only-verified --no-update "$f" >/dev/null || rc=1
fi
done <<< "$CHANGED"
[ $rc -eq 0 ] || { echo "ERROR: TruffleHog знайшов можливі секрети у staged-файлах."; exit 1; }
fi
EOF
chmod +x ~/.git-hooks/pre-commit
git config --global core.hooksPath ~/.git-hooks
# Необов'язково: файл-винятки для TruffleHog (regex шляхи)
cat > .trufflehog-exclude << 'EOF'
^docs/
\.md$
^tests/fixtures/
EOF
Тепер кожен ваш коміт проходитиме подвійний захист: git-secrets і TruffleHog зупинять зміни, що містять секрети. ⚠️
Сканування в CI/CD (повна історія і PR)
Навіть якщо локальні hook-и вимкнули, CI — остання лінія оборони. Додаємо джобу, яка падає, якщо знайдені секрети в історії.
GitHub Actions
mkdir -p .github/workflows
cat > .github/workflows/secret-scan.yml << 'YML'
name: secret-scan
on:
pull_request:
push:
branches: [ main ]
jobs:
trufflehog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # повна історія
- name: TruffleHog Git history scan
run: |
docker run --rm -v "$PWD":/repo ghcr.io/trufflesecurity/trufflehog:latest \
git --fail --only-verified /repo
YML
git add .github/workflows/secret-scan.yml
# git commit -m "CI: add TruffleHog secret scanning"
GitLab CI
cat > .gitlab-ci.yml << 'YML'
stages: [scan]
secret_scan:
image: docker:stable
stage: scan
services: [docker:dind]
script:
- docker run --rm -v "$CI_PROJECT_DIR":/repo ghcr.io/trufflesecurity/trufflehog:latest git --fail --only-verified /repo
only:
- merge_requests
- main
YML
Порада: додайте обов’язковий статус-перевірку на Pull/Merge Request, щоб без зеленої перевірки було неможливо змерджити.
Альтернативні способи
- Тільки git-secrets: легкий і швидкий захист із регулярками. Добре як базовий рівень.
- Gitleaks як альтернатива TruffleHog: схожий клас інструмента, іноді дає менше хибних спрацьовувань.
- Серверні hook-и (pre-receive) на вашому Git-сервері: гарантують, що секрети не пройдуть навіть без локальних перевірок.
- Docker локально: замість установки — запускайте TruffleHog у контейнері для однакового результату на всіх машинах.
GUI-спосіб
Більшість GUI-клієнтів Git автоматично виконують локальні hook-и. Тож після налаштування pre-commit описаного вище, коміт з GUI також буде заблокований, якщо знайдені секрети. Якщо любите VS Code, запускайте сканування з вбудованого терміналу або підключіть завдання (Task), що викликає TruffleHog. Простий приклад ручного запуску:
# Швидка перевірка всієї робочої копії з VS Code терміналу
trufflehog filesystem --fail --only-verified --no-update .
FAQ
Чому коміт блокується, хоча в мене немає секретів?
Це може бути хибнопозитивне спрацювання. Додайте безпечний патерн у allowlist для git-secrets (git secrets --add -l '...' ) або винесіть файли в .trufflehog-exclude (regex-шляхи) для TruffleHog. Також спробуйте параметр --only-verified, щоб зменшити шум.
Як просканувати всю історію репозиторію локально?
# Скан всього git-історі з TruffleHog
trufflehog git --fail --only-verified file://$PWD
Що робити, якщо секрет уже потрапив у Git?
- Негайно відкличте/перегенеруйте ключ у провайдері.
- Приберіть секрет із коду та додайте відповідний запис у .gitignore/allowlist.
- Очистіть історію: скористайтесь git filter-repo або BFG.
# Приклад з BFG (швидко видаляє секретні рядки з історії)
wget -O bfg.jar https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar
java -jar bfg.jar --replace-text replacements.txt # у файлі вкажіть чутливі рядки
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# Пуш з перезаписом історії (узгодьте з командою!)
# git push --force
TruffleHog повільний на великих репо. Як прискорити?
Скануйте лише staged файли у pre-commit (як у нашому hook-скрипті) і повну історію — у CI. Також виключайте великі каталоги через .trufflehog-exclude.
Чи можна запускати все без Python?
Так, використовуйте Docker-образ TruffleHog у локальних перевірках і CI. git-secrets достатньо зібрати з вихідних (make install).
Як переконатись, що кожен у команді використовує hook-и?
Додайте серверний pre-receive hook або обов'язкову CI-перевірку. Локальні hook-и — це зручність, але не заміна політикам у репозиторії.
Порада від Kernelka
Збережіть чисте дерево змін: тримайте секрети поза репозиторієм (менеджери секретів, змінні середовища, KMS/SealedSecrets). А ще зробіть один спільний core.hooksPath для всієї команди та версіонуйте в окремому репозиторії набір корисних hook-ів — так ви отримаєте відтворюваність і менше сюрпризів.
Підсумок
- Увімкніть git-secrets і додайте релевантні сигнатури.
- Додайте TruffleHog у pre-commit для перевірки staged-файлів.
- Налаштуйте CI-сканування повної історії на кожен PR/мердж.
- Керуйте винятками через .gitallowed та .trufflehog-exclude.
- Регулярно перевидавайте ключі й очищайте історію у разі інцидентів.

Прокоментувати
На сайті відображається лише твоє ім'я та коментар. Електронна пошта зберігається виключно для зв'язку з тобою за потреби та в жодному разі не передається стороннім особам.