User & Role Management Guide
How to invite users, assign roles, manage permissions, and enforce access control
Users, Roles & Teams
A User is an account in your tenant. Each user is assigned exactly one Role. A role bundles multiple Permissions. Users are also assigned to a Team for organizational grouping. Teams have no impact on permissions or authorization – they are separate from roles. Changing a team does not change what a user can do; only the role (or direct permission overrides) does.
User
- Identity: Name + email invited to tenant
- Status: Pending (invitation) or Active
- Exactly One Role: Required at invite
- Team Required: Operational grouping only
Role
- Definition: Named bundle of permissions
- Source: Spatie Permission tables (tenant DB)
- Change Path: Role dropdown on Users page
- Overrides: Add/remove direct permissions if needed
Team
- Purpose: Organize users for reporting & leadership
- No Auth Power: Provides zero permissions
- Pivot Data: Includes optional position (leader/member)
- Leaders: Gain visibility (when combined with permissions)
User Invitation Flow
- 1Open Users page and click Invite User (requires
View Users&Create Userpermissions). - 2Fill modal fields: Name, Email, Role, Team. All are validated in
UserController::create. - 3System enforces subscription user limit (existing users + pending invitations). If limit reached an error is returned.
- 4Invitation stored (
tenant_invitations): email, role, team_id, token, expiry (7 days) andTenantInvitationMailis sent. - 5User accepts link → account associated to tenant → role applied → team pivot row created.
Changing a Role
Use the role select in the Users table (calls UserController::changeUserRole → $user->syncRoles()).
- Immediate effect (Spatie cache updated)
- Does not alter team membership
- Consider adding audit logging (future improvement)
Direct Permission Overrides
Permissions modal toggles entries in model_has_permissions. Use sparingly—prefer adjusting the underlying role.
Teams (Operational Layer Only)
The Team model links users through the team_user pivot (tenant DB) with an optional position like leader. Leaders gain expanded visibility (e.g. time worked, captures) when combined with the correct permissions (e.g. View All Captures or similar gates). No permission inheritance comes from team membership itself.
- No automatic permissions granted
- Moving a user between teams never requires role change
- Default "Break" project auto-created on team creation (
Team::booted()) - Leadership checked via pivot position filters
User Lifecycle
- Invite: Record created & email sent.
- Acceptance: User activates, role + team assignment applied.
- Active: Role adjustments, wage/session type management, permission overrides.
- Disconnection: Remove action detaches user from tenant (does not hard delete base user record).
Best Practices
- Create core roles (Admin, Manager, Contributor) before inviting users.
- Minimize direct permission overrides; keep roles authoritative.
- Use teams for reporting segmentation and leadership scopes only.
- Review pending invitations & expired tokens regularly.
- Plan audit logging for regulated environments.
UserController, Team model, and resources/views/pages/users/index.blade.php.Was this article helpful?