Гости, подрядчики и члены семьи
Актуально для: SimpleTwo 0.9.x · Проверено: 08.09.2026
В платформе не один «пользователь с галочками», а несколько классов доступа, и класс решает сразу две вещи: что человек видит в переписке и куда его пускают в сети. Разделение сделано так, чтобы приглашение в разговор нигде не превращалось в доступ к системам.
| Класс | Как появляется | Профиль в сети | Каталог |
|---|---|---|---|
employee | из корпоративного каталога при первом входе (OIDC/ADFS) | набор правил rs-corp, группы шлюзов corp-egress и geo-pool | по политике роли |
guest | приглашает сотрудник с правом guests:invite | набор правил rs-guest, только geo-pool | ограничен политикой роли |
partner | заводит администратор | тот же rs-guest, только geo-pool, но роль отдельная | ограничен политикой роли |
| бот | администратор в консоли | не применимо | по списку возможностей |
partner — отдельная роль, а не «гость с правами»Расширять права нужно кому-то одному, а не всем сразу. Пока это разные роли, изменение политики подрядчиков не задевает гостей — и наоборот. Наборы правил у них сегодня совпадают, и это осознанное совпадение по умолчанию, а не одна сущность под двумя именами.
1. Кто может приглашать
Приглашение — это право роли, а не отдельная роль: guests:invite выдаётся той роли,
которой оно нужно (например, employee целиком или отдельной роли «принимающий»).
Проверить, что у сотрудника оно есть, можно его же токеном:
curl -fsS "https://s2.<домен>/v1/me/capabilities" -H "Authorization: Bearer $TOKEN"
В ответе должен быть guests:invite в списке can. Если его нет — приглашение вернёт 403,
и это ответ, а не сбой: право выдаётся в консоли, в свойствах роли.
2. Приглашение
Сотрудник делает это сам из приложения (Контакты → пригласить гостя): появляется карточка с QR-кодом и учётными данными, её можно отправить гостю любым способом. Тот же вызов из командной строки:
curl -fsS -X POST "https://s2.<домен>/v1/guests" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"username":"ivanov-guest","display_name":"Иван Иванов","phone":"+79001234567","ttl_hours":720}'
| Поле | Обязательное | Смысл |
|---|---|---|
username | да | логин гостя; занятый вернёт 409 |
phone | да | канал восстановления доступа, формат E.164, должен быть уникальным |
display_name, email | нет | как гость подписан в списках |
password | нет | свой пароль (не короче 8 символов) или сгенерированный сервером |
expires_at / ttl_hours | нет | точная дата (RFC 3339) или срок в часах |
Три поведения, о которые спотыкаются чаще всего:
- Телефон обязателен и уникален. Он нужен не для связи, а для восстановления: гость регулярно теряет выданный пароль, и без телефона единственным способом остаётся заявка администратору. Второй гость с тем же номером получит 409.
- Срок по умолчанию — 30 дней, даже если вы про него не думали. Максимум задаёт администратор (по умолчанию год), и указанный срок молча урезается до максимума, а не отклоняется.
- Кто пригласил — остаётся в записи навсегда (
invited_by), и приглашение попадает в аудит. Гость всегда кому-то принадлежит; «ничей» гость в системе не появляется.
Проверка: запись видна в консоли (Users → фильтр по роли guest) со сроком и именем
пригласившего, а гость входит выданной парой логин/пароль.
3. Максимальный срок приглашения
Ограничение ставится один раз и действует на все самостоятельные приглашения:
curl -fsS -X POST "https://s2.<домен>/admin/api/settings/guest-max-days" \
-H "Cookie: $ADMIN_SESSION" -H 'Content-Type: application/json' \
-d '{"days":90}'
Проверка: приглашение с ttl_hours больше лимита создаётся, но в ответе expires_at
приходит урезанным до лимита.
4. Что гость получает в сети — и чего не получает
Гостевой профиль выпускает в интернет через узел из группы geo-pool и не содержит
корпоративных маршрутов. Разница между «запрещено» и «не описано» здесь принципиальна:
запрет снимается галочкой, отсутствующего маршрута снять нельзя.
Отсюда и сценарий «член семьи сотрудника»: домашнему устройству нужен защищённый интернет, и гостевого класса для этого достаточно. Заводить ем у что-то большее не нужно — а по построению профиля и не получится.
Каталог организации гость не читает: область видимости каталога — свойство роли
(none / groups / org), а не следствие участия в разговоре.
5. Восстановление доступа
Гость восстанавливает доступ сам, по телефону, без администратора:
curl -fsS -X POST "https://s2.<домен>/v1/auth/recover" \
-H 'Content-Type: application/json' -d '{"phone":"+79001234567"}'
Платформа заказывает обратный звонок, который диктует шестизначный код; код и новый пароль уходят во второй вызов:
curl -fsS -X POST "https://s2.<домен>/v1/auth/recover/confirm" \
-H 'Content-Type: application/json' \
-d '{"phone":"+79001234567","code":"123456","password":"<новый пароль>"}'
Ограничения намеренные: одна заявка в минуту на номер, код живёт 10 минут, пять попыток, одноразовый. Ответы одинаковы для существующего и несуществующего номера — иначе перебор номеров превращается в способ узнать, кто у вас есть.
Обратный звонок делает служба телефонии (роль mediation). Там, где её ещё не развернули,
заявка на восстановление появляется в консоли (Users → карточка «Access recovery»), и код
диктует администратор или пригласивший сотрудник. Восстановление работает только для
локальных учётных записей: пользователю из корпоративного каталога пароль меняет каталог.
6. Отзыв
- Сам по себе. Истёк срок — доступ закрылся; забытый гость исчезает без чьего-либо участия. Это и есть причина, по которой срок обязателен.
- Раньше срока. Отключение или удаление записи в консоли; сессии и устройства там же видны по именам. Доступ к сети закрывается на следующем цикле обновления политики на устройстве, а не «когда-нибудь».
Типовые отказы
| Симптом | Вероятная причина |
|---|---|
403 на POST /v1/guests | у роли сотрудника нет права guests:invite |
409 a user with this phone already exists | номер уже привязан к другой записи; телефон уникален |
400 invalid expires_at (want RFC3339) | дата не в формате 2026-12-31T23:59:59Z |
| Гость входит, но не видит коллег | область каталога у роли guest — так и задумано; смотрите политику роли |
| Гость подключился, но внутренние адреса недоступны | ожидаемо: в гостевом наборе правил корпоративных маршрутов нет |
| Восстановление «прошло», но звонка не было | телефония не развёрнута — код в консоли, карточка «Access recovery» |