снят мёртвый godotenv.Load() вместе с зависимостью
- переменных окружения наш рабочий код больше не читает нигде: ушли вызов, импорт и предупреждение на старте - у оставленной строки .env в .gitignore и у запрета forbidigo переписаны причины: прежние называли живым снесённого читателя - в документы записано, что барьеры против .env стоят без читателя, и правило парности .gitignore с .dockerignore
This commit is contained in:
@@ -10,15 +10,17 @@
|
||||
|
||||
**Механизировано:** запрет `os.Getenv` — `forbidigo` в `.golangci.yml`
|
||||
([go-linters.md](go-linters.md), «Механизировано»). Он держит правило «настройки
|
||||
приезжают из TOML»; `godotenv` в `cmd/transcriber` по-прежнему загружает `.env`, но кладёт
|
||||
его в окружение процесса, а не в настройки приложения.
|
||||
приезжают из TOML»: наш рабочий код окружение не читает вовсе — читателя `.env`
|
||||
в `cmd/transcriber` сняли 2026-08-23 вместе с зависимостью. Окружение остаётся
|
||||
у границы SDK: `aws-sdk-go-v2` в `internal/adapter/recognizer/yandex/s3.go`
|
||||
зовёт `config.LoadDefaultConfig`, а тот читает `AWS_PROFILE`, `AWS_CA_BUNDLE`,
|
||||
`AWS_ENDPOINT_URL` и `AWS_ENDPOINT_URL_S3` и смотрит `~/.aws/config`.
|
||||
|
||||
## Принципы
|
||||
|
||||
- **Конфигурация — только TOML.** Переменные окружения для конфигурации **не
|
||||
используем**: окружение наследуется дочерними процессами и видно через
|
||||
`/proc/<pid>/environ` — для секретов это слабее файла под `0600`.
|
||||
*Расхождение:* `cmd/transcriber` зовёт `godotenv.Load()` и молча продолжает без файла.
|
||||
- Грузим **один раз при старте** в одну типизированную структуру `Config`
|
||||
(под-структуры по секциям). Дальше по коду читаем только её — чтения файла в
|
||||
прикладном коде нет, только загрузчик `internal/config`.
|
||||
@@ -127,6 +129,16 @@ Ansible из `pet-project-server`). Приложение просто читае
|
||||
текст остаётся как есть — иначе за разборчивость отказа платили бы там, где
|
||||
платить не за что.
|
||||
|
||||
**Файл, способный нести секрет, называется в `.gitignore` и в
|
||||
`.dockerignore`.** Путей наружу у такого файла два, и закрывает
|
||||
их разное: git держит `.gitignore`, а контекст сборки образа — `.dockerignore`,
|
||||
потому что docker `.gitignore` не читает. Сегодня в обоих названы `config.toml`
|
||||
и `.env`. Правило записано прозой и держится чтением: сверка двух списков стала
|
||||
бы проверкой над проверкой, а такие проект не заводит
|
||||
([../../CLAUDE.md](../../CLAUDE.md), «Запреты»). До 2026-08-23 парность не
|
||||
называл ни один документ, и прогон, снимавший мёртвого читателя `.env`, снял
|
||||
строку с одной стороны — вернуло её ревью.
|
||||
|
||||
## Проверка и остановка на старте
|
||||
|
||||
Конфиг проверяем **на старте, до приёма трафика**. Негодный конфиг — лог `ERROR`
|
||||
|
||||
@@ -336,6 +336,17 @@ Storage, оттуда его читает SpeechKit. Третий путь —
|
||||
Всё перечисленное лежит в `config.toml`. Файл в `.gitignore`, на сервер его
|
||||
кладёт Ansible; `gitleaks` на pre-commit смотрит только индекс коммита.
|
||||
|
||||
**Строки `.env` в `.gitignore` и в `.dockerignore` стоят без читателя, и снимать
|
||||
их поэтому нельзя.** Читателя сняли 2026-08-23 вместе с зависимостью
|
||||
`godotenv`: наш рабочий код окружение не читает, и файл, положенный рядом с
|
||||
бинарником, ничего не меняет. Барьеры остались против другого — против того,
|
||||
чтобы секрет завёлся в этом файле руками и уехал из него теми же двумя путями,
|
||||
какими уехал бы из конфига: в git и в контекст сборки образа. Второй барьер
|
||||
нужен отдельно от первого: `Dockerfile` копирует корень целиком (`COPY . .`), а
|
||||
`.gitignore` docker не читает — чужой `.env` лёг бы слоем образа. Инвариант,
|
||||
ради которого барьеры стоят, — «Секрет не покидает конфиг» из
|
||||
[../CLAUDE.md](../CLAUDE.md).
|
||||
|
||||
Целевой периметр добавляет к списку пять записей, и первая из них — новый вид
|
||||
секрета, которого сегодня в проекте нет вовсе:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user