VOOZH about

URL: https://deepwiki.com/mathsgod/light/5-authentication-and-authorization

⇱ Authentication and Authorization | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

Authentication and Authorization

Purpose and Scope

This document describes the multi-layered security architecture of the Light framework, covering both authentication (verifying user identity) and authorization (enforcing access control). The system implements JWT-based stateless authentication with multiple authentication methods (password, 2FA, WebAuthn, OAuth providers), combined with a role-based access control (RBAC) system for fine-grained permission management.

For information about the User model structure and database fields, see Core Database Models. For session tracking implementation details, see User Model and Sessions. For detailed API documentation of authentication mutations, see AuthController.


System Overview

The Light framework implements defense-in-depth security with authentication and authorization enforced at multiple layers: request middleware level, GraphQL field level, and business logic level.

Security Architecture Diagram


Sources: src/Controller/AuthController.php1-636 src/Auth/Service.php1-141 src/Model/User.php1-389 permissions.yml1-16


Authentication Flow

The authentication process validates user credentials through multiple methods and generates JWT tokens upon successful verification.

Login Process Sequence


Sources: src/Controller/AuthController.php373-456 src/Model/User.php206-227


Authentication Methods

The Light framework supports four authentication methods that feed into a unified JWT token generation pipeline.

1. Password Authentication

Password-based authentication validates credentials using PHP's password_verify() function with support for modern bcrypt hashes and legacy hash detection.

Implementation: src/Controller/AuthController.php374-456

Key Features:

  • Brute force protection: IP-based account lockout after configurable failed attempts (default: 5 attempts in 15 minutes)
  • Password expiration: Configurable password aging policies (default: 90 days)
  • Legacy hash handling: Detects old hash formats ($5, $6 prefixes) and prompts administrator reset
  • First-run initialization: Automatically creates admin user if no users exist

Lockout Logic:

User::isAuthLocked() checks:
- Query UserLog for user_id + IP
- Count FAIL results within auth_lockout_duration (default: 15 minutes)
- Lock if failures >= auth_lockout_attempts (default: 5)

Sources: src/Controller/AuthController.php374-456 src/Model/User.php206-227

2. Two-Factor Authentication (TOTP)

Time-based one-time password (TOTP) authentication using RFC 6238 standard, compatible with Google Authenticator and other TOTP apps.

Setup Flow:

  1. User calls getMy2FA() to generate new secret
  2. System returns QR code image (data URI) and secret string
  3. User scans QR code with authenticator app
  4. User verifies setup by calling updateMy2FA(secret, code) with first TOTP code

Implementation: src/Controller/AuthController.php497-530

QR Code Generation:

URL format: otpauth://totp/{username}@{host}?secret={secret}
Generated by: Endroid\QrCode\QrCode

Verification:

  • Uses Light\Security\TwoFactorAuthentication::checkCode()
  • Accepts codes within time window (typically ±30 seconds)
  • Required on every login if user has secret field populated
  • Enforced system-wide if Config::Value('two_factor_authentication') is true

Reset Capability: Administrators with user.reset2fa permission can reset user's 2FA via reset2FA(user_id) mutation, clearing the secret field.

Sources: src/Controller/AuthController.php31-61 src/Controller/AuthController.php497-530 src/Model/User.php129-144

3. WebAuthn (Biometric Authentication)

WebAuthn/FIDO2 support for passwordless authentication using security keys, platform authenticators (Face ID, Windows Hello), or hardware tokens.

Credential Storage:

  • Stored in User::credential field as JSON array
  • Each credential contains: id, publicKey, counter, transports
  • Accessible via User::getWebAuthn() returning array of Light\Type\WebAuthn objects

Flow:

  1. Registration: Client generates key pair, server stores public key
  2. Authentication: Client signs challenge with private key, server verifies signature
  3. Multiple credentials supported per user

Sources: src/Model/User.php147-158

4. OAuth and Social Login

Integration with three OAuth providers: Google, Microsoft, and Facebook. Each provider follows a similar flow with provider-specific token validation.

Google Authentication

Login Flow: src/Controller/AuthController.php303-330


Configuration: Requires Config::Value('authentication_google_client_id')

User Linking:

  • During login: Finds User::Get(['google' => $payload['sub']])
  • During registration: Stores $payload['sub'] in user.google field
  • Unlink via unlinkGoogle() mutation (clears google field)

Sources: src/Controller/AuthController.php203-234 src/Controller/AuthController.php303-330

Microsoft Authentication

Login Flow: src/Controller/AuthController.php237-267

API Integration:

  • Validates access token via https://graph.microsoft.com/v1.0/me
  • Extracts user ID from response body
  • Matches against user.microsoft field

Configuration: Requires Config::Value('authentication_microsoft_client_id')

Sources: src/Controller/AuthController.php188-201 src/Controller/AuthController.php237-267

Facebook Authentication

Login Flow: src/Controller/AuthController.php270-300

API Integration:

  • Validates access token via https://graph.facebook.com/me?fields=id,name,email
  • Extracts Facebook user ID
  • Matches against user.facebook field

Configuration: Requires Config::Value('authentication_facebook_app_id')

Sources: src/Controller/AuthController.php121-150 src/Controller/AuthController.php270-300


JWT Token System

The Light framework uses dual-token JWT architecture with separate access and refresh tokens.

Token Structure

Access Token:


Refresh Token:


Token Lifetimes:

  • Access token: Config::Value('access_token_expire', 900) seconds (default: 15 minutes)
  • Refresh token: Config::Value('refresh_token_expire', 604800) seconds (default: 7 days)

Sources: src/App.php300-350 (from diagram context)

Cookie Storage

Tokens are stored in HTTP-only cookies with security attributes:

Access Token Cookie:


Refresh Token Cookie:


Security Features:

  • httponly: true - Prevents JavaScript access
  • samesite: Lax - CSRF protection
  • path: /refresh_token for refresh token - Limits refresh token exposure
  • secure flag when HTTPS enabled

Sources: src/Controller/AuthController.php349-367

Token Validation

JWT validation is performed by Auth\Service class during request processing.

Validation Flow:


Implementation Details:

Token Extraction: src/Auth/Service.php36-48

Priority:
1. Authorization: Bearer {token} header
2. access_token cookie

JWT Decoding: src/Auth/Service.php50-79


Revocation Check: src/Auth/Service.php58-60


View-As Mode: src/Auth/Service.php64-72

  • If payload->view_as exists, loads two users:
    • $this->user: The user being impersonated
    • $this->org_user: The original authenticated user
  • Used for administrator impersonation features

Sources: src/Auth/Service.php28-80

Token Revocation

Token revocation is implemented using a hybrid cache + database approach for immediate invalidation with audit trail.

Logout Process: src/Controller/AuthController.php333-370


Individual Session Revocation: src/Model/User.php50-54


Cache Key Format:

revoked_token_{jti}
TTL: refresh_token_expire seconds

This ensures tokens cannot be used after logout even if the JWT hasn't technically expired.

Sources: src/Controller/AuthController.php333-370 src/Model/User.php50-54


Session Management

Sessions are tracked in the UserLog model with each login creating a unique session record identified by JWT ID (jti).

Session Tracking

UserLog Fields:

  • jti: JWT ID (unique session identifier)
  • user_id: Foreign key to User
  • login_dt: Login timestamp
  • logout_dt: Logout timestamp (NULL for active sessions)
  • result: "SUCCESS" or "FAIL"
  • ip: Client IP address
  • user_agent: Browser user agent string
  • last_access_time: Updated on each request

Active Sessions Query: src/Model/User.php56-82


Session Data Structure:


Last Access Update: src/Model/User.php201-204


Called automatically during JWT validation in Auth\Service for every authenticated request.

Sources: src/Model/User.php50-82 src/Model/User.php201-204


Authorization (RBAC) System

The Light framework implements role-based access control (RBAC) with permissions defined in YAML configuration and stored in the database.

RBAC Architecture


Sources: permissions.yml1-16 menus.yml1-171 src/Model/User.php297-311

Role Hierarchy

Default Roles (permissions.yml):

RolePermissions
Administrators* (wildcard - all permissions)
Power Usersuser.list, user.read, user.add, user.delete, user.update, role.list, user.role.add, user.role.remove, user.changePassword, role.getUser
EveryoneDefault role assigned when user has no explicit roles

Role Assignment: src/Model/User.php297-311


Wildcard Permission: The Administrators role has * permission, which grants access to all operations. This is checked via:


Sources: permissions.yml1-16 src/Model/User.php297-311 src/Auth/Service.php132-134

Permission Checking

The RBAC system provides multiple methods for checking permissions at different layers of the application.

1. GraphQL Field-Level Authorization

@Logged Annotation: Requires user to be authenticated but no specific permission.


@Right Annotation: Requires specific permission(s) to access field.


Implementation: Enforced by GraphQLite's schema factory during GraphQL query execution. If permission check fails, field access is denied before method executes.

Sources: src/Controller/AuthController.php105-118

2. Programmatic Permission Checks

User::isGranted(): src/Model/User.php283-291


User::isGrantedRights(): src/Model/User.php268-280


User::getPermissions(): src/Model/User.php188-199


Sources: src/Model/User.php188-199 src/Model/User.php268-291

3. Menu-Based Path Authorization

User::isAllowedPath(): src/Model/User.php96-123

Checks if user can access a specific route path based on menu configuration.


Menu Permission Configuration (menus.yml):


Sources: src/Model/User.php96-123 menus.yml1-171

4. Auth Service Authorization

Auth\Service::isAllowed(): src/Auth/Service.php122-139

Used by GraphQLite to enforce @Right annotations.


Sources: src/Auth/Service.php122-139


Password Management

The system implements configurable password policies and secure password reset flows.

Password Expiration

Configuration:

  • Config::Value('password_expiration'): Enable/disable expiration (boolean)
  • Config::Value('password_expiration_duration', 90): Days until expiration (default: 90)

Enforcement: src/Controller/AuthController.php446-452


User Field:

  • password_dt: Timestamp of last password change
  • Updated automatically when password is changed

Sources: src/Controller/AuthController.php446-452 src/Controller/AuthController.php64-102

Password Reset Flow

The password reset process uses JWT tokens with embedded verification codes to prevent brute force attacks.

Reset Process:


JWT Payload Structure:


Rate Limiting: src/Controller/AuthController.php541-551

  • Cache key: reset_code_attempt_{code_hash}
  • Maximum 5 verification attempts per code
  • 10-minute expiration

Sources: src/Controller/AuthController.php533-594 src/Controller/AuthController.php596-635


Security Features Summary

FeatureImplementationLocation
Brute Force ProtectionIP-based lockout after 5 failed attempts in 15 minutessrc/Model/User.php206-227
Token RevocationCache-based blacklist with revoked_token_{jti} keyssrc/Controller/AuthController.php333-370
Password Hashingbcrypt via password_hash(), PASSWORD_DEFAULTsrc/Controller/AuthController.php383
JWT SigningHS256 with $_ENV['JWT_SECRET']src/Auth/Service.php51
HTTP-Only CookiesPrevents XSS token theftsrc/Controller/AuthController.php349-367
CSRF ProtectionSameSite cookie attributesrc/Controller/AuthController.php356
Session TrackingEvery login/logout logged to UserLog with IP and user agentsrc/Model/User.php56-82
2FA Rate Limiting5 attempts per 10 minutes during setupsrc/Controller/AuthController.php33-39
Password Reset Rate Limiting5 code verification attemptssrc/Controller/AuthController.php541-551
Role InheritanceWildcard * permission for Administratorspermissions.yml1-3
Field-Level Authorization@Right annotations on GraphQL fieldssrc/Controller/AuthController.php107

Sources: Multiple files as cited above.