Tenant Isolation Architecture
Every agency lives in its own secure data silo
BelongsToTenant Global Scope
Every database model (Invoices, Clients, Contracts, Expenses, etc.) uses a BelongsToTenant trait that automatically appends a WHERE tenant_id = ? clause to every single database query — making cross-tenant data access architecturally impossible.
Tenant Middleware Enforcement
A dedicated TenantMiddleware is applied to every protected route. It verifies authentication, checks account status (active, trial, suspended), and gates access before any controller or Livewire component is ever reached.
Auth ID as Tenant Identity
Each authenticated user is their own tenant. The system uses Auth::id() as the tenant boundary — no shared user pools, no ambiguous role mappings. Your login session only ever sees your own data.
Shared Tables, Isolated Data
All tenants share the same database tables but with strict tenant_id column isolation enforced at the ORM layer. This means zero possibility of query results crossing tenant boundaries — even from internal admin tools.
Authentication & Access Security
Multi-layered identity verification
Mandatory TOTP 2FA
All agency accounts require Google Authenticator-based Two-Factor Authentication. Even if your password is stolen, your account cannot be accessed without your phone.
OTP-Based Password Reset
Password resets are handled via time-limited, 6-digit OTP codes sent to your verified email — not insecure URL tokens that can be shared or forwarded.
Rate Limiting
Login, OTP verification, and 2FA challenge endpoints are protected by aggressive rate limiting — 5 failed attempts trigger a 15-minute IP-level lockout to block brute-force attacks.
Secure Google OAuth
Google sign-in is handled via Laravel Socialite. Google-linked accounts have their login email locked to prevent OAuth session hijacking through email reassignment.
Email Change OTP Verification
Changing your login email requires confirming a 6-digit OTP sent to the new address — with resend rate limits (60 seconds wait, max 3 attempts, then 30-minute lockout).
IP Tracking & Reg Limits
IP addresses are recorded at registration. A maximum of 3 accounts can be created per IP address per hour to prevent mass fraudulent sign-ups.
Data & Credential Protection
Encryption at rest for sensitive fields
Bcrypt Password Hashing
All user passwords are stored using Laravel's default bcrypt hashing algorithm. Passwords are never stored in plain text — not even admins can see them. The only way in is through your own credentials.
Encrypted SMTP Credentials
Custom SMTP credentials you configure for outgoing emails are stored using Laravel's Crypt::encryptString() — AES-256-CBC encryption. They are decrypted only at runtime when sending email.
Database-Only Storage
Sensitive files — logos, payment proofs, receipts, and contract PDFs — are stored as Base64 directly in the database rather than on a shared filesystem. This eliminates any risk of server path traversal or unauthorized file access.
Soft Deletes & Audit Trails
All critical models use Laravel's SoftDeletes — deleted records are flagged, not permanently erased, preserving financial audit integrity and protecting against accidental or malicious data loss.
Contract & Client Portal Security
Protected public-facing document flows
Identity Gateway OTP
Before a client can read or sign a contract, they must verify their identity with a 6-digit OTP sent to their email. The contract content is fully blurred and unrendered in the DOM until verification succeeds.
Secure Token URLs
Contract and proposal public links are generated with unique, non-guessable tokens. There are no sequential IDs in public-facing URLs — each token is cryptographically unique to that document.
E-Signature Timestamping
Every e-signature captures the signer's name, email, IP address, and exact timestamp — creating a tamper-evident digital audit record that is permanently stored with the signed contract.
Admin Access Controls
Auditable super admin operations
Impersonation with Session Audit
Super Admins can impersonate tenant accounts for support purposes. Every impersonation session is visually flagged with a persistent amber banner showing exactly which tenant is being accessed, and a one-click "Exit Impersonation" button.
Email Audit Logs
Every email sent through Xpendee — invoices, receipts, contracts, notifications — is automatically logged with recipient, subject, category, status, and timestamp. Both tenants and admins can audit their full email history at any time.
Built on Trust, Backed by Architecture
Xpendee's security is not an afterthought — it's woven into every query, every route, and every session. Your agency data is legally and technically yours alone.