Vaulx uses a built-in user system backed by PostgreSQL. Admins can create and manage accounts directly from theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/noelzappy/vaulx/llms.txt
Use this file to discover all available pages before exploring further.
/admin/users panel, assigning one of three roles to each user. On first boot, the server automatically seeds a single admin account from environment variables so there is always a way in. Every user action that modifies an account — including role changes, deactivations, and password updates — is recorded in the audit log.
User model
Each user is stored in theusers table. The schema is defined in migrations/001_initial.up.sql:
| Field | Type | Notes |
|---|---|---|
id | UUID | Auto-generated primary key |
email | TEXT | Unique — login identifier |
name | TEXT | Display name shown in the sidebar |
role | TEXT | One of admin, editor, or viewer |
password_hash | TEXT | bcrypt hash at DefaultCost |
active | BOOLEAN | true by default; set false to block login |
created_at | TIMESTAMPTZ | Set automatically on insert |
Admin seeding on first boot
When the server starts and theusers table is empty, seed.AdminUser is called automatically. It reads SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD from the environment and creates a single admin account with the name "Admin". If either variable is missing, seeding is skipped with a log warning. On subsequent starts the seed is a no-op — it only runs when COUNT(*) = 0.
Change
SEED_ADMIN_PASSWORD to a strong, unique value before exposing Vaulx publicly. The seed step passes the password directly to bcrypt — no minimum-length check is enforced at seed time.Creating a user (admin only)
Open the admin panel
Navigate to
/admin/users. Only users with role = 'admin' can access this page; all others receive a 403 Access denied response.POST /admin/users
The user’s email address. Must be unique across all accounts.
The user’s display name shown in the UI.
One of
viewer, editor, or admin.| Role | Can do |
|---|---|
viewer | Browse and download files they have access to |
editor | Upload files, create/rename/soft-delete their own files and folders, create share links |
admin | Everything — manage users, hard-delete files, grant permissions, view audit log |
Plain-text password hashed with bcrypt
DefaultCost before storage. The server does not enforce a minimum length at this endpoint — use a strong password as a matter of practice.Listing users
Route:GET /admin/users
Admin-only. Returns an HTML page showing every account in the system ordered by created_at DESC, including each user’s email, display name, role, and active status. Non-admin requests receive 403.
Updating a user
Route:PATCH /admin/users/{userID}
Admins can update a user’s role, their active status, or both in a single request. Supply only the fields you want to change; omitted fields are left untouched. On success the response includes an HX-Trigger header that fires a showToast event with the message "User updated".
New role for the user. Must be one of
viewer, editor, or admin. Omit to leave the current role unchanged.Pass
"true" to re-enable a deactivated account or "false" to deactivate an active one. Omit to leave active status unchanged.Deactivating a user
Settingactive=false via PATCH /admin/users/{userID} immediately blocks the user from logging in. The GetUserByEmail query enforces active = true at the database level:
Profile self-service
Any authenticated user can view and update their own profile without admin involvement.- View profile
- Update display name
- Change password
Route:
GET /profileRenders the profile page showing the current user’s name, email, and role. Accepts an optional ?success=name or ?success=password query parameter to display a confirmation message after a successful update.All passwords are hashed with
bcrypt.GenerateFromPassword at bcrypt.DefaultCost before being written to the database. Plain-text passwords are never stored. The session cookie is refreshed after a successful name change so the sidebar reflects the update without a re-login.