Skip to content

Commit f556af5

Browse files
committed
Добавлена поддержка условной проверки SSL для GigaChat
- Добавлен флаг конфигурации GIGACHAT_VERIFY_SSL_CERTS в backend/config.py - Обновлен gigachat_helper.py для условной проверки SSL-сертификатов - При GIGACHAT_VERIFY_SSL_CERTS=false приложение работает без корневого сертификата - Обновлена документация в env.example и README.md с предупреждениями о безопасности - Добавлена инструкция instruction-no-ssl.md
1 parent f706763 commit f556af5

File tree

5 files changed

+67
-10
lines changed

5 files changed

+67
-10
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ YANDEX_API_KEY=your_yandex_key_here
176176
# GigaChat
177177
GIGACHAT_CREDENTIALS=your_gigachat_credentials
178178
GIGACHAT_CERT_PATH=russian_trusted_root_ca.cer
179+
GIGACHAT_VERIFY_SSL_CERTS=true # false позволяет работать без корневого сертификата (на свой риск)
179180

180181
# Тестовый режим (без API-ключей)
181182
TEST_MODE=true
@@ -206,6 +207,11 @@ REACT_APP_DEBUG=true
206207
- Все функции работают, но без реального анализа
207208
- Полезно для тестирования интерфейса
208209

210+
### Настройка GigaChat и SSL-сертификаты
211+
По умолчанию для работы с GigaChat требуется корневой сертификат `russian_trusted_root_ca.cer`. Если у вас нет установленного корневого сертификата, вы можете отключить проверку SSL-сертификатов, установив `GIGACHAT_VERIFY_SSL_CERTS=false` в `.env`.
212+
213+
**⚠️ ВАЖНО: Отключение проверки SSL-сертификатов небезопасно!** При `GIGACHAT_VERIFY_SSL_CERTS=false` приложение не будет проверять подлинность сертификата сервера GigaChat, что делает соединение уязвимым для атак "человек посередине" (MITM). Используйте этот параметр только в тестовых окружениях или если вы полностью понимаете связанные риски безопасности. В production всегда используйте `GIGACHAT_VERIFY_SSL_CERTS=true` с корректным файлом сертификата.
214+
209215
## Тестирование и типизация
210216

211217
### Backend (pytest + mypy)

backend/config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
load_dotenv(dotenv_path=_root_env_path)
1313

1414

15+
def _get_bool(key: str, default: str = "false") -> bool:
16+
"""
17+
Преобразует строковое значение переменной окружения в булево.
18+
"false", "0", "no" (case-insensitive) → False, иначе True.
19+
"""
20+
value = os.getenv(key, default).lower()
21+
return value not in ("false", "0", "no")
22+
23+
1524
class Config:
1625
"""Централизованный класс конфигурации."""
1726

@@ -21,6 +30,7 @@ class Config:
2130
YANDEX_API_KEY: Optional[str] = os.getenv("YANDEX_API_KEY")
2231
GIGACHAT_CREDENTIALS: Optional[str] = os.getenv("GIGACHAT_CREDENTIALS")
2332
GIGACHAT_CERT_PATH: Optional[str] = os.getenv("GIGACHAT_CERT_PATH")
33+
GIGACHAT_VERIFY_SSL_CERTS: bool = _get_bool("GIGACHAT_VERIFY_SSL_CERTS", "true")
2434

2535
# Security & Rate Limiting
2636
API_KEY: Optional[str] = os.getenv("API_KEY") # опционально, если не задан - проверка отключена

backend/llm/gigachat_helper.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,30 @@ def get_giga_response(user_prompt: str, model: str = "GigaChat:latest") -> str:
1818

1919
try:
2020
credentials = Config.GIGACHAT_CREDENTIALS
21-
cert_path = Config.GIGACHAT_CERT_PATH or "russian_trusted_root_ca.cer"
21+
verify_ssl = Config.GIGACHAT_VERIFY_SSL_CERTS
2222

2323
if not credentials:
2424
logger.error("Не найдены учетные данные GigaChat в переменных окружения")
2525
return "Не удалось получить ответ от GigaChat: отсутствуют учетные данные"
2626

27-
# Проверяем наличие сертификата
28-
if not os.path.exists(cert_path):
29-
logger.warning(f"Сертификат {cert_path} не найден")
30-
return "Не удалось получить ответ от GigaChat: отсутствует сертификат"
27+
# Формируем параметры для GigaChat
28+
giga_kwargs = {
29+
"credentials": credentials,
30+
"verify_ssl_certs": verify_ssl
31+
}
32+
33+
# Проверяем наличие сертификата только если проверка SSL включена
34+
if verify_ssl:
35+
cert_path = Config.GIGACHAT_CERT_PATH or "russian_trusted_root_ca.cer"
36+
if not os.path.exists(cert_path):
37+
logger.warning(f"Сертификат {cert_path} не найден")
38+
return "Не удалось получить ответ от GigaChat: отсутствует сертификат"
39+
giga_kwargs["ca_bundle_file"] = cert_path
40+
else:
41+
logger.warning("SSL-валидация для GigaChat отключена (GIGACHAT_VERIFY_SSL_CERTS=false). Это небезопасно!")
3142

3243
# Создаем клиент GigaChat
33-
giga = GigaChat(
34-
credentials=credentials,
35-
ca_bundle_file=cert_path,
36-
verify_ssl_certs=True
37-
)
44+
giga = GigaChat(**giga_kwargs)
3845

3946
# Создаем структуру сообщения для API
4047
messages = [

env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ YANDEX_API_KEY=your_yandex_key_here
88
# GigaChat
99
GIGACHAT_CREDENTIALS=your_gigachat_credentials
1010
GIGACHAT_CERT_PATH=russian_trusted_root_ca.cer
11+
GIGACHAT_VERIFY_SSL_CERTS=true # false позволяет работать без корневого сертификата (на свой риск)
1112

1213
# Test mode (useful for UI demo without real keys)
1314
TEST_MODE=true

instruction-no-ssl.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# instruction-no-ssl
2+
3+
Документ для агента Cursor. Цель ― разрешить работе с `gigachat` как с установленным корневым сертификатом, так и без него, управляя проверкой TLS через конфигурацию. Никаких изменений библиотек не требуется.
4+
5+
## План правок
6+
7+
1. **Новый флаг конфигурации.** Добавить в `backend/config.py` булеву опцию `GIGACHAT_VERIFY_SSL_CERTS`, которая читается из переменной окружения `GIGACHAT_VERIFY_SSL_CERTS`. Значение по умолчанию — `true`. Преобразование строки в bool делай по тому же принципу, что и уже существующие флаги (`TEST_MODE` и т.п.): `"false"`, `"0"`, `"no"``False`, иначе `True`.
8+
2. **Обновить `backend/llm/gigachat_helper.py`.**
9+
- Забрать новое значение из `Config` и использовать переменную `verify_ssl`.
10+
- Проверку существования файла сертификата и передачу `ca_bundle_file` выполняем **только** если `verify_ssl` истинно.
11+
- Если проверка отключена, не требуй файл сертификата и не выходи с ошибкой; вместо этого логируй `warning`, что SSL-валидация отключена.
12+
- Сформируй `giga_kwargs` с обязательным `credentials` и `verify_ssl_certs=verify_ssl`. Добавляй `ca_bundle_file=cert_path` лишь при включённой проверке.
13+
- Сообщения для пользователя оставь русскими, но обнови текст, чтобы в ветке без сертификата не упоминалось требование файла.
14+
3. **Документация.**
15+
- В `env.example` (и в соответствующем примере блока `.env` в `README.md`) добавь строку `GIGACHAT_VERIFY_SSL_CERTS=true` с коротким комментарием, что `false` позволяет работать без корневого сертификата (на свой риск).
16+
- В разделе README про GigaChat допиши абзац, объясняющий, что переменная `GIGACHAT_VERIFY_SSL_CERTS=false` отключает проверку сертификата, и подчеркни риски безопасности.
17+
18+
## Детали реализации
19+
20+
- В `backend/config.py` удобно завести небольшой приватный helper, например `_get_bool(key: str, default: str = "false") -> bool`, чтобы не дублировать преобразование строк в bool. Если не хочешь вводить helper, напиши выражение в одну строку по аналогии с `TEST_MODE`.
21+
- В `gigachat_helper` следи за тем, чтобы `logger.warning` срабатывал только при `verify_ssl` выключенном, иначе журнал зашумится.
22+
- Возвращаемые пользователю строки (ответы при отсутствии credentials или ошибок) должны остаться в стиле текущего файла; просто убери упоминание обязательного сертификата из ветки, которая теперь выполняется условно.
23+
24+
## Проверка
25+
26+
1. `pytest -q` из корня (убедись, что тесты проходят с `TEST_MODE=true`).
27+
2. Локально прогонять приложение не требуется, но можно быстро вручную вызвать `python - <<'PY' ...` и убедиться, что импорт `backend.llm.gigachat_helper` работает при отсутствии `GIGACHAT_CERT_PATH`, если в `.env` прописать `GIGACHAT_VERIFY_SSL_CERTS=false`.
28+
29+
## Готовность задачи
30+
31+
- Новая переменная окружения задокументирована.
32+
- При `GIGACHAT_VERIFY_SSL_CERTS=false` приложение не требует файл `russian_trusted_root_ca.cer`, не падает при его отсутствии и логирует предупреждение.
33+
- При значении `true` поведение остаётся прежним: без сертификата появляется понятная ошибка.

0 commit comments

Comments
 (0)