Users and Roles
ZenPrint user management lives under Settings → Users (and the adjacent Roles tab). This page is the operational walkthrough; the Permissions reference has the full matrix.
Inviting a user
- Settings → Users → Create User.
- Fill in:
- Name
- Email (must be unique within the org)
- Role: pick from the three system roles or any custom role you’ve created
- Password: set an initial password for the user. Between 8 and 72 characters, with an uppercase letter, a lowercase letter, a number, and a symbol.
- Save. There’s no invite email yet, so share the tenant URL and the initial password through your normal MSP onboarding channel.
- The user logs in, is forced to enrol MFA, and is then live.
MFA
TOTP-based, enforced on first login. There’s no opt-out; MFA is required for everyone.
Until a user finishes enrolling, their account can’t do anything except enrol. That covers the API as well as the web pages, so an initial password on its own is never enough to act on your workspace.
Each 6-digit code works once. If you mistype and retry within the same 30-second window, wait for your authenticator to roll over to a fresh code rather than re-entering the one you just used.
Backup codes
You get ten single-use backup codes when you enrol. They’re shown once, so store them somewhere safe.
Enrolling again replaces the whole set, and resetting MFA (by an admin or from your Profile) invalidates every outstanding code. Any codes you wrote down before a reset stop working, so capture the new list each time you re-enrol.
What admin can do for a user:
- Unlock: clears the failed-login counter after a lockout (5 bad attempts locks the account for 30 minutes)
- Reset MFA: disconnects their authenticator app and invalidates their backup codes. They enrol again on next login. Use it when someone has lost access to their authenticator.
- Reset Password: sets a new strong password, signs the user out everywhere, and shows you the new password once to pass on to them
The user can also self-reset MFA via the Profile page if they’re logged in. A locked-out user can’t, of course, which is what admin-reset is for.
Disabling vs deleting
Two non-destructive options before you delete:
- Disable: login is blocked immediately and existing sessions are revoked. The user’s audit history stays intact. Re-enable any time to restore access.
- Delete: removes the user entirely.
On the Users page you can’t act on your own account (disable, delete, edit, change role, or reset). Manage your own password and MFA from your Profile instead.
The three system roles
Created automatically for every new tenant. They can’t be edited or deleted.
- Admin: every permission on every resource. Bypasses client scoping.
- Technician: can create, view, and edit the operational resources (clients, locations, printers, queues, drivers, endpoints). Can’t delete anything, and can’t touch users, API keys, scripts, or webhooks.
- Read-Only: view-only on operational resources, plus the audit log.
See the Permissions reference for the full matrix.
Creating a custom role
When the three system roles don’t fit (e.g. “L1 tech who can create queues but not delete them, scoped to one client”), build a custom role:
- Settings → Roles → Create Role.
- Name the role.
- Check the permission cells you want to grant. The matrix has rows for each resource and columns for view, create, edit, and delete.
- Pick client scopes in the searchable picker below the matrix:
- Leave empty for org-wide access
- Or check one or more clients to restrict the role to only those clients’ resources
- Save. Assign the new role to users via Settings → Users → Edit → Role.
Custom roles don’t get the admin bypass. Every permission is what you check. To grant admin-like access but scoped, check every cell and add client scopes.
How scoping is enforced
A scoped user only ever sees and acts on the customers in their scope. Two things are checked on every action: that their role allows it, and that the resource belongs to one of their customers. Anything else is refused.
This isn’t just the UI hiding buttons. The limit is enforced on the server, so a scoped user can’t work around it by editing a URL or calling the API directly.
Sessions
A signed-in session refreshes itself quietly in the background, and idles out after two hours of inactivity. Signing out, being disabled by an admin, or having your password reset ends every session you have open.
One case catches people out. If ZenPrint sees an expired session being reused after it has already been replaced, it assumes the session was copied and signs you out everywhere. Log back in with your password and authenticator and carry on. If it keeps happening with no explanation, tell your admin, because it can mean someone else holds a copy of your session.
API keys vs users
Users sign in through the browser with a password and an authenticator app. A user has a role, can be scoped to specific clients, and everything they do is attributed to them in the audit log.
API keys authenticate via Authorization: Bearer zpk_..., used by RMM-driven scripts. They aren’t tied to a user; they’re tied to your ZenPrint tenant and can act across every client and location in it. A key is either full-access (what the bootstrap uses) or read-only (GET requests only, rejected on any write), and carries a rate limit, but no role and no client scope.
Create and manage API keys under Settings → API Keys. The full key is shown once on creation, so copy it then or rotate it later.
Audit trail
Every user-management action writes an audit row: invite, role change, disable, enable, MFA reset, password reset, delete. View it under Settings → Audit Log (visible to all three system roles by default).
Role mutations (role_create, role_update, role_delete) and scope changes are audited too.
Each row reads as a sentence describing what happened, naming the queue, endpoint, printer, driver or user involved rather than an internal ID. The Details column carries whatever extra fields the action recorded, and the line underneath names the client and location the change happened in. The Action and Resource filters list only the values your workspace has actually logged, so an empty result is never a stale filter option.
Workspace settings
Settings → Workspace holds your organization profile and display preferences. The whole tab is available to anyone with the users: edit permission.
The Profile section sets your organization name and contact email. It also shows, read-only, your workspace URL (your {slug} address), your plan, and how many managed printers you have against your plan limit. Only managed printers count: devices with a print queue assigned. Discovered devices you never onboarded, dismissed devices, and decommissioned devices do not count.
If you are on a trial, the trial end date shows here too. When a trial ends your workspace moves to the Free plan automatically. Nothing is deleted and existing printers keep working, but you cannot bring new printers under management while you are over the Free allowance.
If the plan line reads “over limit”, you are managing more printers than the plan includes. Adding a queue to a new printer is blocked until you either dismiss or decommission printers you no longer manage, or upgrade. Your plan and printer limit are managed by ZenPrint; email support@zenprint.io to change them.
Below the plan details you may see a Set up billing or Manage billing button. See Billing for how checkout, invoices, and monthly peak billing work.
The Display section sets the timezone for your whole workspace. Pick your timezone from the list and save. Absolute timestamps across the app render in it: the audit log, last-seen and last check-in times, API key and webhook activity, and similar. The audit log shows the zone abbreviation (for example 2026-03-08 15:04:05 CET) so a time is never ambiguous.
Relative times like “2h ago” are the same in any timezone, so they do not change. The default is UTC until you set a timezone. This is one setting for the organization, not per user, and it controls display only. Stored timestamps stay in UTC.