Manage users and roles
Automate user administration for your Elastio tenant: find users, add and invite new ones, disable leavers, and organise access with user groups, account groups and role assignments.
Before you begin
Section titled “Before you begin”- These operations live under
/rbac/api/v1/…. Use a token issued by a tenant admin with theadmincategory (writefor any change). See Automate personal access tokens. - Every user has a built-in
roleofadminorviewer, and astatusofactive,disabledorinvited. - Separately, the tenant can define named roles (
/rbac/api/v1/roles) and assign them to users. User groups apply a role to a set of users, and account groups bundle cloud accounts (byaccount_idandprovider_type) so access can be scoped to them.
Find users
Section titled “Find users”List users, optionally filtered with q (matches email, name, status or role). Deleted users are excluded unless you pass status=all. For a dedicated free-text search, use GET /rbac/api/v1/users/search?search_query=….
curl -G "https://acme.app.elastio.com/rbac/api/v1/users" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ --data-urlencode "q=viewer"import os, requests
BASE = "https://acme.app.elastio.com"HEADERS = {"Authorization": f"Bearer {os.environ['ELASTIO_TOKEN']}"}
resp = requests.get(f"{BASE}/rbac/api/v1/users", headers=HEADERS, timeout=30)resp.raise_for_status()users = resp.json() # a plain array, no paginationpending = [u["email"] for u in users if u["status"] == "invited"]print("Invitations not yet accepted:", pending)$Base = "https://acme.app.elastio.com"$Headers = @{ Authorization = "Bearer $env:ELASTIO_TOKEN" }Invoke-RestMethod -Uri "$Base/rbac/api/v1/users?q=viewer" -Headers $Headers | Format-Table email, role, status, last_logged_inThe response is an array of users:
[ { "id": "5e8f9a10-1111-4222-8333-444455556666", "email": "jane.doe@example.com", "last_logged_in": "2026-10-11T08:12:44Z", "status": "active", "role": "viewer", "user_groups": ["SOC analysts"], "account_groups": ["Production AWS"] }, { "id": "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b", "email": "new.hire@example.com", "last_logged_in": null, "status": "invited", "role": "viewer", "user_groups": [], "account_groups": [] }]Add a user and resend an invitation
Section titled “Add a user and resend an invitation”Create a user with an email address, built-in role and optional groups. The request schema marks id (a UUID) as required; the spec doesn’t describe how this value is assigned, so check the reference for your tenant’s behaviour. Groups can be passed as user_groups_ids, userGroups and accountGroups arrays.
curl -X POST "https://acme.app.elastio.com/rbac/api/v1/users" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "id": "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b", "email": "new.hire@example.com", "role": "viewer", "user_groups_ids": ["2c4e6a80-1b3d-4f5a-8c7e-9d0f1a2b3c4d"] }'body = { "id": "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b", "email": "new.hire@example.com", "role": "viewer", "user_groups_ids": ["2c4e6a80-1b3d-4f5a-8c7e-9d0f1a2b3c4d"],}resp = requests.post(f"{BASE}/rbac/api/v1/users", headers=HEADERS, json=body, timeout=30)resp.raise_for_status()print(resp.json()) # {"status": "ok"}$Body = @{ id = "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b" email = "new.hire@example.com" role = "viewer" user_groups_ids = @("2c4e6a80-1b3d-4f5a-8c7e-9d0f1a2b3c4d")} | ConvertTo-JsonInvoke-RestMethod -Method Post -Uri "$Base/rbac/api/v1/users" -Headers $Headers ` -ContentType "application/json" -Body $Body{ "status": "ok" }If a user still shows status: "invited", send the invitation email again:
curl -X POST "https://acme.app.elastio.com/rbac/api/v1/users/resend-invite" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email_address": "new.hire@example.com" }'resp = requests.post(f"{BASE}/rbac/api/v1/users/resend-invite", headers=HEADERS, json={"email_address": "new.hire@example.com"}, timeout=30)resp.raise_for_status()Invoke-RestMethod -Method Post -Uri "$Base/rbac/api/v1/users/resend-invite" -Headers $Headers ` -ContentType "application/json" -Body (@{ email_address = "new.hire@example.com" } | ConvertTo-Json)Disable and re-enable users
Section titled “Disable and re-enable users”Disable one or many users in a single call by sending a JSON array of user IDs. The response reports a status per user. PATCH /rbac/api/v1/users/enable takes the same body to restore access.
curl -X PATCH "https://acme.app.elastio.com/rbac/api/v1/users/disable" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '["5e8f9a10-1111-4222-8333-444455556666", "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b"]'# Disable everyone whose email is on the leavers listleavers = {"jane.doe@example.com", "new.hire@example.com"}users = requests.get(f"{BASE}/rbac/api/v1/users", headers=HEADERS, timeout=30).json()ids = [u["id"] for u in users if u["email"] in leavers and u["status"] != "disabled"]
if ids: resp = requests.patch(f"{BASE}/rbac/api/v1/users/disable", headers=HEADERS, json=ids, timeout=30) resp.raise_for_status() for result in resp.json(): print(result["user_id"], result["status"])$Ids = @("5e8f9a10-1111-4222-8333-444455556666", "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b")Invoke-RestMethod -Method Patch -Uri "$Base/rbac/api/v1/users/disable" -Headers $Headers ` -ContentType "application/json" -Body (ConvertTo-Json -InputObject $Ids)[ { "user_id": "5e8f9a10-1111-4222-8333-444455556666", "status": "…" }, { "user_id": "9d1c2b3a-4e5f-4061-8a7b-8c9d0e1f2a3b", "status": "…" }]Organise access with groups and roles
Section titled “Organise access with groups and roles”Create a user group
Section titled “Create a user group”A user group gives every member the same built-in role and can be linked to account groups. name and role are required; add members with users_ids (or userIds), or by email with users_emails.
curl -X POST "https://acme.app.elastio.com/rbac/api/v1/userGroups" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "SOC analysts", "description": "Read-only access for the security operations team", "role": "viewer", "users_emails": ["jane.doe@example.com"], "account_groups_ids": ["7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d"] }'body = { "name": "SOC analysts", "description": "Read-only access for the security operations team", "role": "viewer", "users_emails": ["jane.doe@example.com"], "account_groups_ids": ["7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d"],}resp = requests.post(f"{BASE}/rbac/api/v1/userGroups", headers=HEADERS, json=body, timeout=30)resp.raise_for_status()group = resp.json()$Body = @{ name = "SOC analysts" description = "Read-only access for the security operations team" role = "viewer" users_emails = @("jane.doe@example.com") account_groups_ids = @("7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d")} | ConvertTo-JsonInvoke-RestMethod -Method Post -Uri "$Base/rbac/api/v1/userGroups" -Headers $Headers ` -ContentType "application/json" -Body $BodyThe response is 201 with the group and its members:
{ "id": "2c4e6a80-1b3d-4f5a-8c7e-9d0f1a2b3c4d", "name": "SOC analysts", "description": "Read-only access for the security operations team", "role": "viewer", "user_ids": ["5e8f9a10-1111-4222-8333-444455556666"], "users": [ { "id": "5e8f9a10-1111-4222-8333-444455556666", "email": "jane.doe@example.com", "role": "viewer" } ], "account_groups_names": ["Production AWS"]}Account groups referenced above are created with POST /rbac/api/v1/accountGroups, which takes a name, optional description and an accounts array of {account_id, provider_type} objects. provider_type is one of aws, ova, azure, ibm or gcp.
Assign a role to a user
Section titled “Assign a role to a user”List the tenant’s roles with GET /rbac/api/v1/roles (or create one with POST /rbac/api/v1/roles, which takes name and optional description), then assign it by role_id.
curl -X POST "https://acme.app.elastio.com/rbac/api/v1/users/5e8f9a10-1111-4222-8333-444455556666/roles" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "role_id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f" }'user_id = "5e8f9a10-1111-4222-8333-444455556666"roles = requests.get(f"{BASE}/rbac/api/v1/roles", headers=HEADERS, timeout=30).json()role_id = next(r["id"] for r in roles if r["name"] == "Incident responders")
resp = requests.post(f"{BASE}/rbac/api/v1/users/{user_id}/roles", headers=HEADERS, json={"role_id": role_id}, timeout=30)resp.raise_for_status()
# Confirmprint(requests.get(f"{BASE}/rbac/api/v1/users/{user_id}/roles", headers=HEADERS, timeout=30).json())$UserId = "5e8f9a10-1111-4222-8333-444455556666"$Role = Invoke-RestMethod -Uri "$Base/rbac/api/v1/roles" -Headers $Headers | Where-Object name -eq "Incident responders"Invoke-RestMethod -Method Post -Uri "$Base/rbac/api/v1/users/$UserId/roles" -Headers $Headers ` -ContentType "application/json" -Body (@{ role_id = $Role.id } | ConvertTo-Json){ "status": "ok" }GET /rbac/api/v1/users/{userId}/roles returns the user’s roles:
[ { "id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f", "name": "Incident responders", "description": null, "created_at": "2026-09-01T12:00:00Z", "updated_at": "2026-09-01T12:00:00Z" }]All endpoints
Section titled “All endpoints”Users
15 operations in the reference →- GET
/rbac/api/v1/usersList all users - POST
/rbac/api/v1/usersCreate a new user - POST
/rbac/api/v1/users/byIdsGet user objects by ID list (bulk) - PATCH
/rbac/api/v1/users/disableDisable one or many users by ID - PATCH
/rbac/api/v1/users/enableEnable one or many users by ID - PATCH
/rbac/api/v1/users/{id}Update user attributes - DELETE
/rbac/api/v1/users/{id}Delete a user - GET
/rbac/api/v1/users/{id}/roleGet user's current role - GET
/rbac/api/v1/users/roleGet current authenticated user's role - POST
/rbac/api/v1/users/resend-inviteResend an invitation email - GET
/rbac/api/v1/users/searchSearch users by free‑text query - GET
/rbac/api/v1/users/{userId}Get a specific user by ID - GET
/rbac/api/v1/users/{userId}/rolesList roles for a user - POST
/rbac/api/v1/users/{userId}/rolesAssign role to user - DELETE
/rbac/api/v1/users/{userId}/roles/{roleId}Revoke role from user
User Groups
7 operations in the reference →- GET
/rbac/api/v1/userGroupsList user groups - POST
/rbac/api/v1/userGroupsCreate a user group - POST
/rbac/api/v1/userGroups/byIdsGet user groups by IDs (bulk) - PATCH
/rbac/api/v1/userGroups/{id}Update a user group - DELETE
/rbac/api/v1/userGroups/{id}Delete a user group - GET
/rbac/api/v1/userGroups/searchSearch user groups - GET
/rbac/api/v1/userGroups/{userGroupId}Get a specific user group by ID
Roles
5 operations in the reference →Account Groups
8 operations in the reference →- GET
/rbac/api/v1/accountGroupsList account groups - POST
/rbac/api/v1/accountGroupsCreate an account group - POST
/rbac/api/v1/accountGroups/byIdsGet account groups by IDs (bulk) - PATCH
/rbac/api/v1/accountGroups/{id}Update an account group - DELETE
/rbac/api/v1/accountGroups/{id}Delete an account group - GET
/rbac/api/v1/accountGroups/searchSearch account groups - GET
/rbac/api/v1/accounts/{id}Get raw cloud account ID mapping for an Elastio account group - GET
/rbac/api/v1/accountGroups/{accountGroupId}Get a specific account group by ID