Данные и безопасность

Эта страница собирает в одно место ответы, которые обычно приходится выпытывать по частям: что где лежит, кто это видит, что уходит за пределы платформы и сколько всё это хранится. Тарифом из перечисленного зависят две вещи: срок хранения истории запусков (на бесплатном это трое суток) и размер команды (на бесплатном — одно место для приглашённого участника сверх владельца, см. «Команду и роли»); точные значения — в «Лимитах тарифов». Роли, скоупинг данных, секреты и каналы публикации тарифом не ограничены и работают на любом.

Что скоупится по рабочему пространству

Рабочее пространство — граница данных, и она проведена в хранилище, а не в интерфейсе. Запрос всегда несёт идентификатор пространства, поэтому объект соседнего пространства не просто «не показывается» — он не находится.

ДанныеОбластьКто может прочитать
Сценарий, версии, запуски, логипространстволюбой участник
Файлы и хранилищепространстволюбой участник
Коллекции базы данныхпространстволюбой участник
Базы знаний и их векторапространстволюбой участник
История чатовпространстволюбой участник
Память агентов и переменныепространствосценарий этого пространства
Секретыпространствоимена — редактор и выше; значения — никто
Интеграциипространствоучастники видят настройки, секретные поля скрыты
Баланс кварков, тариф, профильаккаунт владельцавладелец аккаунта

Отсюда практическое следствие: переносить данные между пространствами платформа не умеет. Разложить клиентов по отдельным пространствам стоит сразу, а не «когда вырастем».

Внутри одного пространства ролей три, и они решают, кто читает, а кто меняет; разбор — в «Команде и ролях». Одно важно повторить здесь: наблюдатель читает все данные — историю чатов, файлы, содержимое коллекций. Роль ограничивает изменения, а не любопытство.

Секреты

Секрет — это пара «имя → значение» рабочего пространства: Настройки → Секреты. Ссылаются на него в любом шаблоне как {{ secret.ИМЯ }}, поэтому имя должно быть допустимым идентификатором — как переменная окружения: OPENAI_API_KEY, CRM_TOKEN.

Как это устроено:

  • Хранится зашифрованным. Значение лежит в базе в виде шифротекста; ключ шифрования выводится из мастер-ключа установки и не совпадает с ключом подписи токенов входа.
  • Значение не возвращается наружу никогда. API отдаёт только имя и признак «значение задано». Ни администратор, ни владелец, ни поддержка не могут посмотреть сохранённый секрет — его можно только перезаписать. При правке пустое поле значения означает «оставить прежнее».
  • Расшифровывается один раз на запуск. Первое обращение {{ secret.* }} внутри рана загружает и расшифровывает весь набор в память процесса на время этого запуска; на диск расшифрованное не попадает.
  • Меняет секреты администратор пространства, а видеть их имена (нужные для автодополнения в редакторе) может редактор. Наблюдателю не видно и имён: список имён — это карта ваших интеграций.
  • Удаление секрета не ломает граф на месте. Ссылка на удалённый секрет разворачивается в пустую строку, и сценарий продолжает работать — с пустым ключом в заголовке. Отказ придёт от внешнего сервиса и будет выглядеть как «неверный ключ», а не как «секрета нет». Это и есть причина, по которой удалять секреты стоит осознанно.

Ключи интеграций (пароль IMAP, токен CRM, ключ провайдера моделей) устроены так же: шифруются, не возвращаются, при правке пустое поле значит «не менять».

Секреты не попадают в логи и в тексты ошибок. Снимки входов и выходов ноды заменяют поля с учётными данными на имя интеграции, а текст ошибки прогоняется через санитайзер, который вырезает значения секретов этого запуска, Bearer …, ключи вида sk-… и пароли внутри URL. Смысл: словоохотливый чужой сервер часто цитирует присланный ему ключ обратно в тексте ошибки, и без вычистки этот текст стал бы витриной для ключа.

Что уходит наружу

Любой исходящий HTTP-запрос платформы — из ноды HTTP, из интеграции, из вызова модели — идёт через один защищённый клиент с политикой адресов. Политика проверяется на каждом соединении и на каждом редиректе, а не один раз по строке URL: адрес, который после редиректа указывает в приватную сеть, отбивается там же. Диапазоны loopback, RFC1918 и link-local закрыты, у запроса есть предельный таймаут и потолок на размер ответа.

Пользовательский JavaScript (нода JavaScript-код) исполняется не в процессе платформы, а в отдельной песочнице: у него нет доступа к базе, к секретам и к файловому хранилищу, файловая система только для чтения, сеть ограничена, а параллельность и время работы — квотированы. Подробности — в «Своём коде».

Обезличивание запроса к модели

Текст разговора можно отправлять модели с заменой распознанных персональных данных на метки: телефон, почта, ИНН, СНИЛС, ОГРН, номер карты, IBAN, адрес и ФИО заменяются на <PHONE_RU_a1b2c3> и подобные, а в ответе модели оригиналы возвращаются на место — включая аргументы вызванных инструментов, так что в вашу CRM уедет настоящий номер, а не метка. Соответствие между меткой и оригиналом восстанавливается на нашей стороне и поставщику модели не передаётся.

Где включается: Настройки → Обезличивание для всего пространства, и отдельным полем на ноде, если у конкретного шага должно быть иначе. По умолчанию решает канал: обезличивание включено там, где собеседник посторонний — публичный чат, виджет, Telegram, ВКонтакте, — и выключено во внутренних запусках из редактора, по расписанию, по вебхуку и через API.

Что это не покрывает — это важнее, чем что покрывает:

  • вложения: фотографии, сканы документов и голосовые сообщения проходят мимо, потому что распознавание текстовое;
  • загрузку документов в базу знаний — текст файла уходит поставщику эмбеддингов как есть;
  • веб-поиск, промпты медиа-нод и вызовы HTTP-нод — это отдельные исходящие пути.

Полнота распознавания не гарантируется: часть данных в свободном тексте остаётся. Поэтому в интерфейсе и здесь написано «обезличиваем распознанные», а не «удаляем персональные данные» — второе было бы обещанием, которого механизм не даёт.

У нас хранятся оригиналы. История чатов, логи и разбор запуска не редактируются: иначе разбор перестал бы отвечать на вопрос «что на самом деле сказал клиент». Обезличивание — это про исходящий запрос, а не про хранение.

Если распознаватель недоступен, а обезличивание включено, запуск падает с внятной ошибкой и запрос не уходит — тихой деградации здесь нет.

Экран говорит, что действует сейчас. Сначала распознаватель работает в режиме замера: читает реальный трафик, записывает, что находит и во сколько это обходится по задержке, и ничего в отправляемом не меняет. Всё написанное выше описывает следующую фазу — когда замена включится. «Настройки → Обезличивание» называет действующую фазу, включая ту, в которой ваш выбор сохраняется и начнёт работать в день включения.

Ключи каналов — это право запускать за ваш счёт

Публичная ссылка чата, токен виджета и ключ вебхука — не «доступ к API». Каждый из них даёт ровно одно: запускать один опубликованный сценарий, а кварки за этот запуск списываются с баланса владельца пространства. Отсюда практика: ссылку на чат раздают клиентам, а ключ вебхука — нет, потому что первый защищён от абьюза лимитами канала, а второй пускает машину.

КлючЧто даётКак выдаётсяКак обесценить
Ссылка публичного чата и виджетаговорить с одним сценариемавтоматически при первой публикациивыключить канал и опубликовать заново
Ключ вебхуказапускать сценарий по HTTPавтоматически при публикации в вебхуквыключить канал и опубликовать заново
Секрет подписи виджетаподписывать end-user JWTкнопкой в настройкахкнопка обновления
Ключ Assistant MCPуправлять платформой по MCPкнопкой в настройкахсмена или отключение

Разбор всех дверей и того, чего среди них нет, — в «Доступе по API».

Файлы и подписанные ссылки

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

Сколько всё это живёт

  • История запусков чистится по тарифу: от трёх суток на бесплатном до 90 на «Бизнесе»; точные значения — в таблице лимитов, она формируется из конфигурации. Чистка «мягкая» — удаляются логи и по-нодовые записи, тяжёлые входы-выходы обнуляются, а сама строка запуска со статусом и временем остаётся, поэтому статистика не рвётся. Открытый старый запуск честно скажет, что подробности вычищены.
  • История чатов автоматически не удаляется. Её чистит человек — кнопками очистки в чате (роль редактора). Учитывайте это, если по договору с клиентом переписку хранить нельзя.
  • Записанная история Telegram-групп выключена по умолчанию, включается на конкретном сценарий и имеет собственные тарифные сроки и потолок числа сообщений.
  • Файлы, коллекции, базы знаний и память не имеют срока — живут, пока их не удалят, и считаются в квотах хранения владельца («Лимиты тарифа»).

Архивация пространства ничего из этого не удаляет: данные остаются, освобождается только слот в квоте пространств.

Вход в аккаунт

Пароль хранится в виде хеша. Вход держится, пока вы работаете, и заканчивается после недели без единого действия — тогда платформа попросит пароль снова. Смена пароля завершает вход на всех устройствах сразу. Попытки входа и регистрации ограничены по частоте. Вход, смена ролей и правка секретов пишутся в журнал безопасности с временем, автором и IP — журнал сегодня доступен только глобальному администратору установки.

Если пароль забыт

На экране входа есть ссылка «Забыли пароль?». Она спрашивает адрес и отправляет на него одноразовую ссылку: та живёт один час и срабатывает один раз. По ней вы задаёте новый пароль и сразу оказываетесь внутри.

Подтверждение, которое показывает форма, одинаково для адреса с аккаунтом и без него — и это сделано намеренно: различающийся ответ позволил бы любому со списком корпоративных адресов выяснять по одной отправке, кто у вас работает. Поэтому не пришедшее письмо означает одно из трёх: опечатка в адресе, на этом адресе нет аккаунта, письмо попало в спам.

Два следствия, о которых лучше знать заранее:

  • Смена пароля завершает все остальные сессии. Вкладка, в которой вы его меняли, продолжает работать; телефон, второй браузер и одолженный ноутбук коллеги попросят войти заново. Именно это делает сброс полезным после утечки, а не просто аккуратным.
  • Токен едет во фрагменте ссылки (часть после #), который браузер никогда не отправляет на сервер. Он не попадает ни в наши логи доступа, ни в заголовок Referer, ни в прокси по дороге. Зато почтовый клиент, перенёсший ссылку на вторую строку, её ломает — если страница говорит, что ссылка неполная, скопируйте её целиком.

Тот же пароль можно сменить и изнутри приложения — Настройки → Аккаунт, там понадобится текущий. Задать пароль за пользователя администратор установки по-прежнему не может: такой ручки нет, а восстановление идёт через адрес почты, указанный в аккаунте.