User Management
Tursio provides user management with a clear access control hierarchy.
- Admins:
- Hold the highest level of authority.
- Only admins can add new owners, ensuring restricted elevation of privileges.
- Owners:
- Can view both owners and users.
- Can add or delete users but cannot add new owners.
- Users:
- Have limited rights and cannot access the User Management page.
- Focused on consuming data and executing queries.
This role-based model ensures governance, accountability, and restricted access to sensitive controls. Each user is associated with a name, email, role (Owner, Admin, User), and the date they were added. Users can authenticate using Microsoft or Google login. Alternatively, admins or owners can assign license keys (more on this below).

Add User

Owners and admins can add a new user by providing a name, email, and role. Roles can be selected from a predefined list (Owner, Admin, User) according to the hierarchy rules. Once submitted, the user is added to the database with the selected role and tracked in the system.
Owners and admins can also remove users as needed. The Access Control tab provides additional configuration to govern permissions — specifically, controlling which datasets each user can see.
Note
The User role does not grant access to any dataset by default. The Admin or tenant Owner must explicitly add the relevant dataset in access control for the user to see it.
License Keys
License keys provide an alternative way to log in to the system. This is helpful when authorized users are unable to sign in via Microsoft or Google login.

A license key is generated when assigning an access level (Owner, Admin, or User). Each license shows the access role, email, the key itself, and its validity date. Only one active license can exist per user at any time. This ensures compliance, traceability, and controlled usage across the organization.
Cleanup
Tursio does not allow removing users from the portal for audit reasons — admins should be able to trace back who has ever had access to the data. For accidental user creation and cleanup purposes, the steps below are provided.
Save the following user deletion SQL script into a file named user_delete.sql.
BEGIN;
DO $$
DECLARE
uids bigint[];
BEGIN
-- 1. Collect IDs of ALL soft-deleted users
SELECT array_agg(id)
INTO uids
FROM "public"."User"
WHERE deleted IS NOT NULL;
IF uids IS NULL OR array_length(uids, 1) IS NULL THEN
RAISE NOTICE 'No soft-deleted users found.';
RETURN;
END IF;
RAISE NOTICE 'Found % soft-deleted users. IDs: %', array_length(uids, 1), uids;
-- 2. Delete from AccountUserAccessControl
DELETE FROM "public"."AccountUserAccessControl"
WHERE "user" = ANY(uids);
-- 3. Delete from ConnectionUserAccessControl
DELETE FROM "public"."ConnectionUserAccessControl"
WHERE "user" = ANY(uids);
-- 4. Delete from UserAccessToken
DELETE FROM "public"."UserAccessToken"
WHERE "user" = ANY(uids);
-- 5. Delete from Login
DELETE FROM "public"."Login"
WHERE "user" = ANY(uids);
-- 6. Delete from User
DELETE FROM "public"."User"
WHERE id = ANY(uids);
RAISE NOTICE 'Bulk hard delete completed for % user(s).', array_length(uids, 1);
END $$;
COMMIT;
Save the following driver script into a file named run_user_delete.sh.
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "Usage: bash run_user_delete.sh \"username\""
exit 1
fi
USERNAME="$1"
# SQL file must be present
if [ ! -f user_delete.sql ]; then
echo "❌ Missing user_delete.sql file"
exit 1
fi
echo "✔ Updating username inside WHERE clause to \"$USERNAME\"..."
# Replace ANY existing username in WHERE name = '...'
sed "s/WHERE[[:space:]]\+name[[:space:]]*=[[:space:]]*'[^']*'/WHERE name = '$USERNAME'/" \
user_delete.sql > user_delete_runtime.sql
# Detect Postgres container (port 5432)
CID=$(docker ps -q --filter "publish=5432")
if [ -z "$CID" ]; then
echo "❌ Could not find Postgres container"
exit 1
fi
echo "✔ Found Postgres container: $CID"
# Copy runtime SQL
echo "✔ Copying SQL to container..."
docker cp user_delete_runtime.sql "$CID":/tmp/user_delete.sql
# Open psql shell
echo "✔ Opening psql shell..."
docker exec -it "$CID" psql -U postgres
Now run the following command, replacing the username placeholder with the actual username:
bash run_user_delete.sh "<username>"
This detects the Postgres container, copies the SQL file into /tmp, and opens the psql shell inside the container. You should see the postgres=# prompt. Optionally, view all existing users inside psql:
SELECT id, name FROM "public"."User";
Run the deletion script inside psql:
\i /tmp/user_delete.sql
Verify both the user and login tables BEFORE committing:
SELECT * FROM "public"."User";
SELECT * FROM "public"."Login";
Commit if correct:
COMMIT;
Otherwise, rollback:
ROLLBACK;
If the prompt is stuck in an aborted state, run ROLLBACK; again until you return to postgres=#.
Once done, exit psql:
\q
The user management page provides a centralized interface to control who has access, at what level, and with what license validity. Combining it with role-based access control, license governance, transparent user visibility, and the ability to add or remove users, provides enterprise-grade security and operational clarity.