Permissions Overview
1. Permissions Overview#
In the Identity and Access Management (IAM) system, a Permission is a core entity that defines the right to perform a specific action on a specific resource. IAM operates on a "deny by default" model: if a user or service does not have an explicitly granted permission for an action, that action is blocked.
1.1. Permission Structure#
Each permission is represented as a string consisting of three parts separated by dots:
<service_name>.<resource_name>.<action>
-
<service_name>:- A unique identifier for a service or module in your system
- Examples:
billing,compute,auth,storage
-
<resource_name>:- Defines the type of object an action can be performed on
- Expressed in the singular form
- Examples:
account,vm,user,policy
-
<action>:- Defines the operation that can be performed on the specified resource
- Examples:
read,write,create,delete,activate
Permission examples:
billing.account.read— view account information in the billing servicecompute.vm.create— create a new virtual machine in the compute serviceauth.user.deactivate— deactivate a user in the authentication service
You can also use * (wildcard) in any of the three parts. It means all values are allowed in that part.
How * works by part:
*in the first part (service_name) — access for all services*in the second part (resource_name) — access for all resources in the selected service*in the third part (action) — access for all actions on the selected resource
Wildcard permission examples:
*.vm.read— allows readingvmin all servicescompute.*.read— allows reading any resource in thecomputeservicecompute.vm.*— allows any action onvmin thecomputeservice*.*.*— full access to all services, resources, and actions
1.2. Security Model: "Deny by Default"#
An important IAM philosophy is the principle of explicit permission:
- Initially, any user or service account has no access rights
- To perform any action, the subject must be granted the corresponding permission
- Services integrated with IAM must check for the required permission before executing an operation
1.3. Permissions API Examples#
Create a Permission#
POST /v1/iam/permissions/
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "compute.vm.create",
"description": "Permission to create a virtual machine"
}
Response#
{
"uuid": "5a1b2c3d-4e5f-6789-abcd-ef0123456789",
"name": "compute.vm.create",
"description": "Permission to create a virtual machine",
"created_at": "2025-08-21T07:38:04.778680Z",
"updated_at": "2025-08-21T07:38:04.778688Z",
"status": "ACTIVE"
}
Get a Permission#
GET /v1/iam/permissions/5a1b2c3d-4e5f-6789-abcd-ef0123456789
Authorization: Bearer <token>
Filter Permissions#
GET /v1/iam/permissions/?name=compute.vm.create&status=ACTIVE
Authorization: Bearer <token>
2. Roles#
A Role is a named collection of Permissions. While a Permission defines the right for one specific action, a Role groups these rights into logical blocks corresponding to job functions, responsibilities, or the access level of a user or service.
2.1. Permission Binding: Linking Roles and Permissions#
To assign permissions to a role, the Permission Binding entity is used. This entity establishes a many-to-many relationship between roles and permissions.
- One Permission can be bound to several different roles
- One Role can contain many different permissions
Example:
- The
BillingViewerrole receives the following via Permission Binding:billing.account.readbilling.invoice.read
- The
BillingOperatorrole receives the following via Permission Binding:billing.account.readbilling.invoice.readbilling.invoice.pay
2.2. Role Binding: Assigning Roles to Users#
To grant a user access, a role must be assigned to them. The Role Binding entity is used for this purpose. This entity establishes a many-to-many relationship between users and roles.
- One user can be assigned several roles
- One role can be assigned to many users
2.3. Final Access Model#
The access verification process:
- A User calls a service with a token
- The Service calls IAM token introspection
- The service gets the list of permissions available for this token from the introspection response
- The Service checks whether the required permission exists for the requested action
- If the permission is present, access is granted
2.4. Roles API Examples#
Create a Role#
POST /v1/iam/roles/
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "BillingOperator",
"description": "Billing operator with rights to manage accounts"
}
Response#
{
"uuid": "6b2c3d4e-5f67-789a-bcde-f01234567890",
"name": "BillingOperator",
"description": "Billing operator with rights to manage accounts",
"created_at": "2025-08-21T07:38:04.779416Z",
"updated_at": "2025-08-21T07:38:04.779424Z",
"status": "ACTIVE",
"project_id": null
}
Create a Permission Binding#
POST /v1/iam/permission_bindings/
Content-Type: application/json
Authorization: Bearer <token>
{
"role": "6b2c3d4e-5f67-789a-bcde-f01234567890",
"permission": "5a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
Create a Role Binding#
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 User Roles#
GET /v1/iam/users/7c3d4e5f-6789-89ab-cdef-123456789012/actions/get_my_roles
Authorization: Bearer <token>
2.5. Projects and Role/Permission Scope#
In IAM, roles can be assigned as:
- Global (without project,
project = null) - Project-scoped (via the
projectfield inRole Binding)
This directly affects the effective permission set in a token.
When issuing a token, IAM determines the project from scope:
project:<uuid>— token is bound to the specified projectproject:default— token is bound to the user's default project- if no
project:...segment is present inscope, the token is issued without project (project = null)
During introspection, IAM returns permissions only in the context of the token's project. In other words, the effective permission set depends on which project the token is issued for.
Important:
getting a token without project does not automatically grant access to all projects.
Such token includes only permissions valid in project = null context (global assignments) and does not include project-scoped assignments from other projects.
2.6. How Services Should Check Permissions (Practical Template)#
Below is a recommended integration model for a business service with IAM.
Basic flow#
- Service receives a user token (
Authorization: Bearer ...) - Service calls IAM token introspection endpoint
- Service gets the permission list from introspection for the current token
- Before each protected action, service checks that required permission is present
- If permission is missing, service returns
403 Forbidden
Minimal service code structure#
class IamClient:
def introspect(self, token: str) -> dict:
# HTTP GET /v1/iam/clients/<client_uuid>/actions/introspect/invoke
# with 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/decorator for permission checks#
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
Endpoint example#
@require_permission("compute.vm.create")
def create_vm(request):
payload = request.json
# VM creation business logic
return {"status": "ok"}, 201
Context initialization in 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 # continue
Practical recommendations#
- Check permissions as close as possible to action execution point (endpoint/use-case)
- Do not infer rights in the service — IAM must stay the source of truth
- Only short-lived server-side cache for introspection response is acceptable; do not cache permissions on the client side
- Log access denials with required permission and user/token context
3. Best Practices#
3.1. Principle of Least Privilege#
Create roles that provide exactly the level of access required to perform a task, and nothing more.
3.2. Semantic Naming#
Give roles and permissions clear names that reflect their purpose:
- Roles:
NetworkReadOnly,DatabaseSuperUser - Permissions:
compute.vm.read,storage.bucket.delete
3.3. Regular Audits#
Periodically review:
- Which roles are assigned to whom
- Which permissions are included in roles
- Remove unnecessary access promptly
3.4. Using Projects for Isolation#
Use project-scoped Role Binding to isolate access between environments. Detailed project-context behavior is described in section 2.5.
4. Error Handling#
The following errors may occur when working with the IAM API:
4.1. Access Error (403 Forbidden)#
{
"status": 403,
"json": {
"code": 403,
"type": "PermissionDeniedException",
"message": "User does not have required permission: compute.vm.create"
}
}
4.2. Not Found (404 Not Found)#
{
"status": 404,
"json": {
"code": 404,
"type": "NotFoundException",
"message": "Role with uuid 6b2c3d4e-5f67-789a-bcde-f01234567890 not found"
}
}
4.3. Bad Request (400 Bad Request)#
{
"status": 400,
"json": {
"code": 400,
"type": "ValidationErrorException",
"message": "Field 'name' must be between 0 and 255 characters"
}
}
5. Important Notes#
- All changes to permissions and role bindings take effect immediately
- Do not cache permissions on the client side; if caching is needed, use only short-lived server-side introspection cache
- For service accounts, use separate roles with the minimum required permissions
- Regularly update and review role assignments within the system