OAuth через SSH / удалённые хосты
Некоторые провайдеры VibeOS — xAI Grok OAuth, Spotify и удалённые MCP-серверы (Linear, Sentry, Atlassian, Asana, Figma, …) — используют OAuth-поток с loopback-редиректом. Сервер авторизации перенаправляет ваш браузер на http://127.0.0.1:<port>/callback, чтобы крошечный HTTP-слушатель, запущенный VibeOS, мог получить код авторизации.
Это отлично работает, когда VibeOS и ваш браузер находятся на одной машине. Но перестаёт работать, когда это не так: браузер вашего ноутбука пытается обратиться к 127.0.0.1 на вашем ноутбуке, в то время как слушатель привязан к 127.0.0.1 на удалённом сервере.
Решение — однострочный SSH-туннель с локальной переадресацией портов. Или, если у вас нет обычного SSH-клиента (GCP Cloud Shell, GitHub Codespaces, EC2 Instance Connect, Gitpod, браузерные веб-IDE), используйте новый флаг --manual-paste, появившийся в #26923.
TL;DR
# На вашей локальной машине (ноутбуке), в отдельном терминале:
ssh -N -L 56121:127.0.0.1:56121 user@remote-host
# В вашей существующей SSH-сессии на удалённой машине:
vibeos auth add xai-oauth --no-browser
# → VibeOS выводит URL для авторизации. Откройте его в браузере на ноутбуке.
# → Ваш браузер перенаправляется на 127.0.0.1:56121/callback, туннель
# пересылает запрос удалённому слушателю, авторизация завершается.
Порт 56121 используется xAI OAuth. Для Spotify замените его на 43827. VibeOS выводит точный порт, к которому он привязался, в строке Waiting for callback on ... — скопируйте его оттуда.
Только браузерный удалённый доступ (Cloud Shell / Codespaces / EC2 Instance Connect)
Если у вас нет обычного SSH-клиента — например, вы запускаете VibeOS внутри GCP Cloud Shell, GitHub Codespaces, AWS EC2 Instance Connect, Gitpod или другой браузерной консоли — описанный выше SSH-туннель недоступен. Вместо этого используйте --manual-paste:
vibeos auth add xai-oauth --manual-paste
# → VibeOS выводит URL для авторизации. Откройте его в браузере на ноутбуке.
# → Подтвердите в браузере. Перенаправление на 127.0.0.1:56121/callback
# не загрузится — это ожидаемо.
# → Скопируйте ПОЛНЫЙ URL из адресной строки страницы с ошибкой.
# → Вставьте его обратно в терминал в ответ на приглашение "Callback URL:".
Тот же флаг работает с vibeos model --manual-paste для встроенного выбора модели. VibeOS принимает три формы вставки callback: полный URL, фрагмент ?code=...&state=... или — если страница согласия провайдера отображает код авторизации на самой странице вместо перенаправления (текущее поведение xAI в браузерных консолях) — просто сам код авторизации.
VibeOS использует один и тот же PKCE-верификатор, state и nonce для обоих путей, поэтому исходящий OAuth-поток идентичен на уровне байтов — --manual-paste является чисто транспортным изменением для этапа callback и не является понижением уровня безопасности.
Каким провайдерам это нужно
| Провайдер | Loopback-порт | Нужен туннель? |
|---|---|---|
xai-oauth (Grok SuperGrok) | 56121 | Да, если VibeOS удалён |
| Spotify | 43827 | Да, если VibeOS удалён |
MCP-серверы (auth: oauth) | выбирается автоматически для каждого сервера | Да, если VibeOS удалён |
anthropic (Claude Pro/Max) | н/д | Нет — поток с вставкой кода |
openai-codex (ChatGPT Plus/Pro) | н/д | Нет — поток с кодом устройства |
minimax, nous-portal | н/д | Нет — поток с кодом устройства |
Если вашего провайдера нет в таблице, туннель вам не нужен.
MCP-серверы
Удалённые MCP-серверы (Linear, Sentry, Atlassian, Asana, Figma и т.д.) используют тот же поток с loopback-редиректом. VibeOS автоматически выбирает свободный порт для каждого сервера и выводит URL для авторизации, когда запускается OAuth-поток — либо при запуске (когда новый сервер появляется в mcp_servers:), либо когда вы выполняете vibeos mcp login <server>.
У вас есть два способа завершить его с удалённого хоста:
Вариант 1 — вставьте URL перенаправления обратно (без настройки, работает везде). В интерактивном терминале VibeOS предлагает вставить URL перенаправления, одновременно запуская локальный слушатель. После подтверждения в браузере перенаправление на http://127.0.0.1:<port>/callback покажет ошибку соединения — это ожидаемо. Скопируйте полный URL из адресной строки браузера и вставьте его в приглашение VibeOS:
MCP OAuth: требуется авторизация.
Откройте этот URL в вашем браузере:
https://mcp.linear.app/authorize?response_type=code&...
Или вставьте сюда URL перенаправления (или часть ?code=...&state=...) и нажмите Enter:
> https://mcp.linear.app/callback?code=abc123&state=xyz
Получен код авторизации из вставки — завершение потока.
Также принимается просто строка запроса ?code=...&state=.... Это работает для любого MCP-сервера с auth: oauth и не требует изменений в конфигурации SSH.
Вариант 2 — SSH-туннель (как для xAI / Spotify). VibeOS выводит точный порт, к которому он привязался, в подсказке SSH-сессии. Откройте отдельный терминал на вашем ноутбуке:
ssh -N -L <port>:127.0.0.1:<port> user@remote-host
Затем откройте URL авторизации в браузере как обычно; перенаправление проходит через туннель, и слушатель его обрабатывает. Используйте этот вариант, когда нужно завершить поток без участия пользователя (например, при скриптовой повторной авторизации, когда вы не можете вставить данные в интерактивном режиме).
Подводный камень — 30-секундная гонка перезагрузки конфигурации. Если вы редактируете ~/.vibeos/config.yaml, чтобы добавить OAuth MCP-сервер из запущенной сессии VibeOS, CLI автоматически перезагружает MCP-соединения с таймаутом 30 секунд. Этого времени недостаточно для завершения интерактивного OAuth-потока, и перезагрузка завершится ошибкой. Вместо этого используйте vibeos mcp login <server> из свежего терминала — у него нет такого ограничения, и он ждёт полные 5 минут, пока вы вставите данные.
Почему слушатель не может просто привязаться к 0.0.0.0
xAI и Spotify проверяют параметр redirect_uri по белому списку. Оба требуют loopback-форму (http://127.0.0.1:<точный-порт>/callback). Привязка слушателя к 0.0.0.0 или другому порту приведёт к тому, что сервер авторизации отклонит запрос из-за несовпадения redirect_uri. SSH-туннель сохраняет loopback-URI нетронутым на всём пути.
Пошаговая инструкция: один SSH-переход
1. Запустите туннель с вашей локальной машины
# xAI Grok OAuth (порт 56121)
ssh -N -L 56121:127.0.0.1:56121 user@remote-host
# Или для Spotify (порт 43827)
ssh -N -L 43827:127.0.0.1:43827 user@remote-host
-N означает «не открывать удалённую оболочку, просто держать туннель открытым». Держите этот терминал работающим на время авторизации.
2. В отдельной SSH-сессии выполните команду auth
ssh user@remote-host
vibeos auth add xai-oauth --no-browser
# или для Spotify:
# vibeos auth add spotify --no-browser
VibeOS обнаруживает SSH-сессию, пропускает автоматическое открытие браузера и выводит URL авторизации, а также строку Waiting for callback on http://127.0.0.1:<port>/callback.
3. Откройте URL в вашем локальном браузере
Скопируйте URL авторизации из удалённого терминала и вставьте его в браузер на вашем ноутбуке. Подтвердите на экране согласия. Сервер авторизации перенаправляет на http://127.0.0.1:<port>/callback. Ваш браузер попадает в туннель, запрос пересылается удалённому слушателю, и VibeOS выводит Login successful!.
Вы можете закрыть туннель (Ctrl+C в первом терминале) после появления строки об успехе.
Пошаговая инструкция: через шлюз
Если вы подключаетесь к VibeOS через бастион / шлюз, используйте встроенный -J (ProxyJump) SSH:
ssh -N -L 56121:127.0.0.1:56121 -J jump-user@jump-host user@final-host
Это создаёт цепочку SSH-соединений через шлюз, не размещая loopback-порт на самом шлюзе. Локальный 127.0.0.1:56121 на вашем ноутбуке туннелируется напрямую к 127.0.0.1:56121 на конечном удалённом хосте.
Для старых версий OpenSSH, не поддерживающих -J, длинная форма:
ssh -N \
-o "ProxyCommand=ssh -W %h:%p jump-user@jump-host" \
-L 56121:127.0.0.1:56121 \
user@final-host
Mosh, tmux, ssh ControlMaster
Туннель является свойством базового SSH-соединения. Если вы запускаете VibeOS внутри tmux через mosh-сессию, роуминг mosh не переносит переадресацию -L. Откройте отдельную обычную SSH-сессию только для туннеля -L — это соединение должно оставаться активным во время потока авторизации. Ваша интерактивная mosh/tmux-сессия может продолжать нормально работать с VibeOS.
Если вы используете ssh -o ControlMaster=auto, переадресация портов в мультиплексированном соединении разделяет время жизни мастер-соединения. Перезапустите мастер, если туннель не поднимается:
ssh -O exit user@remote-host
ssh -N -L 56121:127.0.0.1:56121 user@remote-host
Устранение неполадок
bind [127.0.0.1]:56121: Address already in use
Что-то на вашем ноутбуке уже использует этот порт. Возможно, предыдущий туннель не закрылся корректно, или локальный VibeOS также слушает на нём. Найдите и завершите процесс:
# macOS / Linux
lsof -iTCP:56121 -sTCP:LISTEN
kill <PID>
Затем повторите команду ssh -L.
«Не удалось установить соединение. Мы не смогли связаться с вашим приложением.» (xAI)
Страница авторизации xAI показывает это, когда её перенаправление на 127.0.0.1:<port>/callback не достигает слушателя. Либо туннель не запущен, либо порт неверен, либо вы используете порт, который VibeOS вывел в предыдущем запуске (порт может быть автоматически изменён, если предпочтительный занят — всегда читайте последнюю строку Waiting for callback on ...).
xAI authorization timed out waiting for the local callback
Та же основная причина, что и выше — перенаправление никогда не вернулось. Проверьте, жив ли туннель (ssh -N не показывает вывод, поэтому посмотрите на терминал, из которого вы его запустили), перезапустите его при необходимости и повторно выполните vibeos auth add xai-oauth --no-browser.
Токены попадают не в тот ~/.vibeos
Токены записываются под пользователем Linux, который выполнил vibeos auth add .... Если ваш шлюз / systemd-сервис работает от другого пользователя (например, root или выделенный пользователь vibeos), аутентифицируйтесь от этого пользователя, чтобы токены попали в его ~/.vibeos/auth.json. Используйте sudo -u vibeos -i или эквивалент.