# Конфигурация проекта iams-v2

Документ описывает все переменные окружения и способы конфигурирования сервиса **iams** (`platform/iams-v2`) — сервиса управления пользователями, ресурсами и правами доступа (IAM).

## Способы конфигурирования

Сервис настраивается **только через переменные окружения**. Разбор выполняется в `internal/app/config.go` (функция `app.Load`) через библиотеку [`github.com/sethvargo/go-envconfig`](https://github.com/sethvargo/go-envconfig) (структура `Config`).

Особенности разбора:

- вложенные секции задаются полями-структурами с тегом `env:", prefix=<PREFIX>_"`, напр. `DB_` → `Config.DB`, `S3_` → `Config.S3`;
- у большинства полей задан дефолт через `env:"NAME, default=..."`; поля без дефолта при отсутствии остаются нулевыми, а обязательность проверяется отдельными валидаторами (см. ниже);
- перед разбором окружения подхватывается env-файл через [`godotenv`](https://github.com/joho/godotenv): путь берётся из переменной `ENV_FILE`, иначе `.env`. Отсутствие файла **не** является ошибкой (ошибка `godotenv.Load` игнорируется), реальные значения читаются из окружения процесса.

Отдельного конфиг-файла (yaml/toml) у приложения нет, за исключением двух внешних файлов, путь к которым задаётся переменными: `ZITADEL_ORG_RULES_FILE` (JSON-правила организаций Zitadel) и `KAFKA_TOPIC_OVERRIDES_FILE` (JSON-переопределения имён топиков).

Валидация на старте (`app.Load`):

- при `S3_ENABLED=true` обязательны `S3_ENDPOINT_URL`, `S3_BUCKET_NAME`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY` — иначе ошибка старта;
- при `ZITADEL_ENABLED=true` обязательны `ZITADEL_HOST`, `ZITADEL_ACCESS_TOKEN`, `ZITADEL_ORG_RULES_FILE` — иначе ошибка старта;
- при заданном `KAFKA_TOPIC_OVERRIDES_FILE` файл читается и парсится как JSON `{event_type: topic}` — при ошибке чтения/парсинга сервис не стартует.

Источники переменных по способам запуска:

| Способ запуска | Откуда берутся переменные |
| --- | --- |
| Локально (бинарник) | Переменные окружения процесса + env-файл (`.env` или `ENV_FILE`), который автоматически загружается `godotenv` |
| Локально (docker compose) | `docker-compose.yml`: сервис `http` получает `DB_DSN`, `KAFKA_ENABLED`, `S3_ENABLED` из окружения хоста; Postgres — из блока `environment` |
| Kubernetes (Helm) | `.helm/values.yaml` (universal-chart): блоки `envs` (обычные значения по окружениям `_default`/`stage`/`production`), `secretEnvs` (значения из k8s-секретов) и `volumes` (монтирование CA-сертификата Kafka) |
| CI/CD (GitLab) | `.gitlab-ci.yml`: переключение стенда по ветке/тегу (`workflow.rules`), общие шаблоны из `generic/common-ci`, `HELM_SET_ARGS` |

Способы запуска процессов (`cmd/*`):

| Команда | Точка входа | Назначение |
| --- | --- | --- |
| `server` (docker `ENTRYPOINT`, `make build`) | `cmd/server/main.go` | HTTP API (Fiber). Флаг `-env-file=PATH` переопределяет `ENV_FILE` |
| `cli migrate` | `cmd/cli/main.go` | Прогон миграций БД (`golang-migrate`). Требует `DB_DSN`; путь миграций — `DB_MIGRATIONS_PATH` |
| `seed` | `cmd/seed/main.go` | Наполнение БД тестовыми данными (флаги `--seed`, `--resources`, `--users`, `--tenant-id`, `--type-id`) |

Docker-образ (`docker/httpserver/Dockerfile`) собирает статический бинарник `server` (scratch-образ) и копирует каталог `config/` (файлы правил Zitadel). Миграции применяются отдельной командой `cli migrate` (в локальном сценарии — целью `make postgres-up`).

## Переменные приложения

В столбце «Переменная» указано полное имя (с учётом префикса секции). Дефолт `—` означает, что в коде значения по умолчанию нет (поле остаётся нулевым, если не задано).

### App (верхний уровень, без префикса)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ENVIRONMENT` | string | `local` | Окружение развёртывания (`local`/`stage`/`prod`) |
| `LOG_LEVEL` | string | `info` | Уровень логирования (`debug`/`info`/`warn`/`error`) |
| `SERVICE_NAME` | string | `iams` | Имя сервиса |
| `SERVICE_VERSION` | string | `0.0.0` | Версия сервиса |

### HTTP (`HTTP_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `HTTP_PORT` | string | `8080` | Порт HTTP-сервера |
| `HTTP_READ_BUFFER_SIZE` | int | `131072` | Размер буфера чтения запроса (Fiber/fasthttp), байты |

### Database (`DB_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DB_DSN` | string | — | DSN PostgreSQL (`postgres://user:pass@host:port/db?sslmode=...`). Обязателен для работы БД и команды `cli migrate` |
| `DB_MIGRATIONS_PATH` | string | `migrations` | Путь к каталогу SQL-миграций |

### Auth (`AUTH_*`)

Конфигурация внешнего контура `/external/api/*`.

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `AUTH_ENABLED` | bool | `false` | При `false` внешний контур не регистрируется и пользовательская авторизация не выполняется; внутренние эндпоинты работают без изменений |

### Sonyflake (`SONYFLAKE_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `SONYFLAKE_MACHINE_ID` | uint16 | `1` | Machine ID генератора идентификаторов `resource.id` для новых записей |

### Zitadel (`ZITADEL_*`)

Management API (Service User с правами администратора). При `ENABLED=true` `HOST`, `ACCESS_TOKEN`, `ORG_RULES_FILE` обязательны.

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ZITADEL_ENABLED` | bool | `false` | Включить интеграцию с Zitadel |
| `ZITADEL_HOST` | string | — | Хост Zitadel (напр. `https://login.sarex.io`) |
| `ZITADEL_ACCESS_TOKEN` | string | — | Access token сервисного пользователя |
| `ZITADEL_ORG_RULES_FILE` | string | — | Путь к JSON-файлу правил организаций (`config/zitadel/org-rules-<env>.json`) |

### S3 (`S3_*`)

Presigned GET для вложений виджета в приватном S3-совместимом бакете. При `ENABLED=true` `ENDPOINT_URL`, `BUCKET_NAME`, `ACCESS_KEY_ID`, `SECRET_ACCESS_KEY` обязательны.

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `S3_ENABLED` | bool | `false` | Включить S3-интеграцию |
| `S3_ENDPOINT_URL` | string | — | Эндпоинт S3 (напр. `https://storage.yandexcloud.net`) |
| `S3_BUCKET_NAME` | string | — | Имя бакета |
| `S3_REGION` | string | `ru-central1` | Регион |
| `S3_ACCESS_KEY_ID` | string | — | Access key |
| `S3_SECRET_ACCESS_KEY` | string | — | Secret key |
| `S3_PRESIGN_EXPIRES` | duration | `1h` | Срок жизни presigned-ссылки (Go duration, напр. `1h`, `15m`) |

### Kafka (`KAFKA_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `KAFKA_ENABLED` | bool | `false` | Включить Kafka-продюсер |
| `KAFKA_BROKERS` | string | `localhost:9092` | Список брокеров |
| `KAFKA_SECURITY_PROTOCOL` | string | `PLAINTEXT` | Протокол (`PLAINTEXT`/`SASL_SSL`/...) |
| `KAFKA_SASL_MECHANISM` | string | — | SASL-механизм (напр. `SCRAM-SHA-512`) |
| `KAFKA_SASL_PLAIN_USERNAME` | string | — | SASL-логин |
| `KAFKA_SASL_PLAIN_PASSWORD` | string | — | SASL-пароль |
| `KAFKA_SSL_CAFILE` | string | — | Путь к CA-сертификату для SSL |

Политика имён топиков (`KAFKA_TOPIC_*`):

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `KAFKA_TOPIC_PREFIX` | string | — | Префикс, добавляемый ко всем именам топиков. По умолчанию `topic = event_type` |
| `KAFKA_TOPIC_OVERRIDES_FILE` | string | — | Путь к JSON-файлу `{event_type: topic}` с переопределениями. Читается на старте |
| `KAFKA_TOPIC_LEGACY_AMS_SYNC` | string | `ams-sync` | Legacy-топик для `BrokerMessage` пользователя |

### OpenTelemetry (`OTEL_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `OTEL_ENABLED` | bool | `false` | Включить трейсинг |
| `OTEL_HOST` | string | `localhost` | Хост OTLP/gRPC-коллектора |
| `OTEL_PORT` | string | `4317` | Порт коллектора |
| `OTEL_INSECURE` | bool | `true` | Небезопасное (без TLS) подключение к коллектору |
| `OTEL_SERVICE_NAME` | string | `iams` | Имя сервиса в трейсах |

## Переменные из Helm-чарта (`.helm/values.yaml`)

Чарт — `universal-chart` (сервис `iams`). Обычные значения задаются в блоке `envs` с профилями `_default`/`stage`/`production` и содержат те же переменные `ENVIRONMENT`, `LOG_LEVEL`, `AUTH_ENABLED`, `HTTP_*`, `DB_MIGRATIONS_PATH`, `ZITADEL_*`, `S3_*`, `KAFKA_*`, `OTEL_*` (различаются адресами БД/брокеров/коллектора, бакетом, доменом Zitadel и путём к файлу правил).

Значения из секретов (блок `secretEnvs`, монтируются как env через `secretKeyRef`):

| Переменная | Секрет (`secretName`) | Ключ (`secretKey`) |
| --- | --- | --- |
| `DB_DSN` | `iams-secret` | `db-dsn` |
| `ZITADEL_ACCESS_TOKEN` | `iams-secret` | `zitadel-access-token` |
| `KAFKA_SASL_PLAIN_USERNAME` | `iams-secret` | `kafka-sasl-plain-username` |
| `KAFKA_SASL_PLAIN_PASSWORD` | `iams-secret` | `kafka-sasl-plain-password` |
| `S3_ACCESS_KEY_ID` | `yc-s3-secret` | `key_id` |
| `S3_SECRET_ACCESS_KEY` | `yc-s3-secret` | `access_key` |

Помимо env, чарт монтирует CA-сертификат Kafka из секрета `ya-ca-secret` как файл `/etc/ca-certificates/Yandex/ca-cert` — именно на него указывает `KAFKA_SSL_CAFILE` в конфигурации стенда/прода.

Прочие значения чарта (не переменные приложения): `deployment.*` (имя, порт `8080`, `replicaCount`: `_default=1`, `production=4`), `image.name` (`cr.yandex/.../iams:latest`), `service.*` (порт/targetPort `8080`).

## Переменные в CI (`.gitlab-ci.yml`)

Пайплайн подключает общие шаблоны из `generic/common-ci` (`common-security-scan.yaml`, `universal-pipeline.yaml@apps-business`) и переключает окружение по ветке/тегу через `workflow.rules`:

| Условие | STAND | Namespace | Chart version |
| --- | --- | --- | --- |
| ветка `stage` | `stage` | `platform` | `0.0.1-stage` |
| тег (`CI_COMMIT_TAG`) | `production` | `iam` | `0.0.1-prod` |
| merge request | — | — | сборка образа отключена (`ENABLE_BUILD_IMAGE=false`) |

Ключевые переменные пайплайна: `SERVICE_NAME=iams`, `DOCKERFILE_PATH=./docker/httpserver/Dockerfile`, `RELEASE_NAME`, `CHART_NAME`, `K8S_HUSTLER_BRANCH`, `HELM_SET_ARGS` (образ, `global.env`, `commitSha`, ссылки на GitLab). Джобы `lint` (`go vet` + `golangci-lint`) и `test` (`go test ./...`) выполняются на merge request.

## Замечания и минимальный набор для локального запуска

- Приложение **загружает env-файл автоматически** (`godotenv`): достаточно положить `.env` рядом с бинарником или указать путь через `ENV_FILE` / флаг `-env-file`. Отсутствие файла не является ошибкой.
- Три интеграции выключены по умолчанию (`ENABLED=false`): `AUTH`, `ZITADEL`, `S3`, `KAFKA`, `OTEL`. Включение любой из `S3`/`ZITADEL` требует заполнения обязательных полей (см. валидаторы выше), иначе сервис не стартует.
- Для локального запуска минимально необходимо задать `DB_DSN` (Postgres поднимается через `docker compose up -d postgres`, миграции — `make postgres-up` → `cli migrate`). Остальные секции можно оставить с дефолтами (`ENABLED=false`).
- Готовые значения-примеры для всех переменных приведены в `.env.example`.
