Перенесены секреты из .env в SM

This commit is contained in:
mi
2026-07-30 19:22:48 +03:00
parent 049c45db5c
commit e24ed9d8ef
58 changed files with 3350 additions and 1054 deletions
@@ -262,7 +262,7 @@ han-chat-documents
## 8. Создание файла окружения
На VM:
`.env` содержит только несекретную конфигурацию. На VM:
```sh
cd /opt/han-chat/backend
@@ -272,7 +272,18 @@ chmod 600 .env
nano .env
```
Замените все `change-me` и адреса `example.*`.
Замените несекретные адреса `example.*`. Не добавляйте в `.env` пароли, токены,
ключи, credential-bearing DSN или пути `*_FILE`. Установите отдельно проверенный
launcher `deployment/secrets/han-secrets` из ops-пакета. Его интерфейс:
```sh
deployment/secrets/han-secrets run --config .env -- <command>
```
Launcher читает `SECRETS_SOURCE=file|selectel`, устанавливает
`HAN_SECRETS_ACTIVE=1`, выдаёт значения только дочернему процессу и не печатает
их. Рекомендуемый `HAN_RUNTIME_SECRET_MANIFEST` содержит только пары
`SECRET_KEY=/absolute/protected/path`; файлы имеют mode `0400`/`0600`.
### 8.1. Основные адреса
@@ -295,7 +306,7 @@ KEYCLOAK_AUDIENCE=han-chat-api
### 8.2. PostgreSQL
Укажите фактические host, port, database, пользователей и пароли:
В `.env` укажите только host, port, database и путь к публичному CA:
```dotenv
HAN_PG_HOST=<PG_HOST>
@@ -303,17 +314,13 @@ HAN_PG_PORT=6432
HAN_PG_DATABASE=han_chat
PG_CA_HOST_PATH=/opt/han-chat/backend/secrets/pg/ca.pem
DATABASE_URL=postgresql+asyncpg://han_app:<PASSWORD>@<PG_HOST>:5433/han_chat?sslmode=verify-full&sslrootcert=/run/secrets/pg-ca.pem
BITRIX_DATABASE_URL=postgresql://bitrix_local_app:<PASSWORD>@<PG_HOST>:5433/han_chat?sslmode=verify-full&sslrootcert=/run/secrets/pg-ca.pem
BITRIX_SYNC_DATABASE_URL=postgresql://bitrix_sync_user:<PASSWORD>@<PG_HOST>:5433/han_chat?sslmode=verify-full&sslrootcert=/run/secrets/pg-ca.pem
MESSAGE_SAFETY_DATABASE_URL=postgresql://message_safety_app:<PASSWORD>@<PG_HOST>:5433/han_chat?sslmode=verify-full&sslrootcert=/run/secrets/pg-ca.pem
KEYCLOAK_DB_URL=jdbc:postgresql://<PG_HOST>:5433/han_chat?sslmode=verify-full&sslrootcert=/run/secrets/pg-ca.pem
KEYCLOAK_DB_SCHEMA=keycloak
KEYCLOAK_DB_USERNAME=keycloak_user
KEYCLOAK_DB_PASSWORD=<PASSWORD>
```
Все service DSN, включая JDBC и backup DSN, формирует secret backend. Runtime
validator проверяет `verify-full`, `sslrootcert` и запрет `options/currentSchema`
без вывода строк подключения.
Порт `5433` используется с PgBouncer в режиме `session`. Не добавляйте
`options=-csearch_path...` или JDBC-параметр `currentSchema`: они передают
startup parameter `search_path`, который Selectel PgBouncer отклоняет. Для
@@ -323,9 +330,12 @@ Keycloak схема задаётся отдельно через `KEYCLOAK_DB_SC
Если пароль содержит `@`, `:`, `/`, `?`, `#` или `%`, его необходимо
URL-кодировать внутри PostgreSQL URL.
### 8.3. Генерация секретов
### 8.3. Подготовка runtime-секретов
Для обычных токенов используйте:
Генерируйте секреты вне shell history средствами secret manager. Не выполняйте
`export TOKEN=...` и не вставляйте значения в команды. Имена обязательных
runtime-переменных определены в `scripts/validate-env`; парные токены связываются
в secret backend.
```sh
openssl rand -hex 32
@@ -337,7 +347,8 @@ openssl rand -hex 32
python3 -c 'import base64,secrets; print(base64.urlsafe_b64encode(secrets.token_bytes(32)).decode())'
```
Заполните все секреты. Две пары должны совпадать:
Ни один из этих секретов не добавляется в `.env`. Пары проверяются runtime
validator без вывода значений.
```dotenv
BITRIX_LOCAL_APP_INTERNAL_TOKEN=<TOKEN_A>
@@ -361,7 +372,8 @@ KEYCLOAK_ADMIN_PASSWORD=<UNIQUE_ADMIN_PASSWORD>
### 8.4. Redis
Создайте три разных пароля и продублируйте их в URL:
Создайте три разных пароля в secret backend; там же сформируйте Redis URL.
Следующий блок описывает логический контракт и не является содержимым `.env`:
```dotenv
REDIS_API_PASSWORD=<REDIS_API_PASSWORD>
@@ -380,11 +392,10 @@ MESSAGE_SAFETY_REDIS_URL=redis://message_safety:<REDIS_SAFETY_PASSWORD>@redis:63
```dotenv
KEYCLOAK_OTP_MOCK_ENABLED=true
KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=true
KEYCLOAK_OTP_MOCK_CODE=<ТЕСТОВЫЙ_КОД_НЕ_КОРОЧЕ_16_СИМВОЛОВ>
```
Этот код будет вводиться пользователем при тестовой авторизации. Не используйте
его как production-механизм доставки OTP.
`KEYCLOAK_OTP_MOCK_CODE` хранится только в secret backend. Не используйте mock
как production-механизм доставки OTP.
Целевой real mode задаёт `modules/module-11-idgtl-sms.md`: Keycloak генерирует и локально проверяет OTP, `sms-service` надёжно записывает заказ/журнал, worker вызывает i-Digital Direct, callback обновляет только delivery journal. Нельзя просто установить `KEYCLOAK_OTP_MOCK_ENABLED=false`.
@@ -397,13 +408,10 @@ SELECTEL_S3_ENDPOINT_URL=https://s3.storage.selcloud.ru
SELECTEL_S3_BUCKET_QUARANTINE=han-chat-quarantine
SELECTEL_S3_BUCKET_ATTACHMENTS=han-chat-attachments
SELECTEL_S3_BUCKET_DOCUMENTS=han-chat-documents
SELECTEL_S3_ACCESS_KEY=<API_ACCESS_KEY>
SELECTEL_S3_SECRET_KEY=<API_SECRET_KEY>
SELECTEL_S3_QUARANTINE_READ_ACCESS_KEY=<SAFETY_READ_ACCESS_KEY>
SELECTEL_S3_QUARANTINE_READ_SECRET_KEY=<SAFETY_READ_SECRET_KEY>
```
Обе пары S3 credentials хранятся только в secret backend.
API backend принудительно использует virtual-hosted addressing:
`https://<bucket>.s3.storage.selcloud.ru/<object-key>`. Это обязательно для
браузерных presigned PUT и CORS в Selectel; path-style URL для этого сценария не
@@ -411,20 +419,17 @@ API backend принудительно использует virtual-hosted addre
### 8.7. Bitrix24
До установки локального приложения заполните:
До установки локального приложения загрузите credentials в secret backend.
В `.env` остаются только несекретные connector/public URL параметры:
```dotenv
BITRIX_CLIENT_ID=<BITRIX_CLIENT_ID>
BITRIX_CLIENT_SECRET=<BITRIX_CLIENT_SECRET>
BITRIX_CONNECTOR_ID=han_mobile_app
BITRIX_OPEN_LINE_ID=8
BITRIX_PUBLIC_BASE_URL=https://chat.example.ru/bitrix
BITRIX_TOKEN_ENCRYPTION_KEY=<URLSAFE_BASE64_KEY>
```
`BITRIX_APPLICATION_TOKEN` можно окончательно задать после создания приложения в
Bitrix24. До этого используйте отдельное случайное значение, проходящее
валидацию окружения.
`BITRIX_APPLICATION_TOKEN` сохраняется в secret backend после создания
приложения и никогда не помещается в `.env`.
### 8.8. TLS и наблюдаемость
@@ -448,8 +453,11 @@ ACME_EMAIL=<ADMIN_EMAIL>
```sh
cd /opt/han-chat/backend
./scripts/validate-env .env
docker compose --env-file .env config --quiet
docker compose --env-file .env config --services
sudo systemctl restart han-secrets@production.service
sudo ./scripts/validate-env .env \
--runtime-manifest /run/han-chat/secrets/manifest
sudo deployment/secrets/han-compose config --quiet
sudo deployment/secrets/han-compose config --services
python3 -m unittest discover -s tests -v
```
@@ -670,7 +678,8 @@ curl -i https://chat.example.ru/internal/safety/v1/messages/check
https://chat.example.ru/
```
Для тестовой авторизации используйте значение `KEYCLOAK_OTP_MOCK_CODE` из `.env`.
Для тестовой авторизации получите mock code утверждённым защищённым способом,
не читая его из `.env` и не помещая в shell history.
## 16. Подключение Bitrix24
@@ -685,7 +694,7 @@ Placement: https://chat.example.ru/bitrix/placement
После установки:
1. Получите и сохраните application token.
2. Запишите его в `BITRIX_APPLICATION_TOKEN` файла `.env`.
2. Сохраните его как `BITRIX_APPLICATION_TOKEN` в secret backend.
3. Пересоздайте сервис:
```sh
@@ -735,7 +744,7 @@ docker compose --env-file .env up -d --force-recreate <SERVICE_NAME>
1. Создайте backup/PITR marker PostgreSQL.
2. Сохраните текущие image digests.
3. Получите новый код.
4. Проверьте `.env`.
4. Проверьте несекретный `.env` и runtime secret set.
5. Пересоберите образы.
6. Примените миграции и seed.
7. Пересоздайте сервисы.