Velocity • Durability

6. Tenant Users and Roles

6.1 Tenant Users

Endpoint Summary

Path Summary Method
/api/v1/tenants/{tenant_id}/users List tenant users GET
/api/v1/tenants/{tenant_id}/users Create tenant user POST
/api/v1/tenants/{tenant_id}/users/{user_id} Get tenant user GET
/api/v1/tenants/{tenant_id}/users/{user_id} Update tenant user PATCH
/api/v1/tenants/{tenant_id}/users/{user_id} Delete tenant user DELETE

GET /api/v1/tenants/{tenant_id}/users

List tenant users

Return all users that belong to the specified tenant. The response includes a total count field. Tenant Admins can only list users within their own tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).

Responses

Status Description Schema
200 Tenant users retrieved successfully. UserListResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, UserListResponse)

Field Type Required Default Example Description
total integer yes n/a 0, 5, 50 Total count of Tenant Users in this response.
users array of User object no n/a Array of Tenant User objects. Empty array if no users found.

Example

{
   "total" : 1,
   "users" : [
      {
         "auth_settings" : {
            "auth_mode" : "local"
         },
         "created_at" : "2026-01-01T00:00:00Z",
         "display_name" : "Alice Anderson",
         "email" : "alice@fintech.example.com",
         "id" : "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
         "updated_at" : "2026-01-01T00:00:00Z",
         "username" : "alice"
      }
   ]
}

POST /api/v1/tenants/{tenant_id}/users

Create tenant user

Create a new tenant user within the specified tenant. The name must be unique within the tenant. The password is hashed server-side; the plaintext value is never stored.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).

Request Body (application/json, required)

Schema: UserCreateRequest

Request payload for creating a Tenant User.

The password is hashed server-side before storage; the plaintext value is never persisted. The name must be unique within the tenant.

Field Type Required Default Example Description
auth_settings LocalAuthSettings object or PamAuthSettings object yes n/a {"auth_mode":"local"}, {"auth_mode":"pam","service":"login"} Authentication backend for this user, discriminated on auth_mode.
display_name string, nullable no null Alice Anderson Human-readable full name. Optional; username remains the unique handle.
email string, nullable no null alice@fintech.example.com Optional contact email for the Tenant User.
password string (password) yes n/a Tenant User password (min 8 characters). Hashed server-side before storage.
username string yes n/a alice Tenant User username. Must be unique within the tenant. Whitespace, control and invisible characters are not allowed.

Example

{
   "auth_settings" : {
      "auth_mode" : "local"
   },
   "display_name" : "Alice Anderson",
   "email" : "alice@fintech.example.com",
   "password" : "secure-password",
   "username" : "alice"
}

Responses

Status Description Schema
201 Tenant user created successfully. UserCreateResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
409 Conflict. A user with this username already exists in the target tenant. -
422 Validation error. -
500 Internal server error. -

Response Body (201, UserCreateResponse)

Field Type Required Default Example Description
id string (uuid) yes n/a a1b2c3d4-e5f6-7890-abcd-ef1234567890 Unique Tenant User identifier (UUID) assigned by the system.

Example

{
   "id" : "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

GET /api/v1/tenants/{tenant_id}/users/{user_id}

Get tenant user

Retrieve a specific tenant user by ID. Returns 404 if the user does not exist or belongs to a different tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).
user_id path string (uuid) yes Tenant user identifier (UUID).

Responses

Status Description Schema
200 Tenant user retrieved successfully. GetUserResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant user not found. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, GetUserResponse)

Field Type Required Default Example Description
user User object yes n/a Tenant User entity with all available details.

Example

{
   "user" : {
      "auth_settings" : {
         "auth_mode" : "local"
      },
      "created_at" : "2026-01-01T00:00:00Z",
      "display_name" : "Alice Anderson",
      "email" : "alice@fintech.example.com",
      "id" : "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "updated_at" : "2026-01-01T00:00:00Z",
      "username" : "alice"
   }
}

PATCH /api/v1/tenants/{tenant_id}/users/{user_id}

Update tenant user

Apply a partial update to the specified tenant user: set a new password, change the authentication backend (auth_settings), update the email and/or the display_name. At least one field must be supplied. This is an administrative operation - the caller does not need to supply the current password. Returns 400 if a password change is requested for a user whose resulting auth mode is not local. Returns 404 if the user does not exist or belongs to a different tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).
user_id path string (uuid) yes Tenant user identifier (UUID).

Request Body (application/json, required)

Schema: UserPatchRequest

Request payload for updating a Tenant User.

Allows partial updates of new_password, auth_settings, email and/or display_name; at least one must be supplied. Administrative operation - the caller does not need to supply the current password. Intended for Tenant Admin or Platform Admin use only.

Field Type Required Default Example Description
auth_settings LocalAuthSettings object or PamAuthSettings object, nullable no null {"auth_mode":"local"}, {"auth_mode":"pam","service":"login"} Updated authentication backend for this user, discriminated on auth_mode.
display_name string, nullable no null Alice Anderson Updated human-readable full name for the Tenant User.
email string, nullable no null alice@fintech.example.com Updated contact email for the Tenant User.
new_password string (password), nullable no null New password for the Tenant User (min 8 characters). Hashed server-side before storage.

Responses

Status Description Schema
204 Password updated successfully. -
400 Bad request. A password change was requested for a user whose auth mode is not ‘local’. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant user not found. -
422 Validation error. Password does not meet minimum length requirement. -
500 Internal server error. -

DELETE /api/v1/tenants/{tenant_id}/users/{user_id}

Delete tenant user

Permanently delete a tenant user by ID, together with everything that would still authenticate as it: the API tokens it holds and its role bindings. Returns 404 if the user does not exist or belongs to a different tenant. Returns 409 for the Platform Admin, which cannot be deleted by any caller. Tenant Admins can only delete users within their own tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).
user_id path string (uuid) yes Tenant user identifier (UUID).

Responses

Status Description Schema
204 Tenant user deleted successfully. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant user not found. -
409 Conflict. The user is protected and cannot be deleted through the API. -
422 Validation Error HTTPValidationError
500 Internal server error. -

6.2 Tenant User Roles

Endpoint Summary

Path Summary Method
/api/v1/tenants/{tenant_id}/users/{user_id}/roles List tenant user roles GET
/api/v1/tenants/{tenant_id}/users/{user_id}/roles Set tenant user roles PATCH

GET /api/v1/tenants/{tenant_id}/users/{user_id}/roles

List tenant user roles

Returns the RBAC roles assigned to a tenant user.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).
user_id path string (uuid) yes Tenant user identifier (UUID).

Responses

Status Description Schema
200 User roles retrieved successfully. RolesResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant user not found. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, RolesResponse)

Field Type Required Default Example Description
roles array of string yes n/a ["admin"] Roles currently bound to the principal.

PATCH /api/v1/tenants/{tenant_id}/users/{user_id}/roles

Set tenant user roles

Replaces the RBAC roles assigned to a tenant user. The roles of a protected user cannot be changed through the API, and the request is refused with 409.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).
user_id path string (uuid) yes Tenant user identifier (UUID).

Request Body (application/json, required)

Schema: SetRolesRequest

Request payload for replacing the full role set of a Tenant User.

Field Type Required Default Example Description
roles array of string yes n/a ["admin"] Roles to assign to the user; replaces the current set. A role the target tenant does not define, or a reserved one, is rejected with HTTP 400.

Responses

Status Description Schema
200 User roles retrieved successfully. RolesResponse
400 Bad request. A requested role is not defined by the tenant’s RBAC policy. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant user not found. -
409 Conflict. The request conflicts with the current state of the resource. -
422 Validation error. -
500 Internal server error. -

Response Body (200, RolesResponse)

Field Type Required Default Example Description
roles array of string yes n/a ["admin"] Roles currently bound to the principal.