# Хук secrets: обнаружение жестко заданных секретов

> Проверьте кодовую базу на жестко заданные учетные данные из командной строки.

Канонический URL: https://lagune.ai/ru-RU/docs/hooks/secrets
Язык: ru-RU
Оригинал: https://lagune.ai/docs/hooks/secrets
Последнее обновление: 2026-11-03

Хук `secrets` помечает **учетные данные, вкомпилированные в исходный код**, вместо того чтобы читаться из окружения. Он ориентируется на **происхождение** значения (литерал или чтение из окружения), а не на его содержимое, поэтому ему не нужен исчерпывающий каталог префиксов провайдеров, и он почти не дает ложных срабатываний. Это детерминированный движок, стоящий за [специализацией `secrets`](https://lagune.ai/ru-RU/docs/catalog).

Сигнатуры форматов провайдеров, учетные данные в строках подключения и литерал, привязанный к идентификатору с именем секрета, **не зависят от языка**: одна и та же строка читается одинаково в любом файле. Две эвристики, зависящие от синтаксиса, чтение из окружения с жестко заданным значением по умолчанию и секрет, попадающий в sink логов, **учитывают язык**, поэтому `console.log` из JavaScript никогда не ищется в файле Rust, а `os.getenv("X", "default")` из Python распознается отдельно.

## Запуск

```bash
npx lagune read secrets                  # scans the whole project
npx lagune read secrets --dir src        # scans a directory
npx lagune read secrets --file config.ts # scans a single file
```

Сканирование выводит до двух разделов. **Hardcoded secrets found** содержит находки (жестко заданное значение по умолчанию для переменной окружения с именем секрета, учетные данные, встроенные в строку подключения, или значение, совпадающее с тщательно отобранным форматом провайдера), поэтому хук завершается с ненулевым кодом. **Secret handling to review manually** содержит поводы для проверки: обычный литерал, привязанный к идентификатору с именем секрета (его происхождение определить можно, а вот является ли значение настоящим секретом, нельзя), и значение с именем секрета, попадающее в sink логов или ответа. Если ничего не найдено, выводится `no hardcoded secrets found`.

### Параметры CLI

| Параметр | Значение   | Описание                                                                      |
| -------- | ---------- | ----------------------------------------------------------------------------- |
| `--dir`  | директория | Ограничивает сканирование директорией. Можно повторять и сочетать с `--file`. |
| `--file` | файл       | Ограничивает сканирование одним файлом. Можно повторять и сочетать с `--dir`. |

Без параметров хук сканирует весь проект.

### Охват языков

Находка с запасным значением из окружения и повод для проверки с sink логов читают формы, свои для каждого языка, поэтому охватывают языки ниже и молчат в остальных. Три других сигнала работают для **каждого** файла.

| Сигнал                             | Языки                                                                           |
| ---------------------------------- | ------------------------------------------------------------------------------- |
| Значение по умолчанию из окружения | JavaScript/TypeScript, Python, Ruby, PHP, Kotlin, Java, Go (`cmp.Or`), Rust, C# |
| Sink логов или ответа              | JavaScript/TypeScript, Python, Ruby, PHP, Java, Kotlin, Go, Rust, C, C++, C#    |

**Это не нарушение политики?**

Нет. Распознавание формата секрета, чтобы предупредить, что он попал в коммит, представляет собой стандартный защитный инструментарий, ту же операцию выполняют gitleaks, trufflehog и push protection в GitHub. Хук поставляет сигнатуры для обнаружения (публичные **форматы** токенов), а не настоящие секреты, и проводит аудит и объясняет, а не выносит данные наружу.

## Частые вопросы

### Как хук secrets избегает ложных срабатываний?

Он ориентируется на происхождение, а не на содержимое значения. Форматы с высокой степенью уверенности (токены провайдеров, запасные значения из окружения, строки подключения) считаются находками и дают ненулевой код выхода. Обычный литерал, привязанный к идентификатору с именем секрета, служит поводом для проверки, который нужно подтвердить, а тот же идентификатор, прочитанный из process.env, вообще не помечается.
