NkapBooks includes a full-featured role-based access control (RBAC) system that lets you control who can view, create, edit, delete, submit, and share every document type in the application. The security model is built on schema-based entities — Users, Roles, Role Permissions, Sessions, and Document Shares — all managed through the standard document interface.
Component Schema Location Description User Accounts UserSetup → Users Individual login identities with profile, contact, and security settings Roles RoleSetup → Roles Named groupings of permissions (e.g., Sales User, Accounts Manager) Role Permissions RolePermissionRole → Permissions tab Granular per-doctype permission matrix for each role Document Sharing DocShareSetup → Document Shares Share specific documents with users who lack full doctype access Session Management SessionSetup → Sessions Track and control active login sessions across devices Authentication AuthSettingsSettings → Authentication Login requirements, password policy, 2FA, lockout, and API keys Permission System PermissionManagerInternal The engine that evaluates all permission checks at runtime
User management features are accessible from the sidebar under Setup → Users , Roles , Document Shares , and Sessions . Authentication settings are configured in Settings → Authentication tab. All user and role CRUD operations use the standard schema-based document interface (list view, form view, quick edit).
NkapBooks implements a layered permission model that evaluates access at multiple levels:
┌─────────────────────────────────────────────────┐
│ 1. Administrator Bypass │
│ If user has Administrator role → ALLOW ALL │
├─────────────────────────────────────────────────┤
│ 2. System Doctype Bypass │
│ Core settings doctypes → ALLOW ALL │
├─────────────────────────────────────────────────┤
│ 3. Role-Based Permissions │
│ Check RolePermission records for user's roles│
├─────────────────────────────────────────────────┤
│ 4. Owner-Based Permissions (ifOwner) │
│ Permission applies only if user owns the doc │
├─────────────────────────────────────────────────┤
│ 5. Document Sharing │
│ Check DocShare records for specific documents │
├─────────────────────────────────────────────────┤
│ 6. Default: DENY │
└─────────────────────────────────────────────────┘
The system supports 13 distinct permission types that can be independently toggled per doctype per role:
Permission Field Description Read readPermView documents of this type Write writePermModify existing documents Create createPermCreate new documents Delete deletePermRemove documents Submit submitPermSubmit draft documents for finalization Cancel cancelPermCancel submitted documents Amend amendPermCreate amended versions of cancelled documents Report reportPermAccess reports related to this doctype Export exportPermExport data (CSV, JSON) Import importPermImport data from external sources Share sharePermShare documents with other users Print printPermPrint or generate PDFs Email emailPermSend documents via email
NkapBooks ships with four system roles that cannot be deleted:
Role Type Description Administrator System Full unrestricted access to everything — bypasses all permission checks System Manager System System configuration access — can manage settings and system-level operations All Automatic Automatically assigned to every user — used for universal baseline permissions Guest Automatic Assigned to unauthenticated or anonymous users
Important: Automatic roles (All and Guest) are assigned automatically and cannot be manually assigned or removed from users. System roles (Administrator and System Manager) cannot be deleted or renamed but can be assigned to users.
A User in NkapBooks represents an individual who can log in, perform actions, and own documents. Users are identified by their email address (which serves as the primary key) and have a rich profile including contact details, security settings, and role assignments.
The User schema is organized into six sections :
Field Type Required Description name (Email)Data ✅ Primary identifier — must be a valid email address (e.g., user@example.com) passwordPassword — Set during creation only; not persisted in the database directly firstNameData — User's first name lastNameData — User's last name fullNameData (read-only) — Auto-computed from firstName + lastName usernameData — Optional display username enabledCheck — Whether the user can log in (default: true) imageAttachImage — Profile picture genderSelect — Male, Female, Other, or Prefer not to say birthDateDate — Date of birth locationData — Geographic location bioText — Short biography
Field Type Description phoneData Office/home phone number mobileNoData Mobile phone number
Field Type Description rolesTable → UserRole Child table linking the user to one or more roles
Each row in the roles table is a UserRole record:
Field Type Description roleLink → Role Reference to a Role record
Field Type Default Description simultaneousSessionsInt 3 Max concurrent sessions (1–100) restrictIpData — Comma-separated allowed IP addresses loginAfterData — Earliest allowed login time (HH:MM format, e.g., 09:00) loginBeforeData — Latest allowed login time (HH:MM format, e.g., 18:00) twoFactorEnabledCheck falseWhether 2FA is enabled for this user
Field Type Description lastLoginDatetime Timestamp of last successful login lastIpData IP address of last login lastActiveDatetime Timestamp of last activity
Activity fields are hidden in the form view and updated automatically by the system. They are read-only and cannot be edited manually.
Field Type Default Description languageSelect English Preferred language (English or French) timeZoneData — User's time zone muteSoundsCheck falseMute UI notification sounds allowedInMentionsCheck trueWhether this user appears in mention lists
Field Type Default Description emailSignatureText — Custom signature for outgoing emails sendWelcomeEmailCheck trueSend welcome email on account creation threadNotifyCheck trueReceive thread notification emails sendMeCopyCheck falseCC the user on outgoing emails
Navigate to Setup → Users from the sidebar Click + New User (or press Ctrl+N) Enter the email address in the Name field — this is the user's login identifier Fill in First Name and Last Name (Full Name is auto-computed) Set a Password (only visible during creation; hidden after save) Assign Roles in the Roles table — click Add Row and select a role Click Save (Ctrl+S) Event Behavior Before Sync Email is set to name if not provided; full name is computed; password is extracted for separate secure storage After Sync Password is set via Tauri secure command (set_password); permission cache is cleared for this user Deactivation Set enabled to false — the user can no longer log in but their data and history are preserved
The Users list view displays three columns by default:
Column Description nameEmail address (primary key) fullNameComputed display name enabledActive/inactive status
Keyword search works across name, email, fullName, and username.
When viewing a user in quick edit mode, these fields are shown:
Email, First Name, Last Name, Enabled, Phone A Role defines a named set of permissions. Roles are assigned to users and determine what actions each user can perform across the application.
Field Type Required Default Description nameData ✅ — Unique role name (2–140 characters, no commas or semicolons) descriptionText — — Human-readable description of what this role grants disabledCheck — falseDisable the role without deleting it deskAccessCheck — trueWhether users with this role can access the application desk/modules twoFactorAuthCheck — falseRequire two-factor authentication for users with this role isCustomCheck — trueSystem flag — true for user-created roles, false for built-in roles restrictToDomainData — — Optional domain restriction permissionsTable → RolePermission — — Child table defining per-doctype permissions
NkapBooks comes with several pre-configured roles:
Role Type Can Delete Can Assign Description Administrator System ❌ ✅ Full access to all features and data System Manager System ❌ ✅ Access to system configuration and settings All Automatic ❌ ❌ (auto-assigned) Baseline permissions for all authenticated users Guest Automatic ❌ ❌ (auto-assigned) Permissions for unauthenticated users Accounts Manager Custom (built-in) ✅ ✅ Full access to accounting features Sales User Custom (built-in) ✅ ✅ Access to sales documents and customers Purchase User Custom (built-in) ✅ ✅ Access to purchase documents and suppliers Inventory User Custom (built-in) ✅ ✅ Access to inventory and stock management
Navigate to Setup → Roles from the sidebar Click + New Role Enter a Role Name (e.g., "Cashier", "Branch Manager") Add a Description explaining the role's purpose Configure Desk Access and Two-Factor Auth settings Add Permissions in the permissions table (see Role Permissions ) Click Save Property Method Description isSystemRoleGetter Returns true for Administrator, System Manager, All, Guest isAutomaticRoleGetter Returns true for All, Guest (auto-assigned) canBeAssignedGetter true if the role is not automatic and not disabledcanDeleteGetter true if the role is not a system role
Event Behavior Before Sync Sets isCustom flag for new roles (true if not a system role) Before Delete Prevents deletion of system roles; checks for assigned users and throws error if any After Sync Clears the global permission cache so changes take effect immediately
When you try to delete a role:
System roles — Cannot be deleted. An error is shown: "Cannot delete system role: Administrator" Assigned roles — Cannot be deleted while assigned to users. Error: "Cannot delete role 'Cashier' as it is assigned to 3 user(s). Please remove the role from all users first." Custom unassigned roles — Can be deleted safely. Associated RolePermission child entries are deleted automatically.Column Description nameRole name descriptionRole description deskAccessWhether the role grants desk access disabledDisabled status
Clicking a role in the list opens the role form at /edit/Role/{name}.
Role Permissions (RolePermission) define the granular access rights for each role on each document type. They are stored as a child table within the Role document.
Field Type Default Description docTypeAutoComplete — The document type this permission applies to (e.g., SalesInvoice) permLevelInt 0Permission level — 0 for document-level, 1–9 for field-level readPermCheck trueCan view documents writePermCheck falseCan edit existing documents createPermCheck falseCan create new documents deletePermCheck falseCan delete documents submitPermCheck falseCan submit draft documents cancelPermCheck falseCan cancel submitted documents amendPermCheck falseCan amend cancelled documents reportPermCheck falseCan view related reports exportPermCheck falseCan export data importPermCheck falseCan import data sharePermCheck falseCan share documents with others printPermCheck falseCan print or generate PDFs emailPermCheck falseCan send documents via email selectPermCheck trueCan select/reference this doctype in Link fields setUserPermissionsCheck falseCan set user-level permissions ifOwnerCheck falsePermission applies only if the user is the document owner
When viewing permissions in the Role form, the table shows:
Column Description docTypeDocument type name readPermRead checkbox writePermWrite checkbox createPermCreate checkbox deletePermDelete checkbox
Additional permissions are accessible via the row quick edit (click a row to expand).
The ifOwner flag is a powerful feature that restricts a permission to only apply when the current user is the owner (creator) of the document:
Scenario ifOwner = falseifOwner = trueUser created the invoice ✅ Can edit ✅ Can edit Another user created the invoice ✅ Can edit ❌ Cannot edit
This is useful for creating roles where users can manage their own documents but not others'. For example, a "Sales User" role might have:
SalesInvoice → Read (ifOwner: false), Write (ifOwner: true), Create, Submit (ifOwner: true)This means: can view all invoices, but can only edit/submit their own Open a Role (e.g., Setup → Roles → Sales User ) Scroll to the Permissions section Click Add Row Select a Document Type from the dropdown Toggle the permission checkboxes as needed Enable If Owner if the permission should be owner-restricted Save the roleThe setRolePermission() function in src/utils/auth.ts provides programmatic permission management:
Parameter Type Description rolestring Role name docTypestring Document type name permissionsobject Permission flags to set
When checking if a user can perform an action, the system:
Gets all roles assigned to the user (including automatic roles like All) For each role, checks the RolePermission entries for the target doctype If any role grants the permission → ALLOW (union of all role permissions) If the granting permission has ifOwner set → checks document ownership If no role grants the permission → falls through to document sharing check Tip: Permissions are additive across roles. If a user has both "Sales User" and "Accounts Manager" roles, they get the union of all permissions from both roles. You cannot use one role to remove permissions granted by another.
Document Sharing (DocShare) lets you grant access to specific documents to users who may not have full doctype-level permissions. This is useful for collaboration scenarios where you want to share a particular invoice or report with a colleague without giving them access to all documents of that type.
Field Type Required Default Description userLink → User ✅ — The user to share the document with shareNameData ✅ — The name/ID of the document being shared shareDocTypeData ✅ — The document type (e.g., SalesInvoice) everyoneCheck — falseIf true, the document is shared with all users readAccessCheck — trueCan view the shared document writeAccessCheck — falseCan edit the shared document shareAccessCheck — falseCan re-share the document with others submitAccessCheck — falseCan submit the shared document notifyByEmailCheck — trueSend an email notification to the shared user notifyByEmailSentCheck (read-only) — falseWhether the notification email was sent sharedByLink → User (read-only) — — The user who created the share
Navigate to Setup → Document Shares from the sidebar Click + New Document Share Select the User to share with Enter the Document Type (e.g., SalesInvoice) Enter the Document Name (e.g., SINV-00042) Configure access levels (Read, Write, Share, Submit) Save The shareDocument() method is available on both the AuthService and PermissionManager:
Parameter Description docTypeDocument type to share docNameSpecific document name/ID userIdUser to share with options.readGrant read access (default: true) options.writeGrant write access (default: false) options.shareGrant re-share access (default: false) options.submitGrant submit access (default: false)
Setting the everyone flag to true makes the document accessible to all authenticated users without specifying individual users. This is checked during permission evaluation — if any DocShare record exists with everyone: true and the matching doctype/name, the permission is granted.
When the role-based permission check denies access, the system performs a secondary check:
Look for DocShare records matching { shareDocType, shareName, user } (direct share) Look for DocShare records matching { shareDocType, shareName, everyone: true } (everyone share) Check the access field (readAccess, writeAccess, shareAccess, submitAccess) corresponding to the requested permission If either check finds a match → ALLOW Function Description shareDocument()Create or update a share for a specific document unshareDocument()Remove a specific user's share on a document getDocumentShares()List all shares for a specific document getUserDocumentShares()List all documents shared with a specific user clearDocumentShares()Remove all shares for a specific document
To share a document, the sharing user must themselves have the Share permission (sharePerm) on the relevant doctype. This prevents unprivileged users from granting access they don't have.
NkapBooks tracks user sessions to provide security monitoring, multi-device support, and automatic session cleanup.
Field Type Required Default Description userLink → User ✅ — The user this session belongs to sessionIdData (read-only) ✅ — Unique session identifier (randomly generated) deviceData — — Device name or type (auto-detected) ipAddressData (read-only) — — IP address of the session userAgentData (read-only) — — Browser/app user agent string lastActiveDatetime (read-only) — — Timestamp of the most recent activity expiresAtDatetime — — When the session will automatically expire isValidCheck — trueWhether the session is still valid isLockedCheck — falseWhether the session is currently locked (screen lock) lockedAtDatetime (read-only) — — When the session was locked
Login Request
│
▼
┌──────────────┐ ┌──────────────┐
│ Authenticate │────►│ Create │
│ Credentials │ │ Session │
└──────────────┘ └──────┬───────┘
│
▼
┌──────────────┐
│ Active │◄──── Refresh / Activity
│ Session │
└──────┬───────┘
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Logout │ │ Timeout │ │ Lock │
│ (Manual) │ │ (Auto) │ │ (Idle) │
└──────────┘ └──────────┘ └──────┬───┘
│
▼
┌──────────────┐
│ Unlock │
│ (Password) │
└──────────────┘
Operation Method Description Login authService.login()Creates a new session, returns session token Validate authService.validateSession()Checks if a session token is still valid Refresh authService.refreshSession()Extends session expiry, returns new token Logout authService.logout()Invalidates the current session Logout All authService.logoutAllDevices()Invalidates all sessions for the current user Get Sessions getUserSessions()Lists all active sessions for a user
Navigate to Setup → Sessions to see all active sessions. The list view shows:
Column Description User The session owner Device Device name/type Is Valid Whether the session is active
Feature Description Session Timeout Configurable in Auth Settings — sessions expire after the specified duration Idle Timeout Separate idle timeout — locks the session after inactivity Session Locking Locked sessions require password re-entry to unlock Max Sessions Configurable per user (simultaneousSessions field) and globally (maxSessionsPerUser in AuthSettings) Token Storage Session tokens are stored securely using the Tauri Stronghold plugin
Authentication in NkapBooks is controlled by the AuthSettings schema (accessible via Settings → Authentication tab) and the AuthService class.
The AuthSettings is a singleton document organized into six sections:
Field Type Default Description requireAuthCheck trueIf enabled, users must log in to access the application allowSkipAuthCheck falseAllow users to skip authentication (for development/testing)
Field Type Default Description allowPasswordResetCheck trueAllow users to reset their password passwordMinLengthInt 8Minimum number of characters required passwordRequireUppercaseCheck trueRequire at least one uppercase letter passwordRequireNumberCheck trueRequire at least one number passwordRequireSpecialCheck falseRequire at least one special character
Field Type Default Description sessionTimeoutInt (minutes) 60Session timeout duration (0 = no timeout) maxSessionsPerUserInt 3Maximum simultaneous sessions per user sessionIdleTimeoutInt (minutes) 30Idle timeout before auto-lock (0 = disabled)
Field Type Default Description enableTwoFactorCheck falseAllow users to enable 2FA requireTwoFactorCheck falseRequire all users to enable 2FA twoFactorMethodSelect TOTPMethod: TOTP (Time-based One-Time Password) or Email
Field Type Default Description maxLoginAttemptsInt 5Maximum failed attempts before lockout (0 = unlimited) lockoutDurationInt (minutes) 15Duration of account lockout after max failed attempts
Field Type Default Description allowApiKeysCheck trueAllow users to generate API keys for programmatic access
Field Type Default Description allowPublicRegistrationCheck falseAllow public user registration defaultRoleLink → Role — Default role assigned to newly registered users requireEmailVerificationCheck trueRequire email verification for new accounts
User enters email/username + password
│
▼
┌──────────────────────┐
│ AuthDemux.login() │──── Tauri backend command
└──────────┬───────────┘
│
▼
┌───────────────┐ ┌──────────────────┐
│ Credentials │─NO─►│ Return error │
│ Valid? │ │ (increment fails) │
└───────┬───────┘ └──────────────────┘
│ YES
▼
┌───────────────┐ ┌──────────────────┐
│ Account │─YES►│ Return lockout │
│ Locked? │ │ error │
└───────┬───────┘ └──────────────────┘
│ NO
▼
┌───────────────┐ ┌──────────────────┐
│ 2FA │─YES►│ Return 2FA │
│ Required? │ │ challenge │
└───────┬───────┘ └──────────────────┘
│ NO
▼
┌───────────────┐
│ Create Session│──── Session token stored
│ Return Success│ via Tauri Stronghold
└───────────────┘
NkapBooks provides several password management operations:
Operation Function Description Set Password setPassword(userId, password)Admin sets a user's password directly Change Password changePassword(current, new)User changes their own password Request Reset requestPasswordReset(email)Initiate a password reset flow Reset Password resetPassword(token, new)Complete a password reset with a reset token
Security Note: Passwords are never stored in the database directly. They are hashed and managed through Tauri backend commands (set_password, change_password). The password field on the User schema is only used during creation and is cleared before the document is saved.
When allowApiKeys is enabled in AuthSettings, users can generate API keys for programmatic access:
Operation Function Description generateApiKeys(userId)Generate new API key pair for a user revokeApiKeys(userId)Revoke all API keys for a user
When allowPublicRegistration is enabled, new users can register through the application:
The system creates a new User document with the provided details Assigns the default role configured in AuthSettings If requireEmailVerification is enabled, sends a verification email Sets the user's password through the secure Tauri backend The PermissionManager (fyo/core/permissionManager.ts) is the central engine that evaluates all permission checks in NkapBooks. It is accessed through fyo.perm and provides both simple boolean checks and detailed permission results.
Every permission check follows this decision tree:
Step Check Result 1 Permission checking disabled? → Allow 2 Setup not complete? → Allow (for setup phase) 3 User is Administrator? → Allow (bypasses everything) 4 Doctype is bypass-exempt? → Allow (core system doctypes) 5 Check role-based permissions → Allow if any role grants it 6 Check ifOwner permissions → Allow if user owns document 7 Check document sharing → Allow if document is shared 8 None of the above → Deny
The following core system doctypes always bypass permission checks — they are essential for the application to function:
Category Doctypes Core PatchRun, SingleValue, NumberSeries, MiscSetup SetupWizard, GetStartedSettings SystemSettings, Defaults, PrintSettings, AccountingSettings, InventorySettings, AuthSettings
Additionally, auth-related doctypes (User, Role, UserRole, RolePermission, Session, DocShare) bypass permission checks during initial setup before permissions are configured.
The PermissionManager uses a two-level cache for performance:
Cache TTL Description Permission Cache 5 minutes Caches the result of individual permission checks Role Cache 5 minutes Caches the role assignments for each user
The cache is automatically cleared when:
A User document is modified → clears that user's cached roles and permissions A Role document is modified → clears the entire permission cache clearCache() is called explicitlyMethod Returns Description hasPermission(docType, permType, options)booleanSimple yes/no permission check canRead(docType, userId)booleanCan the user read this doctype? canWrite(docType, userId)booleanCan the user write this doctype? canCreate(docType, userId)booleanCan the user create this doctype? canDelete(docType, userId)booleanCan the user delete this doctype? canSubmit(docType, userId)booleanCan the user submit this doctype? canCancel(docType, userId)booleanCan the user cancel this doctype?
Method Returns Description hasPermissionDetailed(docType, permType, options)PermissionCheckResultDetailed result with granting roles and denial reason getDocPermissions(docType, options)DocPermissionsAll 13 permission flags for a doctype
The PermissionCheckResult object contains:
Field Type Description allowedboolean Whether the permission is granted grantedByRolesstring Which roles granted the permission (if allowed) denialReasonstring Human-readable reason for denial (if denied) viaSharingboolean Whether access was granted via document sharing isOwnerBasedboolean Whether the permission is owner-restricted
Method Returns Description canReadDoc(docType, docName, owner)booleanCan read a specific document? canWriteDoc(docType, docName, owner)booleanCan write a specific document? canDeleteDoc(docType, docName, owner)booleanCan delete a specific document? canSubmitDoc(docType, docName, owner)booleanCan submit a specific document? canCancelDoc(docType, docName, owner)booleanCan cancel a specific document?
Method Returns Description getReadableDoctypes(userId)string[]All doctypes the user can read getCreatableDoctypes(userId)string[]All doctypes the user can create getAccessibleDocuments(docType, userId){ hasFullAccess, accessibleNames }Documents accessible to a user for a doctype
Method Behavior validatePermission(docType, permType, options)Throws ForbiddenError if permission is denied validateDocPermission(docType, permType, docName, owner)Throws ForbiddenError for specific document
NkapBooks provides Vue composables for permission-aware UI development:
Returns reactive references for the current authentication state:
Property Type Description isAuthenticatedRef<boolean>Whether the user is logged in userRef<string>Current user email isLoadingRef<boolean>Whether an auth operation is in progress errorRef<string>Last auth error message isAdministratorComputedRef<boolean>Whether current user is Administrator isSystemManagerComputedRef<boolean>Whether current user is System Manager rolesRef<string[]>Current user's role names hasRole(role)Function Check if user has a specific role hasAnyRole(roles)Function Check if user has any of the specified roles hasAllRoles(roles)Function Check if user has all of the specified roles
Returns permission-checking helpers:
Property Type Description isAdminRef<boolean>Whether user is Administrator isSystemManagerRef<boolean>Whether user is System Manager
Returns comprehensive role permission utilities for UI components.
NkapBooks uses Vue Router meta fields to enforce permissions at the route level:
Meta Field Type Description requiresAuthboolean Route requires authentication bypassPermissionCheckboolean Skip permission check for this route requiredPermission{ docType, permissionType }Specific permission required to access
Example route definitions:
Route Auth Required Permission /users✅ User.read/roles✅ Role.read/doc-shares✅ DocShare.read/sessions✅ Session.read/user-settings✅ Bypass (own settings) /permission-denied— None (error page)
Tip: When a user navigates to a route they don't have permission for, they are redirected to the /permission-denied page with a clear explanation of what permission is required.
Recommendation Description Start with built-in roles Use Administrator, Accounts Manager, Sales User, etc. as a starting point Create task-specific roles E.g., "Cashier" with only POS and payment permissions Use ifOwner judiciously Great for allowing users to manage their own documents without seeing others Avoid excessive roles per user Permissions are additive — too many roles can be hard to audit Test permissions Use the hasPermissionDetailed() function to debug permission issues
Recommendation Description Enable authentication Set requireAuth: true in production environments Set strong password policies Minimum 8 characters, require uppercase and numbers Configure session timeouts 60 minutes session, 30 minutes idle timeout for office environments Enable 2FA for sensitive roles Require two-factor authentication for Administrator and Accounts Manager roles Limit concurrent sessions Set simultaneousSessions to 3 or fewer per user Review active sessions Periodically check Setup → Sessions for unexpected activity
Recommendation Description Prefer role-based access Use document sharing for exceptions, not as the primary access model Audit shares regularly Review Setup → Document Shares for stale or unnecessary shares Use "everyone" sparingly Only for documents that genuinely need universal access Require share permission Ensure only authorized users have sharePerm on sensitive doctypes