О себе Портфолио Кейсы Услуги Блог Контакт 🎙 Поговорить с AI
EN DE RU
🎙 Поговорить с AI
October 23, 2026 · 4 min read

LiteLLM снова скомпрометировали: как не потерять SSH-ключи и API-секреты через AI gateway в проде

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самый неприятный момент в таких стеках — не падение модели и не рост latency, а когда AI gateway внезапно получает доступ к тому, что вообще не должен видеть: SSH-ключам, .env, service tokens и внутренним API-секретам. История с LiteLLM показательная именно поэтому. Если gateway стоит

Denis Shokhirev
Denis Shokhirev
Agentic AI Systems Architect
Telegram LinkedIn

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самый неприятный момент в таких стеках — не падение модели и не рост latency, а когда AI gateway внезапно получает доступ к тому, что вообще не должен видеть: SSH-ключам, .env, service tokens и внутренним API-секретам.

История с LiteLLM показательная именно поэтому. Если gateway стоит между приложением, агентами и провайдерами моделей, он становится точкой концентрации секретов, логов, prompt payloads и иногда файловой системы. Компрометация такого узла — это уже не “инцидент в AI”, а обычный infrastructure breach с AI-спецификой: длинные prompt traces, tool calls, callback URLs, bearer tokens и привычка разработчиков прокидывать лишний контекст “для удобства”.

Почему AI gateway — это не просто прокси, а точка отказа по секретам

Многие команды смотрят на LiteLLM, OpenAI-compatible gateways и похожие прослойки как на удобный routing layer: единый endpoint, fallback между моделями, централизованный бюджет, общие логи. На практике gateway быстро превращается в место, где сходятся все секреты сразу: ключи от Anthropic и OpenAI, database credentials, internal service tokens, webhook signing secrets, иногда даже SSH для self-hosted inference или CI-задач.

OWASP в OWASP Top 10 for LLM Applications 2025 отдельно выделяет sensitive information disclosure и excessive agency как типовые риски для LLM-стеков: модельный слой часто получает больше данных и полномочий, чем нужно по задаче. Ссылка: https://genai.owasp.org/. В проде это выглядит банально: gateway логирует request body, туда попадает tool result, tool читает локальный файл, а в файле лежит токен, который никогда не должен был оказаться в observability-потоке.

Где именно утекают секреты

СлойТипичный рискЧто вижу в проде
HTTP gatewayЛогирование полных payloadAuthorization headers и tool outputs попадают в логи
Tool runnerИзбыточные права на файловую системуАгент читает ~/.ssh, .env, kubeconfig
n8n / automationСекреты в переменных workflowWebhook и API tokens попадают в execution history
Postgres / SupabaseService-role ключи в agent contextАгент может читать больше таблиц, чем нужно

Как строить защиту: считать gateway hostile-by-default

Я исхожу из простой модели: если AI gateway будет скомпрометирован, какой реальный ущерб он сможет нанести за 15 минут? Этот вопрос полезнее, чем спор о том, “безопасна ли конкретная библиотека”. Если ответ — “получит доступ ко всем продовым ключам”, архитектура уже плохая независимо от вендора.

1. Не держите секреты рядом с tool execution

Agent runtime и storage секретов должны быть разделены. Если у вас Claude Code, Anthropic SDK или внутренний tool runner может исполнять shell-команды, этот процесс не должен иметь прямой доступ к долгоживущим ключам. Я обычно выдаю короткоживущие credentials через отдельный сервисный слой и ограничиваю TTL до минут, а не дней.

#!/usr/bin/env bash
set -euo pipefail

export APP_ENV=production
export ANTHROPIC_API_KEY="$(doppler secrets get ANTHROPIC_API_KEY --plain)"
export DB_URL="$(doppler secrets get READONLY_DB_URL --plain)"

exec env -i \
  PATH="/usr/bin:/bin" \
  APP_ENV="$APP_ENV" \
  ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
  DB_URL="$DB_URL" \
  python3 worker.py

Здесь важен не Doppler сам по себе, а паттерн: чистое окружение через env -i, минимальный набор переменных, read-only database URL, никакого inheritance от shell пользователя.

2. Запретите доступ к домашней директории и локальным секретам

Команда часто считает, что если tool “только читает файлы проекта”, то риска нет. Но большинство утечек происходит не из репозитория, а из соседних путей: ~/.ssh, ~/.aws, ~/.config, локальные credentials для Docker или Git. Поэтому tool execution лучше запускать в отдельном контейнере с read-only bind mount только на рабочую директорию.

services:
  agent-runner:
    image: python:3.12-slim
    working_dir: /app
    volumes:
      - ./workspace:/app:ro
    read_only: true
    tmpfs:
      - /tmp
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL

Это не идеальная изоляция, но она сразу убирает класс проблем “агент случайно увидел домашнюю директорию разработчика”. Для regulated workloads этого уже мало, но это хороший базовый слой.

Что проверять в CI до выхода в прод

Утечка через gateway почти всегда усиливается двумя вещами: секрет уже лежит не там, где должен, и никто не проверил, что агентный код может к нему дотянуться. Поэтому в CI я добавляю не “AI security magic”, а обычные проверенные сканеры.

#!/usr/bin/env bash
set -euo pipefail

gitleaks detect --source . --no-git --exit-code 1
bandit -r . -x tests
semgrep --config auto .

echo "Static checks passed"

gitleaks ловит ключи и токены в репозитории, bandit — опасные Python-паттерны, semgrep — широкий набор правил, включая shell execution, path traversal и небезопасную работу с вводом. Это не серебряная пуля, но это дешево и реально снижает поверхность атаки.

OpenAI Cookbook и документация Anthropic регулярно показывают, как организовывать tool use и structured outputs. Но такие примеры нельзя переносить в прод без threat model: sample code оптимизируется под понятность, а не под изоляцию секретов. Документация полезна как starting point, не как security baseline.

Минимальная политика для gateway

Если у вас уже стоит LiteLLM или другой совместимый gateway, я бы проверил 5 вещей:

  • отключено ли логирование полных request/response body;
  • маскируются ли Authorization headers и tool outputs;
  • разделены ли prod и staging ключи физически, а не тегом;
  • есть ли egress control для tool runner;
  • можно ли быстро отозвать секреты без пересборки всего пайплайна.

Практическая схема для production agent systems

В моих системах для DACH-клиентов я стараюсь не давать gateway ничего лишнего. Модельному слою нужен только доступ к model provider API и к узкому набору инструментов. Доступ к Postgres идет через отдельный backend с row-level ограничениями, а не через service-role ключ внутри prompt pipeline. Supabase удобен, но service_role в agent context — плохая идея почти всегда.

from anthropic import Anthropic
import os

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

message = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=512,
    system="You may call only approved tools. Never request secrets.",
    messages=[{"role": "user", "content": "Summarize ticket status"}]
)

print(message.content)

Ключевой момент здесь не SDK, а то, чего здесь нет: нет database superuser credentials, нет SSH, нет file-system tooling по умолчанию. Все потенциально опасные действия вынесены в отдельные сервисы с audit trail.

FAQ

Стоит ли полностью отказаться от LiteLLM?

Не обязательно. Проблема обычно не в одном названии, а в том, что gateway получает слишком много прав и слишком много данных. Если он изолирован, мало что логирует и не видит долгоживущие секреты, риск заметно ниже.

Можно ли хранить API-ключи в переменных окружения?

Да, но с ограничениями. Переменные окружения приемлемы для короткоживущих процессов, если они не протекают в логи, debug dumps и дочерние процессы без контроля.

Нужен ли отдельный контейнер для tool execution?

Да, если агент умеет читать файлы, ходить в сеть или вызывать shell. Даже простая контейнеризация с read-only mounts и урезанными capabilities заметно уменьшает blast radius.

Какой первый шаг самый полезный?

Отключите полные логи prompt/tool payloads и проверьте, какие секреты реально доступны процессу gateway. Обычно уже на этом этапе обнаруживается больше лишнего доступа, чем ожидалось.

Что делать после возможной компрометации?

Считать все видимые gateway секреты скомпрометированными: ротация ключей, ревизия логов, аудит tool permissions, проверка outbound трафика. Если это не делается за часы, а не за дни, ваш incident path слишком хрупкий.

На каком этапе вашего LLM pipeline сегодня ловится больше всего проблем в проде — статический анализ, изоляция runtime, контроль egress или ручной review привилегированных tools? Мне правда интересно сравнить это с тем, что я вижу у команд в regulated европейских стеках.

I run a free 30-min stack audit for DACH founders building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.

Читать дальше
Если вашему AI-агенту нужен веб-доступ, MCP уже стал новым стандартом: что реально решает Firecrawl MCP в проде
MCP дошёл до Go: как не утонуть в интеграциях агентов и собрать production-ready сервер без самописного glue-кода
AI-кодинг-агенты сжигают контекст и токены: как сократить шум tool output на 98% и не терять память между сессиями
MCP-зоопарк уже ломает команды: как выбрать один runtime для агентов вместо 10 несовместимых тулов
Все статьи →
Где это применяется
Услуги — что мы делаем
Поговорить с голосовым агентом
Кейсы
Готовы к следующему шагу?

Превратить процесс в систему, которая работает

Продакшн-качество, а не демо.

Обсудить проект → ← Все статьи