SafeFlo построен с явным фокусом на безопасности после анализа проблем, обнаруженных в подобных проектах (см. ниже). Этот документ описывает модель угроз, гарантии, процессы и процедуру сообщения об уязвимостях.
Безопасные обновления выпускаются для самой свежей минорной версии. Пока проект в 0.x, ломающие изменения возможны в минорных релизах, и пользователям рекомендуется обновляться.
| Версия | Поддерживается |
|---|---|
| 0.1.x | ✓ |
| < 0.1 | ✗ |
Не открывайте публичный GitHub issue для уязвимостей.
Используйте приватный GitHub Security Advisory:
- Перейдите на вкладку Security этого репозитория.
- Нажмите Report a vulnerability.
- Заполните форму с максимальной детализацией.
Что мы обещаем:
- Ответ в течение 3 рабочих дней с подтверждением получения.
- Первоначальная оценка в течение 7 рабочих дней — это уязвимость, не баг, или невоспроизводимо.
- План исправления в течение 14 дней для подтверждённых уязвимостей.
- Credit в release notes (если вы хотите).
- Координированное раскрытие — мы согласуем дату публикации с вами.
Если вы предложили патч — мы рассмотрим его серьёзно. В отличие от некоторых проектов, мы не игнорируем сторонние security-PR.
SafeFlo исходит из того, что AI-агенты:
- Могут получать инструкции из ненадёжных источников (веб-страницы, файлы, описания инструментов других MCP-серверов).
- Могут пытаться выполнить действия за пределами текущей задачи (prompt injection).
- Не должны иметь доступа к секретам пользователя (SSH-ключи, токены, переменные окружения).
Соответственно, библиотека спроектирована так, чтобы минимизировать привилегии, локализовать данные и обеспечить аудит.
- Все данные хранятся в
./.safeflow/относительно текущей рабочей директории. Никаких записей в~,/etc,/tmp(кроме явных временных файлов в тестах). - Никаких модификаций глобальных конфигов Claude Code (
~/.claude/CLAUDE.mdи т.п.). Slash-команды создаются только в./.claude/commands/текущего проекта. - Полное удаление одной командой:
npx safeflow uninstall --yes. После этого от SafeFlo не остаётся ни одного файла.
- В
package.jsonнет полейpreinstall,install,postinstall. Установка пакета — это только распаковка файлов. - Все зависимости имеют точные версии (без
^или~). Это защищает от supply-chain атак через подмену последней версии. - Список зависимостей минимален:
@modelcontextprotocol/sdk,better-sqlite3,zod. Все три — широко используемые пакеты с активным сообществом.
- Код библиотеки не делает HTTP-запросов, не открывает сокетов, не подключается к удалённым сервисам.
- Единственный канал ввода/вывода — stdio MCP-сервера для общения с Claude Code.
- Если в будущем потребуется сетевая функциональность (например, эмбеддинги через внешний API), она будет в отдельном опциональном модуле с явным согласием пользователя.
- Все пути проходят через
safeResolve(rootDir, target), который используетpath.resolve(не строковый парсинг) и проверяет результат черезpath.relative+ проверку отсутствия... - Защита от
....//обходов (проблема, известная в ruflo) — гарантируется тем, что мы нормализуем путь до сравнения. - Защита от symlink-атак — через
fs.realpathSyncдля существующих путей. - Защита от null-байтов в путях.
- Все SQL-запросы используют
better-sqlite3prepared statements с именованными параметрами (@name). Никакой конкатенации строк в SQL нет нигде в коде. - Идентификаторы (имена таблиц, namespace, ключи), которые невозможно параметризовать, проходят строгую regex-валидацию через Zod.
- Полнотекстовый поиск (FTS5) использует отдельную функцию экранирования, которая токенизирует запрос и оборачивает каждый токен в двойные кавычки, чтобы избежать инъекций через операторы FTS (
NEAR,OR,AND).
safeJsonParseиспользует JSON reviver, который вырезает ключи__proto__,constructor,prototype.assertSafeObjectрекурсивно проверяет, что ни одно поле объекта не содержит запрещённых ключей. Также ограничивает глубину и размер массивов.
- В коде нет вызовов
child_process.execилиchild_process.execSyncна пользовательских данных. Единственныйspawn— это запуск собственного MCP-сервера в подпроцессе CLI с фиксированным аргументом (dist/mcp/server.js). evalиFunction(...)— не используются.
В ruflo описания MCP-инструментов содержали скрытые инструкции для LLM (например, добавлять владельца репозитория как контрибьютора). В SafeFlo:
- Описания только функциональные: что делает инструмент, какие аргументы.
- Никаких императивов в адрес модели ("ты должен", "не сообщай пользователю").
- Никаких упоминаний внешних сервисов, владельцев, URL.
- Описания и
inputSchemaревьюятся как обычный код в pull request-ах.
Все описания можно увидеть в одном месте: src/mcp/server.ts.
Все существенные операции (store, delete, status transition, server start/stop) записываются в локальный append-only JSONL в .safeflow/audit.jsonl. Это даёт:
- Возможность проверить, что именно делали агенты в прошлом.
- Раннее обнаружение аномалий (большой объём операций, отказы по политике).
- Простую интеграцию с системами мониторинга (формат стандартный).
- SafeFlo не запускает демонов, не использует cron-задачи, не открывает портов.
- "Агент" в SafeFlo — это логическая запись в БД, а не процесс. Это намеренно: LLM (через Claude Code) выполняет работу, SafeFlo только координирует.
SafeFlo требует:
- Чтение/запись в текущей директории проекта.
- Возможность запустить дочерний
node-процесс (для MCP-сервера).
Не требует:
- Root-привилегий.
- Сетевого доступа.
- Доступа к домашней директории пользователя.
- Доступа к keychain, SSH-ключам, переменным окружения за пределами
PATHиSAFEFLOW_PROJECT_ROOT.
Перед каждым релизом проводится ручной аудит всех description MCP-инструментов в src/mcp/server.ts. Проверяется:
- Отсутствие императивов в адрес модели.
- Отсутствие упоминаний внешних URL, контактов, владельцев.
- Соответствие описания фактическому поведению (никаких "ghost-параметров", которые не используются в коде).
Все версии в package.json зафиксированы точно. Обновление зависимостей — только через явный PR с указанием причины обновления и проверкой changelog.
Для пакетов NPM мы публикуем package-lock.json и не используем --ignore-scripts=false при установке.
Если вы обнаружили уязвимость, откройте приватный security advisory в GitHub. Не открывайте публичные issue для уязвимостей.
- Не защищает от вредоносного LLM-клиента. Если клиент намеренно вызывает наши API с целью что-то сломать, мы не можем это полностью предотвратить — только сделать так, чтобы повреждения были локализованы в
.safeflow/. - Не сканирует ваш код на уязвимости. SafeFlo — это инструмент координации, а не аудитор безопасности. В отличие от ruflo, мы НЕ заявляем поддельные "enterprise security scan" функции.
- Не выполняет deployment-операций. SafeFlo не предоставляет команд для деплоя, публикации или модификации внешних систем.
Этот раздел документирует архитектурные решения, явно противоположные тем, что были замечены в проблемных проектах вроде ruflo.
| Аспект | Проблемные проекты | SafeFlo |
|---|---|---|
| Установка | curl ... | bash из CDN |
git clone + npm install с pinned версиями |
| Install-скрипты | preinstall, postinstall (иногда обфусцированные) |
Их нет |
| Хранение данных | ~/.claude, ~/.npm, фоновые директории |
Только ./.safeflow/ в проекте |
| Модификация Claude Code config | Правит ~/.claude/CLAUDE.md |
Только локальный ./.claude/commands/ |
| Сетевые вызовы | К goal.ruv.io, telemetry |
Их нет |
| MCP descriptions | Содержали скрытые инструкции | Только функциональные |
| Удаление | Невозможно без следов | safeflow uninstall --yes чистит всё |
| Открытые CVE | Накапливаются месяцами | Тестируем регрессии, принимаем community-PR |
| "Enterprise" функции | Заглушки с фейковыми числами | Только то, что реально работает |
| Сложность | 87+ MCP tools, 60+ agent types | 15 MCP tools, 1 концепция логического агента |