Безопасность и удалённый доступ
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/localhostPIN не спрашивается - ни до, ни после любого обновления. Читайте дальше, только если хотите открывать 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-M2X9Kept 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 с другого устройства (телефон, ноутбук)»- (Необязательно) Разрешите имя хоста. Settings → Security → Разрешённые хосты - добавьте
имя, которое будете набирать на другом устройстве, например
rog.tail1234.ts.net. Это можно пропустить: хост, которого M.A.V.E.N ещё не знает, получает экран разблокировки, и правильный PIN сам добавляет его в список. Список нужен, чтобы просматривать и убирать хосты. - Откройте порт приватно. Tailscale:
tailscale serve --bg 3000. Или SSH-туннель:ssh -L 3000:127.0.0.1:3000 you@machine(туннель приходит какlocalhost, поэтому ему не нужны ни список разрешённых, ни PIN). - Откройте там -
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 с телефона.
Settings → Security
Заголовок раздела «Settings → Security»- Сгенерированный 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. - Навыки сообщества проходят обязательный гейт «карантин → статический скан → песочница» перед установкой. См. Навыки.
Справочник переменных окружения
Заголовок раздела «Справочник переменных окружения»# .env.example - Remote-access gateMAVEN_ACCESS_PIN= # unset = generated PIN for remote hosts; <pin> = yours, everywhere; off = no gateMAVEN_ALLOWED_ORIGINS= # host[:port] or origin, comma-separated - everything MAVEN answers for besides loopbackMAVEN_DAILY_SPEND_USD=25 # daily ceiling across paid engines; 0 = noneMAVEN_ALLOW_PRIVATE_FETCH= # 1 = let R-Forge/N-Forge fetch LAN / loopback URLsMAVEN_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(см. Конфигурация).