TQE Documentation portal logo
Помощь
Обновлена 9 ноября 2026 г. в 13:01

Аутентификация и авторизация

Авторизация в TQE(MQ) работает на двух уровнях:

  • Уровень gRPC — собственный механизм TQE: аутентификация клиента и проверка его прав на очереди.
  • Уровень ядра (Tarantool) — штатные механизмы Tarantool: контроль прав сервисного аккаунта, под которым gRPC-сервер обращается к ядру по IPROTO.

Также см. пример конфигурации для работы на сервере с включенной авторизацией.

Уровень gRPC (базовая аутентификация + RBAC)

При каждом вызове gRPC API проверяются учетные данные клиента. Учетные данные хранятся в трех сущностях:

  • user — учетная запись клиента gRPC API.
  • secret — данные о пароле пользователя, которые хранятся отдельно, в виде bcrypt-хэша.
  • role — набор прав (tqe.produce, tqe.consume, tqe.admin).

Совокупность этих сущностей определяет прохождение базовой аутентификации и авторизацию (RBAC) клиента на сервере.

Базовая аутентификация по TLS

Клиент передает логин и пароль в gRPC-метаданных authorization: Basic base64(login:password) по обязательному протоколу шифрования TLS.

Пароль передается внутри TLS-канала в Base64 кодировке, и никогда не хранится в открытом виде: в хранилище лежит только bcrypt-хэш. Успешная проверка пароля кэшируется на короткое время, чтобы не повторять bcrypt при каждом запросе. После серии неудачных попыток секрет временно блокируется (защита от подбора).

Авторизация — RBAC

В TQE (MQ) привилегии выдаются на отдельные очереди сообщений и на шаблоны имен очередей (queue_patterns). Шаблон имени очереди является частью имени очереди с маской с *, например billing.*. Операция с очередью разрешается, если шаблон, на который назначена роль, совпадает с очередью, а роль содержит нужную привилегию.

Встроенные роли и их привилегии:

Роль
Привилегии
Назначение
Admin
tqe.admin
Управление сущностями user, secret, и role (все методы Iam)
Producer
tqe.produce
Публикация в очередь (Produce, ProduceStream, Broadcast)
Consumer
tqe.consume
Подписка и коммит курсора в пределах того же потока, чтение через consumer-group (Subscribe, ConsumeGroup)

Матрица прав по gRPC-методам:

RPC
Producer
Consumer
Produce / ProduceStream / Broadcast
✓
—
Subscribe / ConsumeGroup
—
✓

Конфигурация

Конфигурация аутентификации задается в разделе auth. Параметры раздела:

  • enabled - включает аутентификацию и авторизацию gRPC API. Значение по умолчанию: false. При true требуется grpc_options.tls.enabled: true, иначе сервер не запускается.
  • permission_cache_ttl - время жизни снимка прав по user_id. Значение 0 разворачивает снимок на каждую проверку. Значение по умолчанию: 1s.
  • credentials_cache_ttl - время жизни кэша проверенных учетных данных. Позволяет не выполнять bcrypt на каждый запрос. Значение по умолчанию: 30s.
  • store_poll_interval - период фонового опроса хранилища данных аутентификации с указанием единиц измерения. Задает задержку отзыва прав и блокировок. Значение по умолчанию: 10s.
  • store_stale_ttl - период, в течение которого авторизационные данные считаются корректными, в случае недоступности их внешнего хранилища. Задается с указанием единиц измерения. Значение по умолчанию: 5m. В случае его истечения, все вызовы возвращают Unavailable. Должен превышать store_poll_interval.
  • integrity - раздел проверки подписи сущностей (RSA-PSS).
    • check - включает или выключает проверку подписи. Принимает значения:
      • true - отклонять значение с несовпавшей подписью.
      • false - возвращать значение. Используется по умолчанию.
    • private_key_file - путь к ключу подписи (RSA-2048, PKCS#1, PEM). Пустое значение - встроенный ключ по умолчанию (для разработки).
  • password_policy - раздел требований к паролям и блокировки после неудачных попыток.
    • min_length - минимальная длина пароля. Сложность по классам символов не требуется. Значение по умолчанию: 16.
    • lockout_threshold - число неудачных попыток до временной блокировки секрета. Значение по умолчанию: 10.
    • lockout_duration - длительность временной блокировки, задается с указанием единиц измерения. Значение 0 выключает блокировку. Значение по умолчанию: 1m.
    • max_age - срок действия пароля. Значение 0 выключает принудительную смену; значение больше 0 включает смену по сроку.
    • history_depth - количество прежних хэшей пароля, которые хранятся для запрета повторного использования. Значение по умолчанию: 0. При таком значении история прошлых паролей не ведется и ничего не сверяется — задать можно любой пароль, включая действующий.

Пример настройки:

grpc_options:  tls:    enabled: true                      # Всегда true при auth.enabled: true.    cert_file: /etc/tqe/grpc.crt    key_file: /etc/tqe/grpc.keyauth:  enabled: true  permission_cache_ttl: 1s  credentials_cache_ttl: 30s  store_poll_interval: 10s  store_stale_ttl: 5m  integrity:    check: true    private_key_file: /etc/tqe/auth-sign.pem  password_policy:    min_length: 16    lockout_threshold: 10    lockout_duration: 1m    max_age: 0    history_depth: 0

Создание первого администратора

При включенной аутентификации/авторизации ни один gRPC-вызов, включая методы сервиса tarantool.queue_ee.Iam не выполнится, пока в хранилище нет хотя бы одного пользователя. Если в конфигурации указан блок auth.bootstrap, первый пользователь (с привилегиями администратора) создается сервером при старте. Параметры раздела:

  • login - логин пользователя.
  • password - пароль в открытом виде. Используется только для разработки.
  • password_env - имя переменной окружения с паролем. Рекомендуемый вариант: пароль не хранится в конфигурации. Пустой пароль недопустим.

Опции password и password_env являются взаимоисключающими, и не могут использоваться одновременно.

auth:  bootstrap:    login: admin    password_env: TQE_BOOTSTRAP_ADMIN_PASSWORD   # или (не рекомендуется) password: "..."    # queue_patterns: ["*"]  # по умолчанию ["*"] — все очереди

Порядок начальной загрузки (при auth.enabled: true):

  1. При старте сервер загружает кэш из хранилища.
  2. Если в хранилище нет ни одного пользователя и задан блок auth.bootstrap, сервер создает первого администратора: пользователя с именем auth.bootstrap.login, парольный секрет (bcrypt-хэш пароля из password или password_env) и назначение встроенной роли Admin на шаблоны auth.bootstrap.queue_patterns.
  3. Если пользователи в хранилище уже есть, начальная загрузка пропускается. Операция идемпотентна.
  4. Если хранилище пусто и блок auth.bootstrap не задан, сервер запускается с предупреждением — все gRPC-вызовы будут возвращать ошибку Unauthenticated: authentication failed.

Управление сущностями учетных данных

Сущности учетных данных управляются сервисом tarantool.queue_ee.Iam (см. описание Iam API). Для вызова его методов нужно право tqe.admin.

Пример настройки доступа через grpcurl. Логин и пароль администратора заданы в auth.bootstrap:

export TQE_ADDR=mq.example:8443export CACERT=/etc/tqe/ca.crtexport ADMIN_B64=$(printf '%s' "admin:${TQE_BOOTSTRAP_ADMIN_PASSWORD}" | base64 | tr -d '\n')export AUTH="authorization: Basic ${ADMIN_B64}"# Создать сервисного пользователя и задать ему пароль:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc", "description": "orders service producer/consumer"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/CreateUsergrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc", "password": "S3rv1ce-Pa55!"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/SetPassword# Назначить роли на шаблоны очередей:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc", "role": "Producer", "queuePatterns": ["orders.*"]}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/GrantRolegrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc", "role": "Consumer", "queuePatterns": ["orders.replies"]}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/GrantRole# Создать пользовательскую роль и назначить её:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "billing-writer", "description": "publish to billing queues", "permissions": ["tqe.produce"]}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/CreateRolegrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "billing-svc", "role": "billing-writer", "queuePatterns": ["billing.*", "audit.invoices"]}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/GrantRole# Посмотреть и обновить пользователя:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/GetUsergrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc", "description": "updated description"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/UpdateUser# Сузить или снять роль:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "billing-svc", "role": "billing-writer", "queuePatterns": ["audit.invoices"]}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/RevokeRolegrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc", "role": "Consumer"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/RevokeRole# Посмотреть роли (встроенные и пользовательские):grpcurl -cacert "$CACERT" -H "$AUTH" "$TQE_ADDR" tarantool.queue_ee.Iam/ListRolesgrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "billing-writer"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/GetRole# Удалить пользовательскую роль и пользователя:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "billing-writer"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/DeleteRolegrpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "orders-svc"}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/DeleteUser

Примеры отказов:

# Нет учетных данных:grpcurl -cacert "$CACERT" "$TQE_ADDR" tarantool.queue_ee.Iam/ListUsers# ERROR: Code: Unauthenticated# Действительный пользователь, но без tqe.admin:grpcurl -cacert "$CACERT" -H "authorization: Basic $(printf '%s' 'orders-svc:S3rv1ce-Pa55!' | base64 | tr -d '\n')" \  "$TQE_ADDR" tarantool.queue_ee.Iam/ListUsers# ERROR: Code: PermissionDenied# Правка встроенной роли:grpcurl -cacert "$CACERT" -H "$AUTH" -d '{"name": "Admin", "permissions": []}' \  "$TQE_ADDR" tarantool.queue_ee.Iam/UpdateRole# ERROR: Code: FailedPrecondition Message: builtin role is immutable

Аудит

Каждый вызов записывается в журнал вместе с решением. В запись добавляются поля:

  • method — имя gRPC-метода.
  • auth_method — способ аутентификации (basic).
  • user — имя аутентифицированного пользователя (если известен).
  • queue — имя очереди, к которой относится вызов (если метод привязан к очереди).
  • perm — требуемое право.
  • decision — allow либо deny:<причина>.

Разрешенный вызов записывается на уровне debug, отклоненный — на уровне warn. Причины отказа (deny:<причина>): no_creds, auth_failed, no_grant, unknown_method, no_queue, store_unavailable, no_active_subscription.

Уровень ядра (Tarantool)

На уровне ядра TQE(MQ) использует штатные механизмы Tarantool: пользователи, роли и привилегии объявляются в секции credentials файла config.yml. Привилегии проверяет сам Tarantool.

Есть два вида учетных записей:

  • Прикладные («Пользователи TQE») — публикатор и потребитель, через которых внешние приложения публикуют и читают сообщения.
  • Служебные — внутренние пользователи Tarantool (storage, replicator), обеспечивающие шардирование, репликацию и работу оркестратора. Доступа к данным очередей они не дают.

Привилегии выдаются на двух уровнях:

  • Роли дают право вызывать функции (execute на lua_call).
  • Привилегии на спейсы очередей дают доступ к данным: write на queue_<name> — право публиковать, read — право читать. Публикация с deduplication_key требует обоих прав (read и write).

Прикладные учетные записи (пользователи TQE)

Учетная запись
Роль
Привилегии на спейсы очередей
публикатор
tqe_producer
read и write на каждый queue_<name> (публикация)
потребитель
tqe_consumer
read на каждый queue_<name> (чтение)

Одна учетная запись может совмещать публикацию и чтение — тогда ей выдаются обе роли (tqe_producer и tqe_consumer), а на нужных очередях — обе привилегии read и write. Имена учетных записей произвольны (в примерах ниже — tqe_producer_user и tqe_consumer_user).

Служебные учетные записи

  • storage — пользователь vshard для маршрутизации между роутером и хранилищами. Использует встроенную роль sharding и указывается в блоке iproto.advertise.sharding. Нужен в любой шардированной конфигурации.
  • replicator — пользователь для WAL-репликации между мастером и репликами; в конфигурации с оркестратором используется также для его внутренних (connpool) вызовов. Использует встроенную роль replication и указывается в блоке iproto.advertise.peer. Нужен при наличии реплик в наборе реплик или экземпляра с ролью roles.tqe-orchestrator.
  • admin — встроенный пользователь со всеми административными привилегиями, доступен только через локальный UNIX-сокет экземпляра. Отдельной записью в credentials.users объявляются пользователи для соединения по IPROTO для выполнения административных задач.

Роли и привилегии на очереди

Роли tqe_producer и tqe_consumer дают право выполнять операции только своего типа — публикацию или чтение. Привилегий на конкретные очереди в ролях нет: привязку к очередям задает администратор отдельно, на самой учетной записи (credentials.users.<user>.privileges).

Служебные учетные записи получают следующие дополнительные привилегии execute (сверх встроенных ролей):

  • replicator (роль replication):

    - vshard.router.buckets_info- router.is_vshard_bootstrapped- router.get_buckets- router.get_advertised_shards- storage.acquire_state- storage.delete_state

Пример конфигурации

Пример конфигурации ядра с consumer-группами и минимальными привилегиями (боевой стенд):

security:  disable_guest: truecredentials:  roles:    # Привилегии на функции выдаются явно через роли; привилегии на очереди — на учетках.    tqe_producer:      privileges:        - permissions: [execute]          lua_call:            - router.is_vshard_bootstrapped            - router.get_sharding_mode            - router.get_buckets            - router.get_shards            - vshard.storage.buckets_discovery            - storage.produce    tqe_consumer:      privileges:        - permissions: [execute]          lua_call:            - router.is_vshard_bootstrapped            - router.get_sharding_mode            - router.get_buckets            - router.get_shards            - vshard.storage.buckets_discovery            - storage.create_poller            - storage.poll_from            - storage.delete_poller            - storage.acquire_state            - storage.commit_state            - storage.release_state            - storage.delete_state            - storage.touch_state            - orchestrator.partition_map            - orchestrator.group_join            - orchestrator.group_sync            - orchestrator.group_exit  users:    # admin — встроенная учетная запись Tarantool, отдельной записью не объявляется.    # Служебная запись репликации и connpool-вызовов оркестратора.    replicator:      password: "<replicator-secret>"      roles: [replication]      privileges:        - permissions: [execute]          lua_call:            - vshard.router.buckets_info            - router.is_vshard_bootstrapped            - router.get_buckets            - router.get_advertised_shards            - storage.acquire_state            - storage.delete_state    # Служебная запись vshard (роутер <-> хранилище).    storage:      password: "<storage-secret>"      roles: [sharding]      privileges:        - permissions: [execute]          lua_call:            - storage.get_advertise_uri    # Прикладные учетные записи; привилегии на конкретные очереди задаются здесь.    # producer.tarantool.user / consumer.tarantool.user в config.service.yml.    tqe_producer_user:      password: "<producer-secret>"      roles: [tqe_producer]      privileges:        # write — публикация; read добавляется при использовании deduplication_key.        - permissions: [write]          spaces: [queue_orders, queue_events]    tqe_consumer_user:      password: "<consumer-secret>"      roles: [tqe_consumer]      privileges:        - permissions: [read]          spaces: [queue_orders, queue_events]iproto:  advertise:    peer:      login: replicator      password: "<replicator-secret>"    sharding:      login: storage      password: "<storage-secret>"

Рекомендации по безопасности

  • Выдавайте доступ к очередям по принципу минимальных привилегий: каждой прикладной учетной записи — только write/read на те очереди, с которыми она действительно работает.
  • Для каждой новой очереди добавляйте отдельную привилегию.
  • Не используйте роли universe и super для прикладных учетных записей в рабочих (production) окружениях.
  • Выставляйте security.disable_guest: true.
  • Не храните пароли в открытом виде. Используйте config.context (from: env или from: file), а в credentials подставляйте ссылку вида {{ context.<имя> }}.
  • Осуществляйте доступ под admin только через локальный UNIX-сокет экземпляра.
  • Не меняйте состав встроенных ролей служебных пользователей (для replicator допустима только роль replication, для storage — только sharding).
  • Регулярно меняйте пароли служебных записей.
  • Проверяйте фактический набор привилегий на каждой реплике через box.schema.user.info(<name>).

Отображение ошибок доступа

Если Tarantool отказывает в доступе, ядро возвращает ошибку с кодом box.error.ACCESS_DENIED (например, Write access to space 'queue_orders' is denied for user '...'). gRPC-сервер возвращает статус PermissionDenied для методов Produce, Broadcast, ProduceStream, Subscribe и ConsumeGroup.

Пример конфигурации

В примере ниже представлена конфигурация модуля API с включенной аутентификацией и авторизацией gRPC:

## Модуль API с включенной аутентификацией и авторизацией gRPC.#### Три условия, без которых сервер не стартует:##   1. auth.enabled: true требует grpc_options.tls.enabled: true##      (Basic-учетные данные не выпускаются в незашифрованный канал);##   2. auth.enabled: true требует источник конфигурации кластера —##      config.etcd или config.storage: там лежат auth-данные;##   3. auth.bootstrap.password_env должна указывать на непустую переменную.app_name: MESSAGE_QUEUE_EE_APIapp_version: grpc-auth-examplecore_host: 0.0.0.0core_port: 18184grpc_listen:  - uri: 'tcp://0.0.0.0:18182'grpc_options:  ## Рефлексия требует права tqe.admin: учетные записи с ролями Producer или  ## Consumer вызывают методы только с -proto / -protoset. Выключите рефлексию,  ## если клиенты и так работают по сгенерированным стабам.  reflection_enabled: true  tls:    enabled: true    cert_file: certs/grpc.crt    key_file: certs/grpc.key    ## ca_file здесь НЕ задан намеренно: он включает проверку клиентского    ## сертификата (mTLS), и тогда каждому клиенту нужны свои cert/key.    ## Пример с mTLS — examples/grpc-mtls.## Источник конфигурации кластера. Обязателен при auth.enabled: true:## пользователи, секреты и роли gRPC API хранятся здесь же.#### ВНИМАНИЕ: эта же секция включает автоматическое обнаружение топологии,## которое заполняет producer/consumer.tarantool.connections из etcd.## Поэтому connections ниже не задаются — заданные значения будут затерты.config:  etcd:    endpoints:      - "http://127.0.0.1:2379"    prefix: "/tqe/grpc-auth-example"    timeout: 5s    reconnect_after: 5s    max_reconnect_attempts: 3    ## Для etcd с аутентификацией:    # username: tqe    # password: "{{ из окружения через шаблон вашего деплоя }}"    ## Для etcd по TLS:    # ssl:    #   ca_file: certs/etcd-ca.crt    #   verify_peer: true    #   verify_host: true## Учетные записи Tarantool, под которыми модуль API ходит в ядро по IPROTO.## Это отдельный уровень доступа: с gRPC-пользователями он не связан.producer:  enabled: true  tarantool:    user: tqe_producer_user    pass: producer-secretconsumer:  enabled: true  polling_timeout: 500ms  tarantool:    user: tqe_consumer_user    pass: consumer-secretauth:  enabled: true  ## Время жизни снимка прав по пользователю. 0 — разворачивать на каждую проверку.  permission_cache_ttl: 1s  ## Время жизни кэша проверенных учетных данных: позволяет не выполнять bcrypt  ## на каждый запрос. Учтите, что проверки блокировки и истечения срока секрета  ## внутри этого окна не выполняются — оно добавляется к задержке отзыва прав.  credentials_cache_ttl: 30s  ## Период фонового опроса хранилища. Задает задержку, с которой до сервера  ## доходят отзыв прав, блокировка и удаление пользователя. Открытые стримы  ## Subscribe и ConsumeGroup при этом разрываются.  store_poll_interval: 10s  ## Сколько сервер отвечает по копии auth-данных после того, как хранилище  ## перестало отвечать. По истечении все вызовы отклоняются с Unavailable,  ## а проба готовности /readyz по ключу auth-data гаснет.  ## Должно быть строго больше store_poll_interval.  store_stale_ttl: 5m  integrity:    ## true — отклонять сущности с несовпавшей подписью.    ## Включайте вместе с собственным ключом: пустой private_key_file означает    ## встроенный ключ, общий для всех установок и пригодный только для разработки.    check: false    # private_key_file: certs/auth-sign.pem  password_policy:    ## Сложность по классам символов не требуется, длина — требуется.    min_length: 16    lockout_threshold: 10    lockout_duration: 1m    ## 0 — принудительная смена по сроку выключена. Включать осознанно:    ## самостоятельной смены пароля нет, просроченный секрет чинит только    ## администратор через Iam/SetPassword.    max_age: 0    ## 0 — история прошлых паролей не ведется, повтор действующего разрешен.    history_depth: 0  ## Первый администратор, создаваемый на пустом хранилище при старте.  ## Без него ни один gRPC-вызов не пройдет, включая методы Iam.  ## Операция идемпотентна: на непустом хранилище пропускается.  bootstrap:    login: admin    ## Пароль берется из переменной окружения и не хранится в конфиге.    ## Должен удовлетворять password_policy.min_length.    ## Взаимоисключающе с полем password.    password_env: TQE_BOOTSTRAP_ADMIN_PASSWORD    ## Шаблоны очередей для встроенной роли Admin. Право tqe.admin не    ## ограничивается очередями, поэтому сузить администратора этим полем нельзя.    queue_patterns: ["*"]log:  ## debug дополнительно показывает аудит разрешенных вызовов;  ## отклоненные пишутся на уровне warn в любом случае.  level: info
Была ли статья полезна?