Для AI-агентов: markdown этой страницы — /docs-content/infra/server-access-recovery.md индекс документации — /llms.txt

Восстановление доступа к серверу

Сервер остаётся привязан к текущему управляющему ключу, поэтому после истечения или отзыва этого ключа другой ключ сервер не видит. Доступ возвращается сменой управляющего ключа в личном кабинете, сервер при этом не пересоздаётся.

Как выглядит потеря доступа

Потеря доступа проявляется так:

  • GET /v1/infra/servers возвращает успех и пустой массив data, хотя серверы на портале есть.
  • GET /v1/infra/servers/:id по известному идентификатору возвращает 404 NOT_FOUND.
  • GET /v1/me при этом подтверждает, что новый ключ действует: accessMode равен READWRITE, скоуп vibe:infra присутствует.
  • В личном кабинете сервер виден в разделе «Серверы Black Hole» и продолжает работать.

Список серверов с ключом, который ими не управляет:

JSON
{
  "success": true,
  "data": []
}

Обращение к конкретному серверу тем же ключом:

JSON
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Server not found"
  }
}

Надёжная проверка — сравнить личный кабинет и API: сервер виден в разделе «Серверы Black Hole», но не приходит в GET /v1/infra/servers. Кабинет показывает серверы по владельцу, поэтому он и есть источник правды о том, что сервер существует.

Счётчики в GET /v1/me дают дополнительную подсказку, но не доказательство. Поле infra.limits.used считает отдельные виртуальные машины (STANDALONE) текущего ключа, а infra.limits.breakdown — серверы владельца по всем его ключам на портале. Нулевой used при ненулевом breakdown.total сам по себе не говорит, что текущий ключ не управляет ничем: used не считает галактики и Galaxy-приложения даже тогда, когда управляет ими именно он. Это повод сверить с кабинетом, не более:

JSON
{
  "success": true,
  "data": {
    "infra": {
      "limits": {
        "max": 3,
        "used": 0,
        "breakdown": {
          "direct": 7,
          "agents": 0,
          "bots": 0,
          "total": 7
        }
      }
    }
  }
}

У подсказки есть и другие границы. Сервер, полностью потерявший ключ, в breakdown не попадает — там оба счётчика останутся нулевыми, хотя сервер работает и виден в кабинете. И наоборот, breakdown считает в том числе виртуальные машины агентов и ботов: они тоже дают used: 0 при ненулевом total, но управляют ими в их разделах личного кабинета, а не через /v1 — см. AI-агенты. Про галактики подробнее — Galaxy-приложение. Поэтому счётчики подсказывают, куда смотреть, а решает сравнение с кабинетом.

Почему сервер не виден

У сервера две разные привязки. Владение закреплено за пользователем и не меняется при действиях с ключами. Поле apiKeyId означает другое — какой ключ управляет сервером сейчас.

Эндпоинты /v1/infra/* авторизуют доступ по управляющему ключу: запрос видит только те серверы, у которых apiKeyId совпадает с вызывающим ключом. Личный кабинет опирается на владение, поэтому там сервер остаётся виден. Отсюда и расхождение: в кабинете сервер есть, через API с новым ключом его нет.

Данные сервера при истечении ключа не затрагиваются. Виртуальная машина, развёрнутое приложение, настройки и субдомен продолжают работать — недоступно только управление через API.

Как вернуть доступ

Смена управляющего ключа выполняется в личном кабинете владельцем сервера:

  1. Откройте раздел Серверы Black Hole.
  2. Найдите нужный сервер в списке.
  3. В меню карточки сервера выберите Сменить управляющий ключ.
  4. Выберите в списке новый ключ и подтвердите.

Если у сервера нет управляющего ключа, на его карточке появляется кнопка Восстановить доступ, которая открывает тот же выбор. Когда карточка показывает Владение потеряно, сначала нажмите Вернуть себе — это вернёт сервер во владение, после чего появится выбор ключа. Бесхозные серверы видит и возвращает себе только администратор портала: остальным POST /api/servers/:id/adopt отвечает 403 ADMIN_ONLY, и карточка им не показывается.

Смена затрагивает только управляющую привязку. Виртуальная машина, данные, настройки и субдомен остаются нетронутыми, перезапуск не выполняется. После подтверждения новый ключ сразу видит сервер в GET /v1/infra/servers — при условии, что срок его действия не закончился. Набор доступных операций зависит от типа ресурса: отдельной виртуальной машине (STANDALONE) доступны и жизненный цикл, и развёртывание, а Galaxy-приложению (GALAXY_APP) — развёртывание и удаление, потому что своей виртуальной машины у него нет и будить или перезагружать нечего. Владелец сервера получает сообщение от бота-помощника о том, что управляющий ключ сменён.

Требования к новому ключу

В списке выбора показываются только подходящие ключи. Ключ подходит, когда выполнены все условия:

Условие Значение
Тип API-ключ (vibe_api_). Ключ авторизации (vibe_app_) в качестве управляющего не принимается
Назначение Ключ общего назначения. Выпущенные платформой временные ключи обслуживания и ключи Cowork не принимаются
Владелец Тот же пользователь, которому принадлежит сервер
Портал Тот же портал Битрикс24, что и у сервера
Состояние Отозванный и заблокированный ключи в списке не показываются
Скоуп vibe:infra
Не текущий Ключ, который уже управляет этим сервером, в списке не показывается

Выбирайте ключ, срок действия которого не закончился. Ключ с истёкшим сроком остаётся в списке, и перепривязка на него проходит — но запросы с ним отклоняются с кодом 401 KEY_EXPIRED, и доступ к серверу придётся восстанавливать заново. Срок действия каждого ключа виден в разделе Ключи API.

Если подходящих ключей нет, создайте новый в разделе Ключи API со скоупом vibe:infra — форма позволяет сделать это, не покидая диалог смены ключа.

Когда это нужно

Ситуации приводят к одному видимому итогу — сервер работает, а новый ключ его не видит. Но состояний за этим три, и порядок действий у них разный.

Управляющий ключ на месте, но не работает. Привязка сервера цела, нерабочим стал сам ключ:

  1. Секрет ключа потерян. Ключ действует, но его значение не сохранили при создании. Значение ключа показывается один раз, восстановить его нельзя.
  2. Ключ отозван. Ключ переведён в состояние REVOKED — владельцем, например после компрометации, или платформой при отключении самостоятельно размещённого портала: отключение отзывает ключи пользователя, привязку сервера оно не трогает.
  3. Ключ истёк. Срок действия закончился, запросы отклоняются с кодом 401 KEY_EXPIRED.

Во всех трёх случаях порядок обычный — смена управляющего ключа на новый.

Сервер остался без управляющего ключа. Поле apiKeyId пусто, владелец сохранён. Карточка показывает кнопку Восстановить доступ, которая открывает тот же выбор ключа. Удалить ключ с работающими серверами вручную нельзя — это запрещает проверка при удалении.

Сервер остался и без владельца. Оба поля пусты. Так бывает после удаления учётной записи владельца: его ключи удаляются вместе с ней, и userId с apiKeyId обнуляются одновременно. Карточка показывает Владение потеряно — сначала нажмите Вернуть себе, и только после этого появится выбор ключа. Такие серверы видит только администратор портала.

Возврат владения работает для отдельных виртуальных машин (STANDALONE). Galaxy-приложение, оставшееся без владельца, вернуть себе нельзя — платформа помечает его удалённым. Пока владелец у приложения сохранён, управляющий ключ ему меняется обычным порядком.

Ошибки

HTTP Код Когда возвращается
401 KEY_EXPIRED Срок действия ключа закончился
401 KEY_INACTIVE Ключ отозван или заблокирован
404 NOT_FOUND Обращение к серверу ключом, который им не управляет
403 WRONG_KEY Развёртывание на сервер ключом, который им не управляет
409 KEY_HAS_ACTIVE_SERVERS Удаление ключа, на котором есть активные серверы
409 KEY_HAS_LINKED_AGENT Удаление ключа, которым управляется агент или бот
409 APP_HAS_ACTIVE_SERVERS Удаление приложения, на ключе которого есть активные серверы
409 CONCURRENT_REBIND Одновременная смена на разные ключи — сервер уже привязан к другому ключу

Полный справочник кодов — Коды ошибок.

Известные особенности

Удаление ключа с активными серверами не проходит. Запрос возвращает 409 KEY_HAS_ACTIVE_SERVERS. Смените у этих серверов управляющий ключ — удалять сами серверы для этого не нужно. Полное число серверов приходит в поле details.activeServerCount при удалении из кабинета и в error.details.activeServerCount у DELETE /v1/keys/:id. Список лежит рядом со счётчиком — соответственно в details.servers и error.details.servers. В списке не больше 10 серверов, самые новые — при значении счётчика больше десяти опирайтесь на него, а остальные серверы смотрите в кабинете. Если на ключе есть ещё и агент или бот, следующая попытка вернёт 409 KEY_HAS_LINKED_AGENT — перепривязка серверов эту проверку не снимает.

Смена ключа выполняется только в личном кабинете. У операции нет варианта в /v1: перепривязка работающего сервера — решение человека, а не автоматизированного клиента. Ключ vibe_api_ этот вызов не выполняет.

Развёртывание чужим ключом возвращает 403 WRONG_KEY. Ответ приходит, когда сервер существует, но управляется другим ключом. В поле hint приходит разбор ситуации и указание на смену управляющего ключа как способ восстановления.

Сервер, созданный приложением, после смены ключа приложению больше не доступен. Если сервер создан ключом авторизации, сменить управление можно только на личный API-ключ владельца — принять привязку другой ключ авторизации не может. После этого GET /v1/infra/servers/:id со старым ключом возвращает 404 NOT_FOUND, а POST /v1/infra/servers/:id/deploy403 WRONG_KEY. Управлять сервером через /v1 можно только новым личным ключом.

Порядок относится к серверам и Galaxy-приложениям. В разделе «Black Hole серверы» показываются отдельные виртуальные машины (STANDALONE) и Galaxy-приложения (GALAXY_APP). Галактика-хост (GALAXY) живёт в разделе «Галактики», и смены управляющего ключа там нет — в GET /v1/infra/servers она возвращается наравне с остальными, поэтому по пустому ответу нового ключа отличить её нельзя.

Одновременная смена ключа с двух устройств разрешается по целевому ключу. Когда оба запроса выбрали один и тот же ключ, второй запрос возвращает 200 — привязка уже такая, какую он запрашивал. Когда запросы выбрали разные ключи, второй возвращает 409 CONCURRENT_REBIND: обновите страницу и посмотрите текущую привязку.

Смотрите также