Security Debug Information Display
Overview
The Security Debug Information feature provides developers and administrators with detailed insights into the authorization system during development. This feature displays user policies and tracks all authorization checks performed during a page request.
Features
1. Debug Mode Only
- Only active when
Configure::read('debug')istrue - No performance impact in production environments
- Authorization tracking is conditionally enabled
2. User Policies Display
Shows all policies assigned to the current user with:
- Policy class and method names
- Scoping rules (Global, Branch Only, Branch and Children)
- Associated branch IDs
3. Authorization Check Log
Tracks and displays all authorization checks performed during the request:
- Action being checked (e.g., ‘view’, ‘edit’, ‘delete’)
- Resource being accessed (entity type and ID)
- Result (granted or denied)
- Additional arguments passed to policy methods
- Sequential order of checks
4. Interactive UI
- Toggle button in the footer: “Show Security Info”
- Smooth slide animations
- Responsive Bootstrap-styled tables
- Color-coded results (green for granted, red for denied)
Architecture
Components
1. AuthorizationService (src/Services/AuthorizationService.php)
Enhanced to track authorization checks:
public function checkCan(?KmpIdentityInterface $user, string $action, $resource, ...$optionalArgs): bool
{
// ... authorization logic ...
// Only log in debug mode
if (\Cake\Core\Configure::read('debug')) {
$this->logAuthCheck($user, $action, $resource, $resultBool, $optionalArgs);
}
return $resultBool;
}
Key methods:
logAuthCheck()- Records authorization attemptsgetAuthCheckLog()- Retrieves log for displayclearAuthCheckLog()- Clears the log
2. SecurityDebugHelper (src/View/Helper/SecurityDebugHelper.php)
View helper for rendering security information:
displaySecurityInfo()- Main display methoddisplayUserPolicies()- Renders user policy tabledisplayAuthorizationChecks()- Renders authorization check log
3. Stimulus Controller (assets/js/controllers/security-debug-controller.js)
JavaScript controller for interactive UI:
- Toggle visibility of debug panel
- Smooth animations
- Session-persistent state
4. Footer Template (templates/element/copyrightFooter.php)
Integrated display in application footer:
- Only visible in debug mode
- Accessible from any page
- Non-intrusive placement
Usage
Viewing Security Information
- Enable debug mode in
config/app.phporconfig/.env:'debug' => true, -
Navigate to any page in the application while logged in
-
Scroll to the footer and click “Show Security Info”
- Review:
- Your assigned policies and their scope
- All authorization checks performed on the page
- Which checks passed or failed
Interpreting Policy Display
Policy Table Columns:
- Policy Class: The policy handling authorization (e.g.,
MemberPolicy) - Method: The specific check method (e.g.,
canView,canEdit) - Scope: Authorization scope
- 🔵 Global: Access to all branches
- 🔵 Branch Only: Access limited to specific branches
- 🟢 Branch + Children: Access to branch and descendants
- Branches: Specific branch IDs (or “All branches” for global)
Interpreting Authorization Log
Log Table Columns:
- #: Sequential order of checks
- Action: The action being checked (e.g., ‘view’, ‘edit’)
- Resource: Entity being accessed (e.g., ‘Member #123’)
- Result: ✓ Granted (green) or ✗ Denied (red)
- Args: Number of additional arguments passed
Color Coding:
- 🟢 Green row: Authorization granted
- 🔴 Red row: Authorization denied
Development Workflow
Debugging Authorization Issues
-
Reproduce the issue: Navigate to the page with authorization problems
-
Check the log: Click “Show Security Info” to see all authorization checks
-
Identify failed checks: Look for red (denied) entries
-
Verify user policies: Confirm the user has the required policy/method
-
Check scope: Ensure branch IDs match if scope is branch-specific
Common Scenarios
Scenario 1: User can’t access a page
- Look for denied checks early in the log
- Verify user has the policy method (e.g.,
canView) - Check if branch scope matches the resource
Scenario 2: Button/action is hidden
- Find the authorization check for that action
- Verify the policy method exists for the user
- Check if the check is even being performed
Scenario 3: Unexpected access granted
- Look for checks that succeed unexpectedly
- Verify scoping rules are correct
- Check if user has unintended global permissions
Performance Considerations
Debug Mode Only
- Authorization tracking only occurs when debug mode is enabled
- Zero performance impact in production
- Log data is stored in memory for the request duration
Memory Usage
- Log entries are lightweight (< 1KB each typically)
- Cleared at end of request
- No database or file I/O
Best Practices
- Don’t enable debug mode in production
- Use this feature during development and testing
- Clear understanding of authorization flow before production deployment
Security Considerations
Information Exposure
- Only available in debug mode
- Assumes debug mode is disabled in production
- Does not expose passwords or sensitive credentials
- Shows authorization structure, not data content
Production Safety
Multiple layers prevent accidental exposure:
- Debug mode configuration check
- Button only rendered in debug mode
- Tracking only occurs in debug mode
- Helper returns empty string if not in debug mode
Integration with KMP Authorization System
Policy System
Works with KMP’s existing policy infrastructure:
BasePolicyand derived policy classes_hasPolicy()method for permission checks- Branch scoping (Global, Branch Only, Branch and Children)
- Permission-based authorization
Identity System
Integrates with KmpIdentityInterface:
getPolicies()- Retrieves user policiesisSuperUser()- Super user detection- Permission and role system
Troubleshooting
Security Info Not Visible
Problem: “Show Security Info” button doesn’t appear
Solutions:
- Verify debug mode is enabled:
Configure::read('debug') - Clear cache:
bin/cake cache clear_all - Check browser console for JavaScript errors
Empty Authorization Log
Problem: No checks appear in the log
Solutions:
- Ensure page performs authorization checks
- Verify you’re logged in
- Some pages may not require authorization
Incorrect Policy Display
Problem: Policies shown don’t match expectations
Solutions:
- Clear permission cache:
bin/cake cache clear _kmp_cache_ - Verify user roles and permissions in database
- Check
PermissionsLoaderconfiguration
Future Enhancements
Potential improvements:
- Filter log by action type
- Export log to JSON/CSV
- Stack trace for each authorization check
- Policy rule explanation
- Performance metrics (time per check)
- Historical comparison across requests
Related Documentation
Code References
Modified Files
app/src/Services/AuthorizationService.php- Authorization trackingapp/src/View/Helper/SecurityDebugHelper.php- Display helperapp/src/View/AppView.php- Helper registrationapp/templates/element/copyrightFooter.php- UI integrationapp/assets/js/controllers/security-debug-controller.js- Interactive UIapp/assets/js/index.js- Controller registration
Key Classes
\App\Services\AuthorizationService- Core authorization with tracking\App\View\Helper\SecurityDebugHelper- Security info rendering\App\Policy\BasePolicy- Base policy with branch scoping\App\KMP\KmpIdentityInterface- User identity interface
Example Output
User Policies Table
┌──────────────────┬─────────────────┬───────────────────────┬──────────────┐
│ Policy Class │ Method │ Scope │ Branches │
├──────────────────┼─────────────────┼───────────────────────┼──────────────┤
│ MemberPolicy │ canView │ 🔵 Global │ All branches │
│ │ canEdit │ 🔵 Branch Only │ 1, 5, 12 │
│ │ canDelete │ 🟢 Branch + Children │ 1, 5 │
└──────────────────┴─────────────────┴───────────────────────┴──────────────┘
Authorization Check Log
┌───┬─────────┬──────────────┬────────────┬──────┐
│ # │ Action │ Resource │ Result │ Args │
├───┼─────────┼──────────────┼────────────┼──────┤
│ 1 │ view │ Member #123 │ ✓ Granted │ 0 │
│ 2 │ edit │ Member #123 │ ✓ Granted │ 1 │
│ 3 │ delete │ Member #456 │ ✗ Denied │ 0 │
└───┴─────────┴──────────────┴────────────┴──────┘