User Management
SeqDesk has a deliberately small account model: two roles, self-service registration for researchers, and invite-only registration for admins. There is no per-feature permission matrix and no group system beyond departments. Understanding what that model does not include is as important as understanding what it does, because several operations administrators expect — changing a role, deactivating an account, reassigning a department — are not implemented in the application.
The two roles
A user’s role is a plain string column on the User record with the default
"RESEARCHER". Only two values are accepted anywhere in the application:
| Role | Granted by | What it can do |
|---|---|---|
RESEARCHER | Self-registration at /register | Create and manage their own sequencing orders, create studies, upload sample metadata, view results for their own data, open support tickets |
FACILITY_ADMIN | A valid invite code at /register/admin, or the installer’s bootstrap account | Everything a researcher can do, plus the entire admin area, every /api/admin/** route, visibility of all sequencing orders, launching pipelines, and registering data with ENA |
The check is uniform and blunt. Effectively every admin route begins with the same guard:
if (!session || session.user.role !== "FACILITY_ADMIN") {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}so anything under /api/admin/** answers 401 Unauthorized for a researcher,
and the admin pages redirect a researcher to /orders.
Ownership is enforced separately from the role. GET /api/orders/[id] returns
403 Forbidden when the caller is neither the owner nor a facility admin, and
the same rule applies to updating and deleting a sequencing order.
The role is baked into the NextAuth JWT at sign-in. If a role is ever changed directly in the database, the affected user keeps their old permissions until their session token is reissued — they must sign out and back in.
Researcher positions are not roles
Separately from the role, a researcher records a position in
researcherRole. It is descriptive metadata used for filtering and reporting;
it grants nothing.
| Stored value | Label on the registration form |
|---|---|
PI | Principal Investigator (PI) |
POSTDOC | Postdoctoral Researcher |
PHD_STUDENT | PhD Student |
MASTER_STUDENT | Master Student |
TECHNICIAN | Lab Technician |
OTHER | Other |
The Researchers page
Users → Researchers (/admin/users) is a read-only directory. It lists
accounts with the RESEARCHER role only — facility admins are managed on
Settings → Accounts instead.
- Search matches first name, last name, email, and department name
- All Departments and All Positions dropdowns filter the list; they are built from the values actually present, so an unused department never appears
- Sort by Researcher, Position, Department, Sequencing Orders, Studies, or Joined; clicking the active column flips the direction
- Clear resets search and both filters
Clicking a row opens that researcher’s profile (/admin/users/<id>) with their
contact details, department, and their ten most recent sequencing orders and
studies. This page is also read-only — it has no edit controls.
Researcher registration
Researchers create their own accounts. There is no admin-side “create user” form.
Open the registration page
The researcher goes to /register and picks Researcher on the first step.
Fill in the profile
The form collects first name, last name, email, password and confirmation, plus
optional department, position and institution. The department dropdown is
populated from GET /api/departments, which returns only active
departments, sorted by name.
Submit
The browser enforces a minimum password length of 8 characters and that the
two password fields match. On success the researcher is redirected to
/login?registered=true and can sign in immediately — there is no email
confirmation step and no admin approval queue.
Passwords are hashed with bcrypt at cost 12 before being stored.
Restricting who may register
The registration endpoint applies exactly one gate: the Account Validation module.
Enable the module
Go to Settings → Modules (/admin/modules) and turn on Account
Validation. It is off by default.
Configure the allowed domains
Add the email domains you accept, for example helmholtz-hzi.de and hzi.de.
Matching is on the full domain after the @, case-insensitively — hzi.de does
not match sub.hzi.de.
Choose enforcement
With enforcement on (the default for the module’s settings), a registration from
any other domain is rejected with
Registration is restricted to email addresses from: … and the code
INVALID_EMAIL_DOMAIN. With enforcement off, the registration succeeds and the
user is shown a warning instead.
An empty domain list allows every domain even while the module is enabled.
The auth.allowRegistration setting (environment variable
SEQDESK_AUTH_REGISTRATION) is accepted by the configuration
loader and reported under Info → Configuration sources, but
the registration route does not currently consult it. To actually close
registration, use the Account Validation module, or put the instance behind
an authenticating reverse proxy.
Admin registration
New facility admins cannot self-register. They need a single-use invite code issued by an existing admin.
Create the invite
On Settings → Accounts (/admin/admin-accounts), press Create Invite.
Optionally restrict it to one email address, and choose an expiry between
1 and 30 days (default 7). SeqDesk generates an 8-character uppercase
hexadecimal code such as A3F19C7B.
Share the code
The Pending Invites list offers a copy button for the raw code and one for the full registration link. Send it over a channel you trust; anyone holding an unrestricted code can create a full facility admin.
The recipient registers
They open /register/admin, enter the code (it is verified against
POST /api/admin/invites/verify before the form appears), then complete their
profile. The admin form’s minimum password length is 6 characters.
The invite is consumed
Creating the account and marking the invite used happen in one database transaction, so a code can never be redeemed twice. The invite moves from Pending Invites to Past Invites with the redeeming account attached.
Invite verification rejects, in this order: an unknown code
(Invalid invite code), an already-redeemed code
(This invite has already been used), an expired code
(This invite has expired), and — at registration time — a code restricted to a
different address (This invite is for a different email address).
Revoke deletes an unused invite outright. There is no way to revoke an invite that has already been redeemed; that would mean removing the admin account, which SeqDesk does not support (see below).
The first admin
The invite flow assumes an admin already exists. The very first one is created by the installer’s bootstrap seed, not by this page. See Installation for the bootstrap account and Reset Password if you lose access to it.
What SeqDesk does not do
These are common expectations that the application does not implement. Knowing them up front avoids a fruitless hunt through the admin screens.
| Operation | Status |
|---|---|
| Change a user’s role | Not available. /api/admin/users is GET-only and the profile page has no controls. |
| Deactivate or suspend an account | Not available. The User record has no active flag; isActive exists on Department, not on users. |
| Delete a user | Not available through the UI or API. |
| Reassign a user’s department | Not available. PUT /api/user/profile updates only first name, last name, phone and institution, and the admin profile page is read-only. The department is fixed at registration. |
| Reset another user’s password | Not available in the app. Use the server-side procedure in Reset Password. |
| Invite a researcher by email | Not available. Invites exist only for the FACILITY_ADMIN role. |
The practical consequence: treat department assignment as permanent and get departments right before you invite researchers, and treat an admin invite as irreversible once redeemed.
Access toggles that affect users
Two switches on Settings → Accounts change what researchers can see and do:
| Toggle | Stored as | Effect |
|---|---|---|
| Department Sharing | departmentSharing | Researchers see sequencing orders from everyone in their own department in the list view. Detailed behaviour and its limits are covered in Departments. |
| User Assembly Downloads | allowUserAssemblyDownload | Researchers may download final assemblies produced for their studies. |
Both are stored in the site settings record and are readable by any signed-in
user through GET /api/admin/settings/access, which returns only
allowUserAssemblyDownload to non-admins.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
User with this email already exists | Emails are unique across both roles | Sign in with the existing account, or use a different address |
Invalid department selected | The chosen department was deleted or deactivated between page load and submit | Reactivate it on Departments, or pick another |
Registration is restricted to email addresses from: … | Account Validation is enforcing a domain list | Add the domain, turn off enforcement, or register with an institutional address |
Admin registration requires an invite code | /register/admin was submitted without a code | Get a code from an existing admin |
| A new admin still sees the researcher view | The role lives in the session token | Sign out and back in |
| The Researchers list is empty but users exist | The page shows RESEARCHER accounts only | Facility admins are on Settings → Accounts |
An admin screen redirects to /orders | The signed-in account is not a facility admin | Check the role, then re-authenticate |
See also
- Departments — what department assignment changes, and why it should be set up first
- Administration overview — the full map of admin screens
- Installation — bootstrap admin credentials