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 стоит между приложением, агентами и провайдерами моделей, он становится точкой концентрации секретов, логов, 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.

Read more

Computer-Use-Agenten scheitern an Pixeln: wie Sie auf stabile UI-Referenzen über Accessibility Trees umstellen und fehleranfällige Desktop-Automatisierung nicht mehr ständig reparieren

von Denis Shokhirev, Enterprise AI Architect aus Freiburg im Breisgau Ich bin Denis Shokhirev, Agentic AI Systems Architect in Freiburg im Breisgau, Germany, und bei DennisCraft AI Studio setze ich produktive KI-Systeme für DACH-B2B-Kunden auf Basis von Claude, Supabase, n8n, Doppler und selbst betriebenem Postgres um. Die teuersten Fehler in

By Denis Shokhirev

Компьютерные агенты ломаются на пикселях: как перейти на stable UI refs через accessibility tree и перестать чинить flaky desktop automation

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

By Denis Shokhirev