Documentation

Role Management & Permissions

How SAVHN's role-based access control model works end to end, how permission-based screens are constructed and enforced server-side, and how to configure per-user module visibility.

Checking access...

Every action in SAVHN โ€” viewing a record, editing an invoice, approving leave, seeing a navigation entry at all โ€” is governed by role-based access control (RBAC). This guide explains the permission model and how to configure it for your organization.

The permission model

SAVHN's RBAC model has three layers that compose together:

  1. Module enablement (org-level): a module must be enabled for the organization at all before any user, regardless of role, can access it. This is configured in the Module Marketplace.
  2. Role permissions (role-level): each role carries a set of permissions scoped to modules and actions (view, create, edit, delete, approve, export). Roles are reusable across users.
  3. User overrides (user-level): individual users can have specific permissions added or revoked on top of their assigned role, for exceptions that don't warrant a new role.

The effective permission for a given user and action is the role's permission, adjusted by any user-level overrides. Module enablement is a hard gate above both โ€” a permission granted for a disabled module has no effect.

Built-in roles

Most organizations start from a small set of built-in roles and refine from there:

Role Typical scope Notes
Org Admin Full access to all enabled modules and the Admin Console Assigned automatically to the org creator; can be granted to others
Department Head Full access within their department's records; read access to org-wide reports Common for team leads managing HRMS, Projects, Tickets
Manager Approve/edit access to direct reports' records (leave, timesheets, expenses) Pairs with Manager Copilot for team oversight
Employee (standard user) Self-service access: own profile, own timesheets, own tickets, shared documents Default role for most invited users
Client (Client Portal) Restricted, external-facing access to shared projects, invoices, and tickets only Used for external stakeholders, never has Admin Console access
Custom roles Defined per-organization Combine any set of module + action permissions

Creating a custom role

  1. Go to Admin Console โ†’ Roles & Permissions โ†’ Create Role.
  2. Name the role and, optionally, base it on an existing role to start from a copy of its permission set.
  3. For each enabled module, set the permission level: No Access, View Only, View & Edit, Full Access (including delete/approve).
  4. Some modules expose finer-grained permissions beyond CRUD โ€” for example, Finance separates "view invoices" from "approve payments," and Payroll separates "view payslips" from "run payroll." Configure these sub-permissions where they appear.
  5. Save the role, then assign it to users from Admin Console โ†’ Users.

Permission-based screens

Screens and navigation entries in SAVHN are rendered based on the current user's resolved permission set, not hidden purely with client-side styling:

  • If a user has no permission on a module, that module does not appear in their navigation at all.
  • If a user has View Only on a module, action buttons (create, edit, delete, approve) are not rendered, and the underlying API calls those actions would trigger reject the request server-side, so removing a button from the UI is a convenience, not the security boundary.
  • Record-level scoping is applied on top of module-level permission: a Manager with edit access to "Team Timesheets" only sees timesheets belonging to their direct reports, even though the Timesheets screen itself is visible.

Per-user module visibility

Because module access is resolved per user, two employees with the same role but different module-level overrides will see different navigation. This is useful for:

  • Contractors who should see Projects and Timeline but not HRMS or Payroll.
  • Finance staff who need Finance and Reports but not Tickets or CRM.
  • Client Portal users, who by design only ever see the subset of Projects, Documents, and Finance records explicitly shared with them.

To adjust an individual user's module visibility without creating a new role:

  1. Go to Admin Console โ†’ Users โ†’ [select user] โ†’ Permissions.
  2. Toggle module-level access on or off, or adjust the permission level for a specific module.
  3. Overrides are flagged in the UI so admins can distinguish "this comes from the role" versus "this was manually overridden," which matters when the user's role is changed later โ€” overrides persist across a role change unless explicitly cleared.

Example: a minimal support-desk role

{
  "roleName": "Support Agent",
  "permissions": {
    "tickets": "full_access",
    "chat": "view_edit",
    "documents": "view_only",
    "reports": "view_only",
    "crm": "no_access",
    "payroll": "no_access"
  }
}

This illustrates the shape of a role's permission set โ€” a real role definition includes an entry per enabled module in the organization, and some modules add nested keys for sub-permissions like approve or export.

Record-level scoping in practice

Module-level permission answers "can this user open this screen at all," while record-level scoping answers "which specific records does this user see once they're on it." The two operate independently:

  • A Manager role might have "View & Edit" at the module level on Timesheets, but the effective query behind that screen is still filtered to only the timesheets of that manager's direct reports โ€” the module permission grants entry, the record scope narrows the result set.
  • A Department Head role commonly extends record scope to an entire department rather than just direct reports, which is why department structure (see Organization Setup & Onboarding) needs to be accurate before this scoping is meaningful.
  • Some modules support explicit record-level sharing on top of role-driven scope โ€” for example, sharing a specific Document or Project with an individual user who wouldn't otherwise see it through their role. This is additive: it can grant visibility into an otherwise out-of-scope record, but it can never override a module-level "No Access" setting, since the module gate is checked first.

Understanding this two-layer model helps when debugging "why can't this user see X" โ€” always check module-level access first, then record-level scope, in that order, since a module-level denial makes record scope irrelevant.

Role design patterns worth adopting

  • Start from function, not from title. Two people with the same job title in different teams may need different access; design roles around what someone needs to do, and assign titles/departments separately.
  • Keep the role count manageable. A sprawling set of near-duplicate roles ("Sales Manager v2," "Sales Manager - East") is harder to audit than a smaller set of well-named roles combined with targeted user-level overrides for genuine exceptions.
  • Separate "view" from "act" wherever the module supports it. Giving broad view access (useful for context and reporting) is lower risk than giving broad edit or approve access; use the finer-grained sub-permissions where a module exposes them rather than defaulting everyone to Full Access.
  • Treat approval permissions as distinct from edit permissions. A user who can edit an expense claim should not automatically be able to approve their own edits โ€” where a module supports separating these, use that separation to maintain a basic segregation of duties.

Auditing role and permission changes

Every change to a role definition or a user's permission overrides is recorded in the organization's audit log (see Security & Compliance Overview), including who made the change and when. Review this periodically, especially after offboarding events, to confirm access was revoked as expected.

Best practices

  • Prefer role-based assignment over per-user overrides; overrides are useful for exceptions, not as the primary mechanism, since a growing pile of overrides makes it hard to reason about "who can see payroll."
  • Review roles quarterly against your current org chart โ€” departments and reporting lines change faster than role definitions tend to.
  • Use the Client role family exclusively for external users, and never grant Admin Console access to an external identity.
  • When offboarding an employee, deactivate the user rather than only removing their role, so historical records they authored remain attributed correctly while login access is revoked immediately.

Stuck on this step? The team that built it can help.

Contact Developer Team