Permissions Overview
1. Обзор разрешений#
В системе управления идентификацией и доступом (IAM) Permission (разрешение) — это основная сущность, определяющая право на выполнение конкретного действия над конкретным ресурсом. IAM работает по модели "запрет по умолчанию": если у пользователя или сервиса нет явно предоставленного разрешения на действие, это действие блокируется.
1.1. Структура разрешения#
Каждое разрешение представляется строкой, состоящей из трёх частей, разделённых точками:
<service_name>.<resource_name>.<action>
-
<service_name>:- Уникальный идентификатор сервиса или модуля в вашей системе
- Примеры:
billing,compute,auth,storage
-
<resource_name>:- Определяет тип объекта, над которым может быть выполнено действие
- Выражается в единственном числе
- Примеры:
account,vm,user,policy
-
<action>:- Определяет операцию, которая может быть выполнена над указанным ресурсом
- Примеры:
read,write,create,delete,activate
Примеры разрешений:
billing.account.read— просмотр информации об аккаунте в сервисе биллингаcompute.vm.create— создание новой виртуальной машины в сервисе вычисленийauth.user.deactivate— деактивация пользователя в сервисе аутентификации
Вы также можете использовать * (wildcard) в любой из трёх частей. Это означает, что разрешены все значения в этой части.
Как работает * по частям:
*в первой части (service_name) — доступ к всем сервисам*во второй части (resource_name) — доступ ко всем ресурсам в выбранном сервисе*в третьей части (action) — доступ ко всем действиям над выбранным ресурсом
Примеры wildcard-разрешений:
*.vm.read— позволяет читатьvmво всех сервисахcompute.*.read— позволяет читать любой ресурс в сервисеcomputecompute.vm.*— позволяет выполнять любые действия надvmв сервисеcompute*.*.*— полный доступ ко всем сервисам, ресурсам и действиям
1.2. Модель безопасности: "Запрет по умолчанию"#
Важная философия IAM — принцип явного разрешения:
- Изначально любой пользователь или сервисный аккаунт не имеет прав доступа
- Для выполнения любого действия субъекту должно быть предоставлено соответствующее разрешение
- Сервисы, интегрированные с IAM, должны проверять наличие требуемого разрешения перед выполнением операции
1.3. Примеры API разрешений#
Создание разрешения#
POST /v1/iam/permissions/
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "compute.vm.create",
"description": "Разрешение на создание виртуальной машины"
}
Ответ#
{
"uuid": "5a1b2c3d-4e5f-6789-abcd-ef0123456789",
"name": "compute.vm.create",
"description": "Разрешение на создание виртуальной машины",
"created_at": "2025-08-21T07:38:04.778680Z",
"updated_at": "2025-08-21T07:38:04.778688Z",
"status": "ACTIVE"
}
Получение разрешения#
GET /v1/iam/permissions/5a1b2c3d-4e5f-6789-abcd-ef0123456789
Authorization: Bearer <token>
Фильтрация разрешений#
GET /v1/iam/permissions/?name=compute.vm.create&status=ACTIVE
Authorization: Bearer <token>
2. Роли#
Role (роль) — это именованная коллекция разрешений. Если разрешение определяет право на одно конкретное действие, то роль группирует эти права в логические блоки, соответствующие должностным функциям, обязанностям или уровню доступа пользователя или сервиса.
2.1. Привязка разрешений: связь ролей и разрешений#
Для назначения разрешений роли используется сущность Permission Binding (привязка разрешения). Эта сущность устанавливает отношение многие-ко-многим между ролями и разрешениями.
- Одно разрешение может быть привязано к нескольким разным ролям
- Одна роль может содержать множество разных разрешений
Пример:
- Роль
BillingViewerполучает следующие разрешения через Permission Binding:billing.account.readbilling.invoice.read
- Роль
BillingOperatorполучает следующие разрешения через Permission Binding:billing.account.readbilling.invoice.readbilling.invoice.pay
2.2. Привязка ролей: назначение ролей пользователям#
Для предоставления пользователю доступа роль должна быть назначена ему. Для этого используется сущность Role Binding (привязка роли). Эта сущность устанавливает отношение многие-ко-многим между пользователями и ролями.
- Один пользователь может быть назначен на несколько ролей
- Одна роль может быть назначена многим пользователям
2.3. Итоговая модель доступа#
Процесс проверки доступа:
- Пользователь вызывает сервис с токеном
- Сервис вызывает интроспекцию токена IAM
- Сервис получает список разрешений, доступных для этого токена, из ответа интроспекции
- Сервис проверяет, существует ли требуемое разрешение для запрошенного действия
- Если разрешение присутствует, доступ предоставляется
2.4. Примеры API ролей#
Создание роли#
POST /v1/iam/roles/
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "BillingOperator",
"description": "Оператор биллинга с правами управления аккаунтами"
}
Ответ#
{
"uuid": "6b2c3d4e-5f67-789a-bcde-f01234567890",
"name": "BillingOperator",
"description": "Оператор биллинга с правами управления аккаунтами",
"created_at": "2025-08-21T07:38:04.779416Z",
"updated_at": "2025-08-21T07:38:04.779424Z",
"status": "ACTIVE",
"project_id": null
}
Создание привязки разрешения#
POST /v1/iam/permission_bindings/
Content-Type: application/json
Authorization: Bearer <token>
{
"role": "6b2c3d4e-5f67-789a-bcde-f01234567890",
"permission": "5a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
Создание привязки роли#
POST /v1/iam/role_bindings/
Content-Type: application/json
Authorization: Bearer <token>
{
"user": "7c3d4e5f-6789-89ab-cdef-123456789012",
"role": "6b2c3d4e-5f67-789a-bcde-f01234567890",
"project": "8d4e5f67-789a-9abc-def1-234567890123"
}
Получение ролей пользователя#
GET /v1/iam/users/7c3d4e5f-6789-89ab-cdef-123456789012/actions/get_my_roles
Authorization: Bearer <token>
2.5. Проекты и область действия ролей/разрешений#
В IAM роли могут быть назначены:
- Глобально (без проекта,
project = null) - В рамках проекта (через поле
projectвRole Binding)
Это напрямую влияет на эффективный набор разрешений в токене.
При выдаче токена IAM определяет проект из scope:
project:<uuid>— токен привязан к указанному проектуproject:default— токен привязан к проекту по умолчанию пользователя- если нет сегмента
project:...вscope, токен выдаётся без проекта (project = null)
При интроспекции IAM возвращает разрешения только в контексте проекта токена. Другими словами, эффективный набор разрешений зависит от того, для какого проекта выдан токен.
Важно:
получение токена без проекта не даёт автоматического доступа ко всем проектам.
Такой токен включает только разрешения, действительные в контексте project = null (глобальные назначения), и не включает назначения в рамках проекта из других проектов.
2.6. Как сервисы должны проверять разрешения (практический шаблон)#
Ниже приведена рекомендуемая модель интеграции бизнес-сервиса с IAM.
Базовый поток#
- Сервис получает токен пользователя (
Authorization: Bearer ...) - Сервис вызывает конечную точку интроспекции токена IAM
- Сервис получает список разрешений из интроспекции для текущего токена
- Перед каждым защищённым действием сервис проверяет наличие требуемого разрешения
- Если разрешение отсутствует, сервис возвращает
403 Forbidden
Минимальная структура кода сервиса#
class IamClient:
def introspect(self, token: str) -> dict:
# HTTP GET /v1/iam/clients/<client_uuid>/actions/introspect/invoke
# с Authorization: Bearer <token>
...
class AuthContext:
def __init__(self, token: str, introspection: dict):
self.token = token
self.introspection = introspection
self.permissions = {
p["name"] if isinstance(p, dict) else str(p)
for p in introspection.get("permissions", [])
}
def has_permission(self, permission_name: str) -> bool:
return permission_name in self.permissions
class PermissionDenied(Exception):
pass
Guard/декоратор для проверки разрешений#
def require_permission(permission_name: str):
def wrapper(handler):
def inner(request, *args, **kwargs):
ctx: AuthContext = request.auth_context
if not ctx.has_permission(permission_name):
raise PermissionDenied(
f"Missing required permission: {permission_name}"
)
return handler(request, *args, **kwargs)
return inner
return wrapper
Пример конечной точки#
@require_permission("compute.vm.create")
def create_vm(request):
payload = request.json
# Бизнес-логика создания VM
return {"status": "ok"}, 201
Инициализация контекста в middleware#
def auth_middleware(request, iam_client: IamClient):
token = extract_bearer_token(request.headers)
if not token:
return {"error": "Unauthorized"}, 401
introspection = iam_client.introspect(token)
request.auth_context = AuthContext(token=token, introspection=introspection)
return None # продолжить
Практические рекомендации#
- Проверяйте разрешения как можно ближе к точке выполнения действия (конечная точка/use-case)
- Не выводите права в сервисе — IAM должен оставаться единственным источником правды
- Приемлем только кратковременный кэш интроспекции на стороне сервера; не кэшируйте разрешения на клиентской стороне
- Логируйте отказы в доступе с указанием требуемого разрешения и контекста пользователя/токена
3. Лучшие практики#
3.1. Принцип минимальных привилегий#
Создавайте роли, предоставляющие ровно тот уровень доступа, который требуется для выполнения задачи, и не больше.
3.2. Семантическое именование#
Давайте ролям и разрешениям понятные имена, отражающие их назначение:
- Роли:
NetworkReadOnly,DatabaseSuperUser - Разрешения:
compute.vm.read,storage.bucket.delete
3.3. Регулярные аудиты#
Периодически проверяйте:
- Какие роли назначены кому
- Какие разрешения включены в роли
- Удаляйте ненужный доступ незамедлительно
3.4. Использование проектов для изоляции#
Используйте привязку ролей в рамках проекта для изоляции доступа между окружениями. Подробное описание поведения в контексте проекта дано в разделе 2.5.
4. Обработка ошибок#
Следующие ошибки могут возникнуть при работе с IAM API:
4.1. Ошибка доступа (403 Forbidden)#
{
"status": 403,
"json": {
"code": 403,
"type": "PermissionDeniedException",
"message": "User does not have required permission: compute.vm.create"
}
}
4.2. Не найдено (404 Not Found)#
{
"status": 404,
"json": {
"code": 404,
"type": "NotFoundException",
"message": "Role with uuid 6b2c3d4e-5f67-789a-bcde-f01234567890 not found"
}
}
4.3. Некорректный запрос (400 Bad Request)#
{
"status": 400,
"json": {
"code": 400,
"type": "ValidationErrorException",
"message": "Field 'name' must be between 0 and 255 characters"
}
}
5. Важные замечания#
- Все изменения разрешений и привязок ролей вступают в силу немедленно
- Не кэшируйте разрешения на клиентской стороне; если кэширование необходимо, используйте только кратковременный серверный кэш интроспекции
- Для сервисных аккаунтов используйте отдельные роли с минимально необходимыми разрешениями
- Регулярно обновляйте и проверяйте назначения ролей в системе