OPENCLAW MACOS
STALE_
LAUNCHAGENT_
TOKEN.

macOS launchd и токен OpenClaw Gateway

В ветке 2026.4.x снова и снова: вы выдали новый Gateway-токен через doctor или панель, обновили export в zsh, возможно docker-compose — а Telegram, корпоративные мосты, Web UI и клиенты интеграций одновременно отвечают 401 unauthorized. Локально openclaw gateway status может кратко быть «зелёным», потому что проба короче реального канального запроса. Фактически macOS LaunchAgent подставляет OPENCLAW_GATEWAY_TOKEN из plist (EnvironmentVariables), и это значение не следует за вашей интерактивной сессией. Без --force команда openclaw gateway install иногда пишет «уже установлено» и не трогает plist. Ниже — таблица симптомов, сравнение трёх источников истины, безопасный bootout/правка/bootstrap, принудительная переустановка, десять SSH-пунктов для удалённого Mac и жёсткие ворота. См. также breaking и auth v2, Docker/WS-токен, миграция и launchd, тихий Gateway, systemd/launchd.

1. Почему глобальные 401 соседствуют с «живым» процессом

Транспорт может быть здоров, а аутентификация — нет: шлюз слушает порт, но отвергает заголовки со старым секретом. Плагины каналов показывают ошибку сразу; лёгкие пробы — не всегда. launchd наследует plist, не ваш последний терминал. Если контрольная плоскость отозвала старый токен, все брокерные пути падают до выравнивания. Идемпотентный install — фича, но не замена ротации, пока вы не включили перезапись (--force по справке CLI).

2. Матрица симптом → доказательство

НаблюдениеГипотезаДоказательство
Все каналы 401 в одну минутушлюз держит отозванный токенвремя + тело ответа
падает только launchd, foreground окустаревший plistplutil -p ~/Library/LaunchAgents/*openclaw*.plist
install «успех», эффекта нетplist не изменилсяmtime/хэш до/после
только удалённый Macнесовпадение пользователя или домена launchdlaunchctl print gui/$(id -u)

3. Как LaunchAgent усугубляет ошибку

plist — декларативная конфигурация: строка токена переживает перезагрузки, пока вы явно не сделаете bootout, правку и повторную загрузку. Относитесь к ротации как к мини-релизу: секрет в хранилище → все материализации (plist, compose) → перезапуск шлюза → дымовой тест реальным сообщением канала, а не только curl на localhost.

4. Семь шагов

Шаг 01 — заморозка

Версии CLI, label LaunchAgent, время ротации; избегайте параллельных несогласованных рестартов.

Шаг 02 — найти plist

Обычно ~/Library/LaunchAgents/; отдельный unix-пользователь ⇒ его $HOME.

ls ~/Library/LaunchAgents/*openclaw* 2>/dev/null launchctl list | grep -i openclaw

Шаг 03 — три источника

plist, интерактивная оболочка (форензика), отпечаток в vault — без сырого секрета в чате.

Шаг 04 — bootout → правка → bootstrap

домен и label по официальной документации.

Шаг 05 — force

openclaw gateway install --force, если помогает справка; критерий — изменились метаданные plist.

Шаг 06 — слойная проверка

логи ok → реальный round-trip канала → UI; искать вторую plist или дубль в Docker.

Шаг 07 — гигиена

отозвать старый токен, зашифровать бэкапы, по возможности связка ключей или файл 0600.

5. Удалённый Mac: десять пунктов SSH

тот же пользователь Unix, $HOME, launchctl print, путь ProgramArguments, старые пути workspace после миграции, минимальный firewall, нужен ли вход Aqua, права на логи, приоритет Docker vs launchd (Docker runbook), в тикет — только замаскированные логи.

Ворота

A: в течение 10 минут после ротации mtime plist меняется или задокументирован force-install. B: хотя бы одна не-пробная бизнес-транзакция успешна. C: старый токен помечен revoked в хранилище.

6. Заблуждения

Менять только .env, когда владелец — launchd, недостаточно. Зелёный текст install без plist — не выравнивание. localhost curl не доказывает Telegram webhooks.

7. Граница апгрейда и миграции

Breaking-движки меняют идентичность устройства и аттестацию. Doctor без plist даёт «наполовину зелёное» состояние. Сведите к одному каналу выдачи секретов с runbook миграции.

8. Таймлайн инцидента (первые 30 минут)

T+0–2: запрет параллельных install, зафиксировать label и build. T+3–8: сопоставить тело 401 и строку auth шлюза; клиент шумит, шлюз молчит → другой proxy/порт. T+9–15: plist, опционально Compose, vault — два источника правды = дрейф. T+16–25: bootout → патч или force → bootstrap; один порядок переключения на весь кейс. T+26–30: без ворот A–C нет «зелёного». «Тихий» Mac в стойке не получит по плечу — письменный runbook задаёт MTTR.

9. Двойные шлюзы, порты, reverse-proxy

Отладка в foreground и launchd на разных loopback, свежий TLS, но proxy_pass на запасной хост, Docker добавляет третий слой env — всё выглядит как «токен верный, 401 остаётся». Снимайте build на loopback и публичном имени; хэши должны совпасть. Один супервизор (только launchd или только compose) либо dual-write в каждом RFC.

10. Треугольник plist ↔ launchctl ↔ процесс

СлойЗдоровьеПоломка
Файлmtime двигается, plutil окбитый XML, права
launchctlпуть как в whichмертвый префикс nvm
env процессаотпечаток = vaultстарт без ключа
логи401 = authтолько CPU — сначала jsonl/bootstrap

Привычку copy-paste EnvironmentFile с systemd оставьте на Linux; macOS LaunchAgent любит литералы. Без треугольника удалённые команды теряются.

11. FAQ: оставшиеся ветки 401

В: plist правили, всё равно 401. О: фактический путь из launchctl print, не iCloud-двойник. В: сначала revoke? О: опасно — фиксируйте порядок. В: doctor зелёный, мессенджер нет. О: нужна живая петля сообщения. В: мультипользовательский mini? О: разные Unix → разные LaunchAgents.

12. Итог

Универсальные 401 после работы с токеном на macOS почти всегда — рассинхрон источников истины. Для постоянно включённого Apple Silicon смотрите цены MACGPU и Telegram (ключевое слово MACGPU). Ориентир — официальная справка CLI вашей версии.