Модель безопасности
Semaphore хранит учётные данные к вашей инфраструктуре и запускает код в ней. Из этого следуют два свойства, и оба определяют все остальные решения на этой странице: секреты никогда не должны во звращаться в браузер, и любой, кто может запустить задачу, может выполнить код на машинах, до которых эта задача дотягивается.
Эта страница объясняет модель. О настройках, которые её реализуют, см. Безопасность.
Границы доверия
| Граница | Что её пересекает | Чем защищена |
|---|---|---|
| Браузер ↔ сервер | Сессии, API-токены | TLS, защищённые cookie, обратный прокси |
| Сервер ↔ база данных | Всё постоянное состояние | Сетевые ограничения; секреты шифруются перед записью |
| Сервер ↔ раннер | Полезная нагрузка заданий, включая секреты | HTTPS и bearer-токен для каждого раннера |
| Задача ↔ управляемые хосты | Ваша автоматизация | Ключи, которые вы указали в шаблоне |
Задача находится по дальнюю сторону каждой из этих границ. Она получает нужные ей секреты в своём окружении, и с этого момента судьбу секретов определяет код в вашем реп озитории.
Идентификация
Пользователи проходят аутентификацию одним из трёх способов, и все три приводят к одной и той же сессии:
- Локальные учётные записи. Пароли хешируются с помощью Argon2id (до 2.20 — bcrypt, с обновлением при первом входе). Можно потребовать двухфакторную аутентификацию TOTP.
- LDAP или Active Directory. Пароль проверяет каталог, а Semaphore хранит только учётную запись.
- OpenID Connect. Провайдер выполняет аутентификацию, а Semaphore сопоставляет claim'ы с пользователями.
Для неинтерактивного доступа используются API-токены, созданные пользователем и несущие его права. Раннеры вообще не используют пользовательскую идентификацию: они аутентифицируются собственным токеном, выданным при регистрации.
Задачи тоже могут нести идентификацию. С JWT задач запуск получает короткоживущий подписанный токен с указанием проекта, шаблона и пользователя, который внешнее хранилище секретов может проверить вместо того, чтобы вы хранили долгоживущие учётные данные.
Авторизация
Существует два независимых уровня.
Уровень сервера. Администратор управляет пользователями, глобальными раннерами и настройками сервера. Быть администратором сервера само по себе не даёт членства в проекте.
Уровень проекта. У каждого участника есть одна роль в каждом проекте:
| Роль | Что может |
|---|---|
| Owner | Всё в проекте, включая управление участниками и удаление. |
| Manager | Запускать задачи и управлять ресурсами и шаблонами. |
| Task Runner | Запускать задачи. Больше ничего. |
| Guest | Читать. |
В Enterprise добавляются пользовательские роли Enterprisesince 2.17 на случай, когда этих четырёх слишком мало.
Важная с точки зрения безопасности граница проходит между Task Runner и Manager. Manager может изменить то, что выполняет шаблон, а значит, может выполнить произвольный код с учётными данными этого проекта. Task Runner может лишь запустить то, что уже существует, — если только шаблон не предоставляет prompts или survey-переменные, попадающие в командную строку: в этом случае автор шаблона расширил эту границу намеренно.
Секреты
Секретные значения — приватные SSH-ключи, пароли, токены, секретные переменные —
шифруются ключом из access_key_encryption перед сохранением, поэтому один только дамп
базы данных их не раскрывает. API никогда не возвращает секретное значение; UI
показывает, что секрет задан, но не то, каков он.
Секреты попадают в задачу через её окружение в момент запуска. Именно поэтому вывод задачи стоит считать чувствительным: playbook, который печатает переменную, печатает её в лог, доступный другим участникам проекта.