Skip to content

User Management

User management in ARROW is straightforward. Roles are broken into three categories:

  • Admin: We recommend assigning this role only to practice leadership (e.g., Practice Director(s), Practice Manager(s), etc.).
  • Manager: This role is ideal for Project Management staff or anyone responsible for adding clients or requesting devices. We do not recommend assigning individual contributors as managers to reduce the possibility of duplicate device requests.
  • User: This role is suited for team members who will utilize ARROW in a technical delivery capacity. They will maintain administrative rights over physical devices and virtual deployments but will not have access to billing information, invoices, device requests, etc.

The table below provides a brief overview of ARROW’s role-based access control (RBAC) structure.

CapabilityAdminManagerUser
User Management✅ Full❌ None❌ None
Role Management✅ Full❌ None❌ None
Client Creation✅ Yes✅ Yes❌ Read-only
Client Management✅ Yes✅ Yes❌ Read-only
Device Request Creation✅ Yes✅ Yes❌ Read-only
Device Access✅ All✅ All✅ All

To add users in ARROW, click Users in the sidebar, then click the + Add User button.

Add New User Dialog Adding a user to ARROW

You can immediately kill access to any user in ARROW and your VPN by terminating their account within your IDP (e.g., Google, o365, Okta, etc.). However, you will still need to delete their account from the ARROW portal. To do this, click Users in the sidebar, then click the Trash Can button in the table next to the desired user.

Delete User Dialog Removing a user from ARROW


This section provides technical details about ARROW’s permission system architecture for developers and system administrators.

ARROW implements a sophisticated multi-layered RBAC system using PocketBase collections and hooks. The architecture consists of the following components:

CollectionPurpose
usersUser accounts with aggregated permissions field
rolesRole definitions with organization_use flag
user_rolesJunction table linking users to roles
permissionsGranular capability definitions

The role system provides hierarchical access control:

RoleScopePrimary Capabilities
AdminFull organization controlUser management, role assignment, billing access, all operations
ManagerOperational controlClient creation, device requests, client management
UserTechnical deliveryDevice access, VPN connectivity, read-only to administrative functions
graph TD
    A[User] -->|has many| B[User Roles]
    B -->|references| C[Role]
    C -->|has many| D[Role Permissions]
    D -->|references| E[Permission]
    A -->|aggregated| F[User Permissions Array]
    C -->|organization_use flag| G{Assignable by Org?}
    G -->|Yes| H[Org Admins Can Assign]
    G -->|No| I[System Only]

    J[Hooks] -->|Sync on Role Change| F
    J -->|Validate on Assignment| G
    J -->|Sync to Zitadel| K[Zitadel Projects]
    J -->|Sync to NetBird| L[VPN Access Groups]

Permissions are automatically synchronized from roles to users through PocketBase hooks implemented in backend/hooks/user_permissions.go.

The SyncUserPermissions function (lines 230-349) aggregates permissions from all assigned roles:

  1. Queries user_roles - Retrieves all role assignments for the user
  2. Expands role permissions - Loads the permissions array from each role
  3. Deduplicates - Combines unique permissions from all roles
  4. Updates user record - Stores the aggregated permissions on the user

Permission synchronization is automatically triggered on:

EventTrigger Location
User role assignmentuser_roles create hook
User role removaluser_roles delete hook
Role updateroles update hook (syncs all affected users)
Role deletionroles delete hook (syncs all affected users)

When a new user is created, permission sync is delayed by 500ms to allow Zitadel integration to complete first:

go func() {
time.Sleep(500 * time.Millisecond)
SyncUserPermissions(app, userId)
}()

For debugging purposes, administrators can manually trigger permission sync:

POST /api/admin/sync-user-permissions

Role assignment validation is enforced in backend/hooks/user_roles_validation.go to ensure organization admins can only assign appropriate roles.

Each role has an organization_use boolean field:

Flag ValueMeaning
trueRole can be assigned by organization admins
falseSystem-only role (site admin assignment only)

When a user role assignment is created or updated:

  1. Check assigner permissions - Verify the requesting user has permission to assign roles
  2. Validate organization_use - If assigner is not a site admin, verify the role has organization_use: true
  3. Reject invalid assignments - Return error for unauthorized role assignments

Attempting to assign a system-only role without site admin privileges returns:

{
"error": "This role cannot be assigned by organization administrators"
}

User permissions integrate with NetBird VPN access control to manage device connectivity.

The consultants field on device requests controls VPN user access:

FieldTypeDescription
consultantsArrayUsers authorized to access the device via VPN

When consultants are assigned to devices, the system automatically synchronizes VPN access through hooks in backend/hooks/device_user_access.go:

  1. Detects consultant changes - Compares old and new consultant arrays
  2. Checks access control status - Verifies if device has access control enabled
  3. Updates NetBird groups - Adds/removes users from consultant groups
  4. Enforces one-way policies - Ensures consultants can reach devices but not vice versa
LevelSettingBehavior
Organizationuser_access_control_defaultDefault for all devices in org
Deviceuser_access_controlPer-device override (enabled/disabled/inherit)

See Network Access Control for detailed documentation on VPN access control.

ARROW defines granular permissions across multiple categories:

PermissionDescription
users.organization.createCreate users within the organization
users.organization.deleteRemove users from the organization
users.organization.updateModify user details and role assignments
users.organization.viewView user list and details
PermissionDescription
devices.request.createSubmit new device requests
devices.request.updateModify existing device requests
devices.manageFull device management (settings, status, etc.)
devices.viewView device information
PermissionDescription
infrastructure.manageManage virtual infrastructure
infrastructure.viewView infrastructure resources
PermissionDescription
clients.createCreate new client records
clients.manageFull client management
clients.viewView client information
PermissionDescription
billing.viewAccess billing information and invoices

Permissions follow additive aggregation:

  1. Union of all role permissions - User receives all permissions from all assigned roles
  2. No permission subtraction - Higher roles cannot remove permissions granted by other roles
  3. Cached on user record - Aggregated permissions stored in users.permissions array for fast access
FilePurpose
backend/hooks/user_permissions.goPermission sync logic (lines 230-349)
backend/hooks/user_roles_validation.goRole assignment validation
backend/hooks/device_user_access.goVPN access synchronization
CollectionKey Fields
userspermissions, organization, is_site_admin
rolesname, permissions, organization_use
user_rolesuser, role
permissionsname, description