Assign user access
This guide assigns roles to a site user. To give organization members access to a site, use organization members instead.
Console-only site access#
Organization membership and site access for members are managed only in Console, on the organization's Members and Invitations screens. The role changes below apply to site users.
Assign and revoke roles#
Before you begin#
Confirm the username and role slug exist in the selected site. taruvi below
is your configured JavaScript client; client is
your configured synchronous Python client.
Assigning or revoking roles needs organization access to the site: an
organization owner, admin, or member, or an API key one of them created. Anyone
else, including a site user with a Super Admin app role, gets 403 FORBIDDEN.
One request takes up to 100 roles and 100 usernames.
Use Site roles to create or change a Site Role; this page only assigns or revokes existing roles.
Choose the assignment duration#
- Permanent assignment: Omit
expires_at. The membership has no expiry. - Expiring assignment: Supply a future ISO 8601 timestamp in
expires_at. The same timestamp applies to every newly created username and role pair in that request.
The API rejects an expires_at value in the past. An active membership has no
expires_at value or one later than the current time. After it expires, the
membership record remains, but active role and app-access reads exclude it.
An existing username and role pair is skipped and counted as a success; the skip leaves its expiry unchanged. Confirm the intended expiry before creating the assignment — assigning the same role again doesn't change it.
In TaruviBase Console, use the site's Users screen. In code, use the SDK calls below. These examples create one permanent assignment and one expiring assignment, then revoke the permanent assignment:
- JavaScript SDK
- Python SDK
import {User} from '@taruvi/sdk';
const users = new User(taruvi);
await users.assignRoles({
roles: ["support-viewer"],
usernames: ["onboarding-user"],
});
await users.assignRoles({
roles: ["support-viewer"],
usernames: ["temporary-user"],
expires_at: "2027-01-31T23:59:59Z",
});
await users.revokeRoles({
roles: ["support-viewer"],
usernames: ["onboarding-user"],
});
client.users.assign_roles(
roles=["support-viewer"], usernames=["onboarding-user"]
)
client.users.assign_roles(
roles=["support-viewer"],
usernames=["temporary-user"],
expires_at="2027-01-31T23:59:59Z",
)
client.users.revoke_roles(
roles=["support-viewer"], usernames=["onboarding-user"]
)
Replace the example expiry with a future ISO 8601 timestamp that matches the
intended access window. To make an assignment permanent, leave out
expires_at.
/api/assign/roles/Headers
AuthorizationApi-Key $TARUVI_API_KEYContent-Typeapplication/json
Request body
{
"roles": [
"$TARUVI_ROLE_SLUG"
],
"usernames": [
"$TARUVI_USERNAME"
]
}
View cURL
curl -X POST "$TARUVI_SITE_URL/api/assign/roles/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<JSON
{
"roles": [
"$TARUVI_ROLE_SLUG"
],
"usernames": [
"$TARUVI_USERNAME"
]
}
JSON
200
/api/revoke/roles/Headers
AuthorizationApi-Key $TARUVI_API_KEYContent-Typeapplication/json
Request body
{
"roles": [
"$TARUVI_ROLE_SLUG"
],
"usernames": [
"$TARUVI_USERNAME"
]
}
View cURL
curl -X DELETE "$TARUVI_SITE_URL/api/revoke/roles/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<JSON
{
"roles": [
"$TARUVI_ROLE_SLUG"
],
"usernames": [
"$TARUVI_USERNAME"
]
}
JSON
200
Assignment can return HTTP 200 with data.failures for individual username
and role pairs. Revocation can also return HTTP 200 with data.failures.
Successful pairs remain applied in either partial result. Re-read the user's
roles and app access, record each failed username and role, correct the
selected site, slug, username, or expiry, then retry only those failed pairs.
A full success has status and message and no data. In JavaScript SDK
1.5.4, RolesResponse types this, so read the failures directly:
- JavaScript SDK
- Python SDK
import {User} from '@taruvi/sdk';
const users = new User(taruvi);
const result = await users.assignRoles({
roles: ["support-viewer"],
usernames: ["onboarding-user", "temporary-user"],
});
for (const {username, role, error} of result.data?.failures ?? []) {
console.warn(`Couldn't assign ${role} to ${username}: ${error}`);
}
result = client.users.assign_roles(
roles=["support-viewer"],
usernames=["onboarding-user", "temporary-user"],
)
for failure in (result.get("data") or {}).get("failures", []):
print(failure["username"], failure["role"], failure["error"])
For other problems, see troubleshooting.
Verify active access#
Re-read the user and available apps after an assignment:
- JavaScript SDK
- Python SDK
- Refine
import {User} from '@taruvi/sdk';
const users = new User(taruvi);
await users.getUser("temporary-user");
await users.getUserApps("temporary-user");
client.users.get("temporary-user")
client.users.apps("temporary-user")
Register userDataProvider(taruvi) as user using the
Refine setup. Read the
assigned roles and apps after the assignment:
import {useList} from '@refinedev/core';
import type {UserApp, UserRole} from '@taruvi/sdk';
useList<UserRole>({
dataProviderName: 'user', resource: 'roles',
meta: {username: 'temporary-user'}, pagination: {mode: 'off'},
});
useList<UserApp>({
dataProviderName: 'user', resource: 'apps',
meta: {username: 'temporary-user'}, pagination: {mode: 'off'},
});
Each hook returns its list in result.data. Use the hook's query.refetch()
to repeat the read after a revocation or expiry.
Confirm the expected role appears in the user read and the expected app appears
in the app read. After expires_at, repeat both reads and confirm the expired
membership no longer contributes roles or app access.
/api/users/$TARUVI_USERNAME/apps/Headers
AuthorizationApi-Key $TARUVI_API_KEY
View cURL
curl "$TARUVI_SITE_URL/api/users/$TARUVI_USERNAME/apps/" \
-H "Authorization: Api-Key $TARUVI_API_KEY"
200
Assigning a role doesn't guarantee the user can do what you expect. Use Test access decisions to check an allowed case and a denied case for the intended resource and action.