Version 0.1.0
Основная идея
Получаем файлы сайта через FTP/SFTP/FTPS и сохраняем неизменяемый снимок в S3. Одна задача анализа безопасно распаковывает снимок, запускает проверки и сохраняет результаты. Агент через MCP исследует находки, меняет временную копию и запускает тот же анализ повторно. Пользователь получает отчёт, diff и возможность восстановить копию из снимка; действующий сайт не меняется.
Планируемая версия, не выпущенный релиз. Номер обозначает границу MVP, а не текущую версию пакетов. Сейчас проектируем в документации.
Схема процесса
text
Сайт клиента → FTP / SFTP / FTPS
↓
Получение файлов и манифест
↓
Исходный снимок в закрытом S3
↓
Одна изолированная задача анализа
структура → распаковка → проверки
↓
Отчёт в S3 + находки и статусы в БД
↓
Агент ↔ MCP/API ↔ временная копия
↓
План → изменение → новый снимок
↓
Повторный анализ теми же инструментами
↓
Отчёт + diff + результат remediationАрхив — формат хранения снимка. Проверка структуры, распаковка и сканирование являются шагами одной задачи. Девять страниц этапов архитектуры объясняют путь подробнее, но не означают девять отдельных сервисов.
Компоненты
| Компонент | Ответственность |
|---|---|
| Один backend с API и MCP | Общая авторизация и логика команд, проектов, ключей, задач и результатов |
| PostgreSQL | Сущности, находки, состояния задач и очередь исполнения |
| Закрытое S3-хранилище | Снимки, манифесты, полные отчёты и diff |
| Исполнитель на отдельном сервере | Получение файлов и запуск изолированных контейнеров с ограниченной параллельностью |
| Проверенный внешний MCP-клиент + skill | Исследование находок и один поддерживаемый тип исправления |
Постоянный контейнер на каждого агента не нужен. Временная рабочая папка живёт между вызовами, а чтение, изменение и анализ выполняются контролируемыми инструментами. После простоя папку удаляем; восстанавливаем её из последнего сохранённого снимка. Несохранённая попытка после сбоя не считается результатом.
Минимальный интерфейс предоставляет вход, команду, сайт, защищённый ввод подключения и выдачу ключа. Полный чат Agentfy/Bridle не блокирует 0.1.0. Команды и ключи сохраняем сразу в модели данных.
Очередь без отдельного сервиса
Backend записывает задачу в PostgreSQL и возвращает её идентификатор. Исполнитель забирает задачу с ограниченным сроком владения и сохраняет прогресс. После сбоя истёкшую задачу можно повторить.
Нужны номер попытки, срок владения, ограничение повторов и идемпотентность. При завершении проверяем актуальный идентификатор владения: просроченный исполнитель не может перезаписать результат новой попытки. Транзакцию БД не держим открытой на всё время анализа.
SKIP LOCKED подходит для конкурентного разбора таблицы задач, но сам не реализует сроки владения и восстановление. Предлагаем строить очередь на возможностях PostgreSQL. Redis и отдельный брокер в этой версии не нужны.
Упрощения
- Только прямое получение файлов; PHP-сборщик отложен.
- Фиксированный набор проверок: существующие правила Securify и выбранный антивирус. Дополнительные движки добавляем после проверки пользы.
- Проверка структуры и безопасная распаковка, затем анализ файлов. Два одинаковых полных антивирусных прохода по ZIP и дереву не нужны.
- Вложенные архивы проверяет антивирус с лимитами. Пропуски отражаются в покрытии.
- В одной рабочей копии допускаем только одно активное исправление.
- Полный новый снимок сохраняем для завершённой попытки, а не каждой правки строки. Цепочки дельт и дедупликацию пока не строим.
- Исходный снимок уже содержит оригиналы. До изменения проверяем его доступность и защищаем от удаления на время работы и установленный срок восстановления.
- Восстанавливаем всю рабочую копию из снимка. Частичный откат файлов не нужен.
Границы безопасности
Получение файлов имеет сетевой доступ к хостингу и секрет конкретного подключения. Анализатор их не получает. Подготовка входа и выгрузка артефактов выполняются отдельно от обработки недоверенного содержимого.
Контейнер анализа работает без сети, под непривилегированным пользователем, с лимитами CPU, памяти, диска, процессов и времени. Он не получает Docker socket, доступ к БД или ключи платформы. Контейнерами управляет только доверенный исполнитель. Отдельный сервер не гарантирует изоляцию между задачами: перед публичным запуском проверяем ограничения и очистку. Границы безопасности Docker.
Не запускаем PHP клиента. Проверяем пути, ссылки и объём при распаковке. Неполный сбор или анализ не выдаём за отсутствие угроз. Проверяем права команды и отзыв ключа перед чувствительными действиями. Секреты не попадают в контекст модели и обычные отчёты.
Порядок разработки
| Шаг | Критерий готовности |
|---|---|
| 1. Данные и доступ | User → team → project, connection и ключи; чужой ресурс недоступен, отзыв работает |
| 2. Снимок | Скачивание с лимитами, манифестом и проверенной загрузкой в S3; пропуски видны |
| 3. Исполнитель и анализ | Задача из БД проходит распаковку и проверки; сбой и повтор не дублируют итог |
| 4. Результаты | Отчёт в S3, находки в БД; удаление контейнера не теряет результат |
| 5. MCP и skill | Реальный агент получает сводку, ищет и читает разрешённые фрагменты кода |
| 6. Исправление | Один выбранный класс: план, исходные хеши, изменение копии, новый снимок и повторный scan |
| 7. Восстановление | Копия пересоздаётся из снимка, хеши совпадают; история попытки сохраняется |
Принимаем версию на синтетическом сайте через весь цикл. Проверяем также неполное скачивание, опасные пути, превышение лимитов, чужие идентификаторы, отзыв ключа, остановку исполнителя, повтор запроса, конфликт хешей и сбой сохранения артефактов.
Публикация на хостинг, запуск магазина с БД, Kubernetes, PHP-сборщик, сложный поиск по коду, автоматический биллинг и оптимизация моделей не являются условиями готовности этой версии.