kompo / auth
Authentication and teams to your kompo application
Installs: 1 200
Dependents: 5
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 4
Requires
- php: ^7.3|^8.0
- arcanedev/log-viewer: ^10.0
- condoedge/utils: ^0.1.1
- kompo/kompo: ^3.0
- lab404/laravel-impersonate: ^1.7
- laravel/fortify: ^1.19
- laravel/framework: >=5.6.0
- laravel/socialite: ^5.12
- laravel/vonage-notification-channel: ^3.3
- maatwebsite/excel: ^3.1
- simplesoftwareio/simple-qrcode: ^4.2
- socialiteproviders/microsoft-azure: ^5.2
- spatie/laravel-backup: ^8.1
- spatie/laravel-mail-preview: ^6.0
- dev-master
- v0.6.38
- v0.6.37
- v0.6.36
- v0.6.35
- v0.6.34
- v0.6.32
- v0.6.31
- v0.6.30
- v0.6.29
- v0.6.28
- v0.6.27
- v0.6.26
- v0.6.12
- v0.6.11
- v0.6.10
- v0.6.9
- v0.6.8
- v0.6.7
- v0.6.6
- v0.6.5
- v0.6.4
- v0.6.3
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.116
- v0.5.115
- v0.5.114
- v0.5.113
- v0.5.112
- v0.5.111
- v0.5.110
- v0.5.109
- v0.5.108
- v0.5.107
- v0.5.106
- v0.5.105
- v0.5.104
- v0.5.103
- v0.5.102
- v0.5.101
- v0.5.100
- v0.5.99
- v0.5.98
- v0.5.97
- v0.5.96
- v0.5.95
- v0.5.94
- v0.5.93
- v0.5.92
- v0.5.39
- v0.5.38
- v0.5.37
- v0.5.36
- v0.5.35
- v0.5.34
- v0.5.33
- v0.5.32
- v0.5.31
- v0.5.30
- v0.5.29
- v0.5.28
- v0.5.27
- v0.5.26
- v0.5.25
- v0.5.24
- v0.5.23
- v0.5.22
- v0.5.21
- v0.5.20
- v0.5.19
- v0.5.18
- v0.5.17
- v0.5.16
- v0.5.15
- v0.5.14
- v0.5.13
- v0.5.12
- v0.5.11
- v0.5.10
- v0.5.8
- v0.5.7
- v0.5.6
- v0.5.5
- v0.5.4
- v0.5.3
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.89
- v0.4.88
- v0.4.87
- v0.4.86
- v0.4.85
- v0.4.84
- v0.4.83
- v0.4.82
- v0.4.81
- v0.4.80
- v0.4.79
- v0.4.75
- v0.4.74
- v0.4.73
- v0.4.72
- v0.4.71
- v0.4.70
- v0.4.69
- v0.4.68
- v0.4.67
- v0.4.65
- v0.4.64
- v0.4.63
- v0.4.62
- v0.4.61
- v0.4.60
- v0.4.59
- v0.4.58
- v0.4.57
- v0.4.56
- v0.4.55
- v0.4.54
- v0.4.53
- v0.4.52
- v0.4.51
- v0.4.50
- v0.4.49
- v0.4.48
- v0.4.47
- v0.4.46
- v0.4.43
- v0.4.42
- v0.4.41
- v0.4.40
- v0.4.39
- v0.4.38
- v0.4.37
- v0.4.36
- v0.4.34
- v0.4.33
- v0.4.32
- v0.4.31
- v0.4.30
- v0.4.29
- v0.4.28
- v0.4.27
- v0.4.26
- v0.4.25
- v0.4.23
- v0.4.22
- v0.4.21
- v0.4.20
- v0.4.19
- v0.4.18
- v0.4.17
- v0.4.16
- v0.4.15
- v0.4.14
- v0.4.13
- v0.4.12
- v0.4.11
- v0.4.10
- v0.4.9
- v0.4.8
- v0.4.7
- v0.4.6
- v0.4.5
- v0.4.4
- v0.4.3
- v0.4.2
- v0.4.1
- v0.3.28
- v0.3.27
- v0.3.26
- v0.3.25
- v0.3.24
- v0.3.23
- v0.3.21
- v0.3.20
- v0.3.19
- v0.3.18
- v0.3.17
- v0.3.16
- v0.3.15
- v0.3.13
- v0.3.12
- v0.3.11
- v0.3.10
- v0.3.9
- v0.3.8
- v0.3.7
- v0.3.6
- v0.3.5
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.2.24
- v0.2.23
- v0.2.22
- v0.2.21
- v0.2.20
- v0.2.19
- v0.2.18
- v0.2.17
- v0.2.16
- v0.2.15
- v0.2.14
- v0.2.13
- v0.2.12
- v0.2.11
- v0.2.10
- v0.2.9
- v0.2.8
- v0.2.7
- v0.2.6
- v0.2.5
- v0.2.4
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.10
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1
- dev-migration-to-utils
- dev-just-one-role-restriction
- dev-roles-visuals
- dev-roles
This package is auto-updated.
Last update: 2025-05-20 00:01:13 UTC
README
Overview
Kompo Auth is a comprehensive authorization and authentication package designed to provide a complete role and permission management system for Laravel applications. The package abstracts complex security logic into simple database configurations, requiring minimal code changes to your models and components.
Key Features
- Role-based access control (RBAC) across your entire application
- Team-based permissions with hierarchy support
- Multiple permission types (READ, WRITE, ALL, DENY)
- Automatic security checks on models and components
- Permission caching for optimal performance
- Sensitive field protection to hide specific model attributes
Installation
1. Install the package using Composer
composer require kompo/auth
2. Run migrations
php artisan migrate
3. Publish configuration files
php artisan vendor:publish --provider="Kompo\Auth\KompoAuthServiceProvider"
4. Add styles (optional)
// In resources/scss/app.scss @import "kompo/auth";
Automatic Security System (Fast usage)
(You can just use the next steps into the db to get a fast authorizated app. For more details you can see also the next parts and get more about more specific usage, bypass and structure)
Kompo Auth uses naming conventions and model properties to automatically enforce security across your application:
Permission Keys Naming Conventions
The system automatically restricts access based on these naming patterns:
- Model Class Names: Each model is automatically protected using its class name as the permission key
Example
User
model is protected by the User
permission key
Project
model is protected by the Project
permission key
- Component Class Names: Components are protected using their class name as the permission key
Example
AssignRoleModal
component is protected by the AssignRoleModal
permission key
- Sensitive Field Protection: Add
.sensibleColumns
suffix to model name to control field visibility. (You should've set $sensibleColumns property into the model to enable this).
Example
User.sensibleColumns
permission controls access to sensitive user fields.
Seed-Based Permission Configuration
The recommended workflow is:
-
Seed All Permission Records: Create database records for all models and components
// In your database seeder Permission::create([ 'permission_key' => 'User', 'permission_name' => 'User Management', 'permission_section_id' => $adminSection->id, ]); Permission::create([ 'permission_key' => 'User.sensibleColumns', 'permission_name' => 'Access to sensitive user fields', 'permission_section_id' => $adminSection->id, ]);
-
Grant Permissions to Roles: Assign appropriate permission types to each role
$adminRole->permissions()->attach($userPermission->id, ['permission_type' => PermissionTypeEnum::ALL]); $editorRole->permissions()->attach($userPermission->id, ['permission_type' => PermissionTypeEnum::WRITE]); $viewerRole->permissions()->attach($userPermission->id, ['permission_type' => PermissionTypeEnum::READ]);
-
Result: Security is enforced automatically throughout your application with minimal code
Visual Components for Role Management
Kompo Auth includes powerful visual components for managing roles and permissions:
-
Roles and Permissions Matrix: A comprehensive interface for setting permissions
// Add to your admin panel new RolesAndPermissionMatrix()
-
Role Assignment Modal: For assigning roles to users within teams
_Button('Assign Role')->selfGet('getAssignRoleModal')->inModal() public function getAssignRoleModal() { return new AssignRoleModal([ 'user_id' => $userId, 'team_id' => $teamId, // Optional ]); }
-
Team Member Management: Components for inviting and managing team members with specific roles
new TeamMembersList(['team_id' => $teamId])
The visual interface allows administrators to:
- Assign fine-grained READ, WRITE, ALL, or DENY permissions
- Group permissions by sections for better organization
- Apply permissions to entire sections with a single click
- Set role hierarchies with inheritance options
- Dynamic role selector: A team role switcher when you can impersonate different team_roles
new OptionsRolesSwitcher()
Authorization System Design
Database Structure
The package uses the following tables to manage roles and permissions:
users
: Standard user informationteams
: Team information with owner referenceroles
: Role definitions with profile settingspermission_sections
: Organizational grouping of permissionspermissions
: Individual permission definitions with keyspermission_role
: Associates permissions with rolesteam_roles
: Associates users with teams and assigns rolespermission_team_role
: Direct permission overrides for user-team combinations
Database Diagram
View or edit diagram on dbdiagram.io
Team Hierarchy & Role Inheritance
Kompo Auth provides a sophisticated team hierarchy system with dynamic role creation based on inheritance settings:
Teams Organization
Teams can be organized in parent-child relationships, creating a tree structure:
Root Team
├── Child Team 1
│ ├── Grandchild Team 1
│ └── Grandchild Team 2
└── Child Team 2
└── Grandchild Team 3
- Root Team: The top-level team, usually representing an organization or a major division.
- Child Teams: Teams that belongs to a parent team, including grandchild teams.
- Neighboring Teams: Teams that are at the same level in the hierarchy.
Teams Hierarchy
Team roles can accept inheritance so the user that has them will have the permissions on all the children teams or neighbouring teams.
The role_hierarchy column on team_roles depends on the RoleHierarchyEnum
that defines how permissions cascade through team hierarchies:
DIRECT: Access limited to only the specific team DOWN Access extends to the team and all its children SIBLINGS: Access extends to the team and its sibling teams DOWN_AND_SIBLINGS: Access extends to the team, its children, and siblings
The roles must accept those configurations on the accept_roll_to_children and accept_roll_to_neighbour fields.
Lazy Role Creation
The basic team roles are created when you assign them to an user. But in the roles switcher you can see all the inherited teams and they will be created dynamically so you can enter to their dashboard.
When you try to set an unexistent role as your current role and you have a team role that allows inheritance it'll be created it in that moment using TeamRole::getParentHierarchyRole()
inside of TeamRole::getOrCreateForUser()
Permission Types
Kompo Auth uses a bitmask system for permission types:
READ (1)
: View-only accessWRITE (3)
: Read and write access (includes READ)ALL (7)
: Complete access (includes READ and WRITE)DENY (100)
: Explicitly denies access, overriding other permissions
Security Implementation
Model-Level Security
Kompo Auth automatically protects your models by adding global scopes and event listeners. To enable security on a model:
- Ensure your model extends
Condoedge\Utils\Models\Model
(includes the HasSecurity plugin) - Add permission records in the database that match your model name
- Configure security restrictions through model properties (optional):
// Control security behavior with these properties protected $readSecurityRestrictions = true; protected $saveSecurityRestrictions = true; protected $deleteSecurityRestrictions = true; protected $restrictByTeam = true; // Define sensitive fields that require special permission protected $sensibleColumns = ['secret_field', 'confidential_data'];
Bypass Security When Needed
There are several ways to bypass security checks when necessary:
// Use system methods for privileged operations $model->systemSave(); $model->systemDelete(); // Set bypass flag before operation $model->_bypassSecurity = true; $model->save(); // Remove global scopes for a specific query Model::withoutGlobalScope('authUserHasPermissions')->get();
Automatic User Access to Own Records
The security system ensures users always have access to their own records, regardless of their role-based permissions. This prevents users from being locked out of their own data.
How it works:
-
User ID based automatic bypass:
// When a model has a user_id column matching the authenticated user, // security restrictions are automatically bypassed // This is built into HasSecurity plugin and requires no additional code
-
Define user ownership scope:
// For more complex ownership relationships, define this scope in your model: public function scopeUserOwnedRecords($query) { // Define your logic for identifying records owned by current user // Examples: return $query->where('user_id', auth()->id()); // Or for more complex relationships: return $query->where('creator_id', auth()->id()) ->orWhereHas('participants', function($q) { $q->where('user_id', auth()->id()); }); }
-
Custom user access method:
// For even more complex scenarios, you can define: public function usersIdsAllowedToManage() { // Return array of user IDs that should have access regardless of permissions return [$this->user_id, $this->manager_id, $this->company->owner_id]; }
This ownership system ensures that:
- Users always see their own records in queries
- Users can edit their own records even without explicit permissions
- Custom ownership relationships can be easily defined
- Security remains tight for non-owned records
Implementation Notes:
- The bypasses only apply to the authenticated user's own records
- This works automatically with the global scope applied to queries
- During save/delete operations, the system checks for ownership before enforcing permissions
- Always consider adding a
bypassToAuthenticatedUser
scope to your models for clarity
Component-Level Security
For Kompo components (forms, tables, etc.), security is provided through the HasAuthorizationUtils
plugin:
Using the checkAuth Macro
The checkAuth
macro allows you to conditionally show or hide UI elements based on user permissions:
// Basic syntax _Button('Create user')->checkAuth('User'); // Example with nested components _Rows( _Html('Access to people')->checkAuth('Person'), _Link('View details')->checkAuth('Project', PermissionTypeEnum::READ), _Button('Edit profile')->checkAuth('User', PermissionTypeEnum::WRITE) );
checkAuth Parameters:
// checkAuth(resource, permission type, team, message) _Button('Delete') ->checkAuth( 'Record', // Resource to check $teamId, // Team ID (optional) false // Retun null instead of a void element );
If permission is denied, the element:
- Is will be rendered using null data
- Or it will return a fully null
Implementation Strategies
Kompo Auth offers two main approaches for implementing security based on your project needs:
1. "Security First" Approach (Recommended)
Everything is restricted by default and permissions are explicitly granted:
// In your models (default settings) class Document extends Model { // No configuration needed - security is enabled by default } // In your database // Create permissions for each resource and assign them to specific roles
Benefits:
- Maximum security: nothing is accessible without explicit permission
- Granular control over all resources
- Ideal for applications with sensitive data
Implementation steps:
- Create permissions for each model and component
- Assign these permissions to specific roles
- Resources without permission will not be accessible
2. "Progressive Security" Approach
Start with minimal restrictions and add security as needed:
// In config/kompo-auth.php 'security' => [ 'default-read-security-restrictions' => false, 'default-save-security-restrictions' => false, ] // Then activate security only on specific models class SensitiveDocument extends Model { protected $readSecurityRestrictions = true; protected $saveSecurityRestrictions = true; }
Benefits:
- Easier gradual implementation
- Works well for migrating existing systems
- Allows protecting only critical operations
Manual checks:
// Explicit checks where needed if (!auth()->user()->hasPermission('Report', PermissionTypeEnum::WRITE)) { return redirect()->back()->withErrors('Unauthorized'); }
Practical Example
A typical security implementation flow:
-
Permission design:
- Identify critical resources (users, payments, settings)
- Define sensitive operations (deleting records, changing roles)
-
Implementation:
// In sensitive models protected $readSecurityRestrictions = true; protected $sensibleColumns = ['confidential_data']; // In UI for critical elements _Button('Delete account')->checkAuth('User', PermissionTypeEnum::ALL);
-
User verification:
// Check if user can view a specific resource if ($user->hasPermission('Project', PermissionTypeEnum::READ, $teamId)) { // Show resource }
This flexible approach allows you to adjust the security level according to your application's specific needs.
Common Usage Patterns
Check If User Has Permission
if (auth()->user()->hasPermission('User', PermissionTypeEnum::READ)) { // User can read User records } // Check for team-specific permission if (auth()->user()->hasPermission('Post', PermissionTypeEnum::WRITE, $teamId)) { // User can write to Posts in the specific team }
Know if the team it's inside of the team
This will check if there's a team_roles record linking the team to the user. It allows also hierarchy so if the role it's rolled down to children and the user is into a parent team it'll return true
$teamIds = auth()->user()->hasAccessToTeam($teamId)
Find Teams With Permission
// Get all teams where user can manage Projects $teamIds = auth()->user()->getTeamsIdsWithPermission('Project', PermissionTypeEnum::WRITE);
Grant Permission To User (NOT Recommended yet)
// Give a user permission directly on their current team role auth()->user()->givePermissionTo('CreateReports'); // Or specify a team role auth()->user()->givePermissionTo('ManageUsers', $teamRoleId);
Developer Guide: Package Architecture
This section provides a streamlined view of how the package works internally, its key components, and how to effectively implement and debug permission-related issues.
Core Components & Flow
┌─────────────────────────┐
│ KompoAuthServiceProvider│◄──────────────┐
└───────────┬─────────────┘ │
│ │
▼ │
┌───────────────────────┐ ┌───────────────┐
│ HasSecurity │◄───┤ Models │
│ (Model Plugin) │ │ │
└───────────┬───────────┘ └───────────────┘
│
│
┌───────────▼───────────┐ ┌───────────────┐
│ HasAuthorizationUtils │◄───┤ UI Elements │
│ (Component Plugin) │ │ │
└───────────────────────┘ └───────────────┘
┌───────────────────────┐ ┌───────────────┐
│ HasTeamsTrait │◄───┤ User Model │
│ │ │ │
└───────────────────────┘ └───────────────┘
Key Files & Responsibilities
File | Responsibility |
---|---|
KompoAuthServiceProvider.php |
Bootstrap, registers services, binds model plugins |
HasSecurity.php |
Model security: global scopes, event listeners for CRUD operations |
HasAuthorizationUtils.php |
UI security: form/query/component permission checks |
HasTeamsTrait.php |
User permissions, team management, permission caching |
Permission.php |
Permission storage and retrieval |
TeamRole.php |
Team-user-role relationships and inheritance |
Security Enforcement Sequence
1. Query Builder Created
└─> HasSecurity global scope triggered
└─> Check for global bypass
└─> No bypass: Apply permission filters
└─> Check for team context
└─> Restrict to authorized teams
└─> Check for user ownership
└─> Allow access to owned records
Model Read Operation:
// Check permission existence Permission::findByKey('User')->exists(); // Test permission with debug mode auth()->user()->hasPermission('User', PermissionTypeEnum::READ, null, true); // Check team permissions auth()->user()->hasAccessToTeam($teamId); $teamsWithAccess = auth()->user()->getTeamsIdsWithPermission('Resource'); // Cache inspection \Cache::get('currentPermissions' . auth()->id()); \Cache::tags(['permissions'])->flush(); // Force clear cache
Developer Guide: Authorization Flow
Understanding how the KompoAuth package processes security checks can help you implement permissions correctly and debug access issues. This section explains the key workflows in the authorization system.
Permission Check Workflow
┌─────────────────┐ ┌──────────────────┐ ┌───────────────────┐
│ hasPermission │────▶│ Get Permissions │────▶│ Check Permission │
│ Request │ │ From Cache │ │ Match │
└─────────────────┘ └──────────────────┘ └───────────────────┘
-
Initial Check:
$user->hasPermission('Resource', PermissionTypeEnum::READ, $teamId)
- First checks if security is globally bypassed
- Retrieves cached permissions for user (either all teams or specified teams)
-
Permission Resolution:
- Formats permission key to standard format
- Checks if any permission in cache matches requested key and type
- Considers DENY permissions which override other permissions
-
Team Context:
- Without team context: checks permissions across all teams
- With team context: checks only permissions applicable to specified team(s)
- Considers team hierarchies (parent/child relationships)
Model Security Flow
-
Query Filtering:
- Global scope automatically filters records based on permissions
- For team-restricted models, limits to authorized teams
- Special bypass logic ensures users can always access their own records
-
Write Operations:
- Before save: checks if user has WRITE permission
- Before delete: checks if user has WRITE permission
- Owner bypass: automatically allows users to modify their own records
-
Field Protection:
- After retrieval: checks for sensitive fields
- Removes sensitive fields if user lacks required permission
- Applies only if model defines sensibleColumns property
Component Authorization Flow
┌─────────────┐ ┌───────────────┐ ┌─────────────────┐
│ Component │────▶│ checkAuth() │────▶│ Visible/Hidden │
│ Render │ │ Macro │ │ Element │
└─────────────┘ └───────────────┘ └─────────────────┘
-
Component Rendering:
- During boot: verifies READ permission for component
- Permission key derived from component class name
- Hidden if permission check fails
-
Element Display Control:
checkAuth()
macro verifies permission for UI elements- Conditionally renders elements based on permission result
- Can include fallback behavior for unauthorized state
-
Form Submission:
- Before processing: verifies WRITE permission
- Forms automatically inherit permission checks from their class name
- Provides consistent security between UI and backend
Bypass Mechanisms
The security system includes several bypass mechanisms that work in this order:
- SuperAdmin Email: Users with emails listed in
config('superadmin-emails')
bypass all security checks - Global Bypass:
config('kompo-auth.security.bypass-security')
setting - Custom Bypass Method:
isSecurityBypassRequired()
on model - User ID Match: Automatic bypass when
user_id
matches authenticated user - Custom Users List:
usersIdsAllowedToManage()
method on model - Custom Scope:
scopeUserOwnedRecords()
method on model - Explicit Flag:
$model->_bypassSecurity = true
attribute - System Methods:
$model->systemSave()
and$model->systemDelete()
These mechanisms ensure that while security is enforced consistently, there are appropriate methods to bypass it when necessary, particularly for allowing users to access their own records.
Debugging Permission Issues
When troubleshooting access problems:
-
Check Cache: Permission results are cached. Clear cache with
php artisan cache:clear
to ensure fresh checks. -
Verify Permissions: Ensure the permission exists in the database:
// Does the permission exist? \Kompo\Auth\Models\Teams\Permission::findByKey('User') // Does user have access? (Debug mode) auth()->user()->hasPermission('User', PermissionTypeEnum::READ, null, true)
-
Check Bypass Logic: For model access, ensure appropriate bypass methods are defined:
// Add this scope to your model public function scopeUserOwnedRecords($query) { // Logic to identify user's own records return $query->where('user_id', auth()->id()); }
-
Examine Team Hierarchy: Team permissions can be affected by parent/child relationships.
Remember that the security system is designed to be restrictive by default - you need to explicitly grant permissions for users to access resources.