← [Раздел](README.md) · [Главная](../README.md)

# Lab 01 — Обнаружение секретов в Git

## Цель

Создать учебный репозиторий с намеренно «утёкшим» фейковым ключом, найти его **Gitleaks**, исправить код и понять, почему секрет остаётся в **истории Git**.

## Предварительно

- Git и Docker.
- Прочитаны [trivy-semgrep-gitleaks.md](../10-instrumenty/trivy-semgrep-gitleaks.md) (раздел Gitleaks).

## Время

~45 минут.

## Шаг 1 — Подготовка каталога

```bash
mkdir -p ~/devsecops-labs/lab01-secrets
cd ~/devsecops-labs/lab01-secrets
git init
git config user.email "learn@example.com"
git config user.name "DevSecOps Learner"
```

## Шаг 2 — «Плохой» коммит

Создайте файл `config.py`:

```python
# УЧЕБНЫЙ ПРИМЕР — НЕ НАСТОЯЩИЙ КЛЮЧ
AWS_ACCESS_KEY_ID = "AKIAFAKEEXAMPLE123"
AWS_SECRET_ACCESS_KEY = "FAKE_SECRET_KEY_FOR_LAB_ONLY_abcdef"
```

```bash
git add config.py
git commit -m "feat: add config (intentionally bad for lab)"
```

## Шаг 3 — «Исправление» без истории

Удалите секреты из файла:

```python
import os

AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "")
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", "")
```

```bash
git add config.py
git commit -m "fix: move secrets to environment variables"
```

## Шаг 4 — Gitleaks на текущем дереве

```bash
docker run --rm -v "$(pwd):/repo" zricethezav/gitleaks:latest \
  detect --source /repo --verbose --redact
```

**Ожидаемый результат:** находка в **истории** (старый коммит), даже если текущий файл чистый.

Запишите в блокнот: файл, commit hash (короткий), rule id.

## Шаг 5 — Скан только последних коммитов

```bash
docker run --rm -v "$(pwd):/repo" zricethezav/gitleaks:latest \
  detect --source /repo --log-opts="HEAD~1..HEAD" --redact
```

Сравните: узкое окно может не показать старый коммит — важно для CI на MR vs full history nightly.

## Шаг 6 — Allowlist (осторожно)

Создайте `gitleaks.toml`:

```toml
title = "lab01"

[allowlist]
paths = ['''config\.py$''']
```

```bash
docker run --rm -v "$(pwd):/repo" -v "$(pwd)/gitleaks.toml:/gitleaks.toml" \
  zricethezav/gitleaks:latest detect --source /repo --config /gitleaks.toml --redact
```

**Вопрос для размышления:** allowlist в prod без тикета — плохая практика. Когда он оправдан?

## Шаг 7 — Ротация (учебная)

Даже для фейкового ключа выполните **процедуру**:

1. Тикет: `SEC-LAB01-001 — обнаружен ключ в Git`.
2. «Отозвать» ключ в воображаемой IAM-консоли.
3. Выдать новый через Vault / CI Variables (см. [vault-i-sekrety.md](../10-instrumenty/vault-i-sekrety.md)).

## Шаг 8 — Очистка истории (опционально, изолированно)

Только в **копии** репозитория:

```bash
cd ~/devsecops-labs
cp -a lab01-secrets lab01-secrets-scrub
cd lab01-secrets-scrub
pip install git-filter-repo  # или brew install git-filter-repo
git filter-repo --path config.py --invert-paths --force
```

Проверьте снова Gitleaks. Обсудите с командой перед `filter-repo` на shared remote.

## Шаг 9 — CI guard (домашнее задание)

Добавьте в `.gitlab-ci.yml` или GitHub workflow job из [gitlab-ci-security.md](../10-instrumenty/gitlab-ci-security.md) / [github-actions-security.md](../10-instrumenty/github-actions-security.md).

## Критерии успеха

- [ ] Gitleaks нашёл секрет в истории.
- [ ] Понимаете разницу «файл исправлен» vs «история чиста».
- [ ] Есть учебный тикет ротации.

## Самопроверка

1. Почему второй коммит не удаляет секрет из первого?
2. Какой `--log-opts` использовать для скана всей истории?
3. Что делать первым после находки реального ключа в main?

## Дальше

[Lab 02 — скан Docker-образа](lab-02-scan-docker-image.md)
