Перейти к содержимому

Безопасность и удалённый доступ

M.A.V.E.N - это local-first (локальная прежде всего) плоскость управления (control plane). Она слушает 127.0.0.1:3000, запускает AI-агентов, которые выполняют команды, читает и пишет ваши файлы и тратит деньги у платных провайдеров. Эта страница объясняет, как она защищена, что такое PIN и что делать, когда нужен доступ с другого устройства.

Пользуетесь M.A.V.E.N только на этой машине? Вам ничего делать не нужно. На 127.0.0.1 / localhost PIN не спрашивается - ни до, ни после любого обновления. Читайте дальше, только если хотите открывать M.A.V.E.N с другого устройства.

Откуда открываете M.A.V.E.N Что происходит
На той же машине - http://127.0.0.1:3000 или http://localhost:3000 Без PIN.
Откуда угодно ещё - имя Tailscale, адрес в LAN, hostname обратного прокси Нужен PIN. Первый правильный PIN с хоста автоматически добавляет его в Разрешённые хосты.

M.A.V.E.N сгенерировал PIN при самом первом запуске. Он был напечатан в консоль один раз и хранится в ~/.maven/access-pin (читает только ваш пользователь). Посмотреть его можно в любой момент: Settings → Security → Показать.

В установке ничего не меняется. После первого npm start (или службы автозапуска) вы один раз увидите в консоли / journalctl --user -u maven:

MAVEN access PIN for remote hosts (Tailscale / LAN): K7Q4-M2X9
Kept in /home/you/.maven/access-pin. Loopback needs no PIN.

Открываете http://127.0.0.1:3000 и работаете. Здесь PIN не спросят.

Доступ к M.A.V.E.N с другого устройства (телефон, ноутбук)

Заголовок раздела «Доступ к M.A.V.E.N с другого устройства (телефон, ноутбук)»
  1. (Необязательно) Разрешите имя хоста. Settings → Security → Разрешённые хосты - добавьте имя, которое будете набирать на другом устройстве, например rog.tail1234.ts.net. Это можно пропустить: хост, которого M.A.V.E.N ещё не знает, получает экран разблокировки, и правильный PIN сам добавляет его в список. Список нужен, чтобы просматривать и убирать хосты.
  2. Откройте порт приватно. Tailscale: tailscale serve --bg 3000. Или SSH-туннель: ssh -L 3000:127.0.0.1:3000 you@machine (туннель приходит как localhost, поэтому ему не нужны ни список разрешённых, ни PIN).
  3. Откройте там - http://rog.tail1234.ts.net:3000. Вы увидите экран Enter access PIN. Введите PIN из Settings → Security → Показать (или cat ~/.maven/access-pin). Сессия живёт 30 дней.

Никогда не выставляйте порт 3000 в публичный интернет - ни с PIN, ни без. Только Tailscale или туннель. Пошаговое руководство со скриншотами - Доступ к M.A.V.E.N с телефона.

  • Сгенерированный PIN для удалённых хостов (по умолчанию) - loopback открыт, любой другой хост спрашивает сгенерированный PIN. Показать, Копировать, Перегенерировать (перегенерация разлогинивает все удалённые сессии).
  • Свой PIN, везде - ваш PIN (8+ символов), нужен и на этой машине. То же, что MAVEN_ACCESS_PIN=<pin> в .env.local. Смена разлогинивает все сессии.
  • Без PIN вообще - MAVEN_ACCESS_PIN=off. Остаются только проверки host/origin. Не рекомендуется, если разрешён хоть один хост кроме loopback.
  • Разрешённые хосты - список MAVEN_ALLOWED_ORIGINS: host[:port] или полный origin, через запятую.
  • Дневной потолок трат - MAVEN_DAILY_SPEND_USD (по умолчанию 25). Каждый платный движок (картинки, видео, голос, 3D, апскейлы) выше потолка отказывает до местной полуночи с HTTP 402. 0 = без потолка. Карточка показывает, сколько потрачено сегодня.

Строка статуса вверху карточки говорит, закрыта ли PIN-ом эта страница - ответ зависит от того, как вы её открыли. Сама карточка описана на странице Settings → Security.

  • На loopback PIN не нужен, потому что там он ничего не защищал бы: любой процесс на машине и так работает от вашего имени и может прочитать файл с PIN. Атаки, которые важны на loopback, приходят из браузера - вредоносная страница с другого сайта, обращающаяся к 127.0.0.1:3000, или трюки с DNS-rebinding, - и их останавливает то, что M.A.V.E.N отказывает любому Host, за который не отвечает, и любому cross-site запросу. Поэтому же продолжают работать локальные интеграции (боты Hermes, тулы OpenMontage, апдейтер, smoke-тесты): они ходят в API с машины, без PIN.
  • Удалённым хостам PIN нужен всегда, потому что именно там неаутентифицированный shell был бы проблемой - а агенты M.A.V.E.N это и есть shell.
  • Разрешённые хосты нужны, чтобы rebinding-страница не могла стать «страницей M.A.V.E.N», просто направив свой домен на ваш loopback-адрес. Хост не из списка видит только экран разблокировки (и 401 на API), пока не введён PIN - а страница атакующего ввести его не может. При выключенном гейте PIN-а, которым можно что-то доказать, нет, поэтому незнакомые хосты получают 421 Misdirected Request.

Что ещё работает само (ничего делать не надо)

Заголовок раздела «Что ещё работает само (ничего делать не надо)»
  • Сессии подписаны per-install секретом (~/.maven/session-secret), истекают на сервере и отзываются при смене PIN. Форма разблокировки - с rate-limit.
  • HTML, SVG и приложения, которые генерируют AI-модели, отдаются в браузерной песочнице: они рендерятся и работают, но не могут вызывать API M.A.V.E.N и читать его cookie.
  • Агенты, которых запускает M.A.V.E.N, получают только нужные им переменные окружения, а не все API-ключи из .env.local. Режим разрешений, с которым работает агент, решает M.A.V.E.N по приложению, а не запрос.
  • Секреты хранятся 0600; панель Settings показывает только замаскированные значения; URL провайдеров нельзя менять из UI (перенаправление утащило бы ключ).
  • Платные роуты - под rate-limit и проходят через потолок трат; дорогие операции спрашивают выданное сервером подтверждение.
  • Самообновление применяет ровно тот коммит, который объявило, ставит зависимости через npm ci --ignore-scripts и никогда не регенерирует lockfile без вашей явной команды.
  • Серверные загрузки вставленных вами URL (R-Forge, N-Forge, D-Forge) отказывают приватным и loopback-адресам. Задайте MAVEN_ALLOW_PRIVATE_FETCH=1, если вы намеренно ингестите сайт в LAN.
  • Навыки сообщества проходят обязательный гейт «карантин → статический скан → песочница» перед установкой. См. Навыки.
Terminal window
# .env.example - Remote-access gate
MAVEN_ACCESS_PIN= # unset = generated PIN for remote hosts; <pin> = yours, everywhere; off = no gate
MAVEN_ALLOWED_ORIGINS= # host[:port] or origin, comma-separated - everything MAVEN answers for besides loopback
MAVEN_DAILY_SPEND_USD=25 # daily ceiling across paid engines; 0 = none
MAVEN_ALLOW_PRIVATE_FETCH= # 1 = let R-Forge/N-Forge fetch LAN / loopback URLs
MAVEN_CHAT_PERMISSION_MODE= # bypass = let the /chat agents run without permission prompts (autonomous apps are unaffected)
MAVEN_SESSION_SECRET= # optional override for ~/.maven/session-secret (32+ chars)

Файлы: ~/.maven/access-pin (сгенерированный PIN), ~/.maven/session-secret (ключ подписи сессий). Оба 0600. Удалите access-pin и перезапустите - получите новый; или используйте Перегенерировать.

  • 421 Misdirected Request - гейт выключен (MAVEN_ACCESS_PIN=off), а набранного имени хоста нет в Разрешённых хостах. Добавьте его или включите гейт обратно, чтобы PIN мог вас впустить.
  • 403 refused: this request came from … - страница с другого сайта (или другого локального порта) попыталась вызвать MAVEN. Можно только собственным страницам MAVEN.
  • Заперло на самой машине - вы задали свой PIN и забыли его: откройте .env.local, уберите MAVEN_ACCESS_PIN, перезапустите. Сгенерированный PIN тогда действует только для удалённых хостов.
  • «Too many tries» - подождите указанные секунды; лимитер растёт экспоненциально и сбрасывается при успехе.
  • 402 «daily spend cap reached» - поднимите потолок в Settings → Security или дождитесь полуночи.
  • Удалённое устройство было разблокировано, а теперь нет - PIN сменили или перегенерировали; введите новый.
  • С удалённого хоста страницы грузятся пустыми в dev-режиме - добавьте хост в allowedDevOrigins в next.config.ts (см. Конфигурация).