Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
Security & Multi-Tenancy
| Status | Updated | Covered Files |
|---|---|---|
| 🟢 Stable | 2026-03-14 | RBACContext.tsx, BaseService.ts, Firestore Rules, securityMonitoringService.ts, AuthContext.tsx |
Multi-Tenancy Architecture
GrantMaster uses a Logical Isolation strategy for multi-tenancy. All customers share the same database collections, but every document is strictly tied to anorganizationId.
Layers of Defense
- Frontend (Context):
TenantProviderandRBACContextensure the UI only shows data for the active organization. - Service Layer (BaseService): Every write operation checks
validateOrganizationId(orgId). This is a programmatic barrier against “ID Reference” attacks. - Backend (Firestore Rules): Security rules enforce that
request.auth.token.organizationId == resource.data.organizationId. Even if the code is bypassed, the database blocks the request.
Role-Based Access Control (RBAC)
System Roles
- SUPER_ADMIN: Full access to all organizations, imuseration (impersonation) capabilities, and platform settings.
- AUDITOR: Read-only access to specific organizations via temporary
AuditorAccessGrant. - ADMIN: Manage organization settings, users, and billing.
- MANAGER: Full access to grants and projects but no user/billing management.
- MEMBER: Standard operational access (journals, expenses, activity).
Permission Enforcement
We use a Permission Matrix approach. Instead of checking roles (e.g.,if (user.role === 'Admin')), we check capabilities:
Advanced Security Features
- Imuseration (Impersonation): SuperAdmins can switch contexts to another organization’s
organizationIdfor support. This creates anImuserationSessiontrackable in the audit logs. - Auditor Access: Auditors do not belong to an organization. Instead, they represent external regulatory bodies and are granted timed, scope-limited access to specific modules.
Security Monitoring Service (Added March 2026)
Source: src/shared/auth/securityMonitoringService.ts
A comprehensive security event logging and monitoring service integrated into the OAuth login flow via AuthContext.tsx.
Capabilities
- Event Logging:
logSecurityEvent()writes security events to Firestore with full metadata (IP, device, location). - Suspicious Login Detection:
detectSuspiciousLogin()checks for location/device changes and rapid location changes between login attempts. - Concurrent Session Detection:
detectConcurrentSessions()identifies active sessions from different IP addresses. - Account Locking:
lockUserAccount()auto-locks accounts after configurable thresholds (default: 5+ security events), logs the event, and notifies admins. - Account Unlocking:
unlockUserAccount()provides admin-controlled unlock with full audit trail. - Event Resolution:
resolveSecurityEvent()allows admins to resolve flagged security events. - Alert Configuration:
getSecurityAlertConfigs()andupdateSecurityAlertConfig()for per-org threshold configuration.
Tracked Event Types
failed_login, suspicious_login, password_change, account_locked, account_unlocked
Integration with Auth Flow
AuthContext.performOAuthLogin() now calls:
detectSuspiciousLogin()post-login to flag anomalous access patternsdetectConcurrentSessions()to identify potential credential sharinglogSecurityEvent()on both success and failure for audit completeness
Data Privacy & Compliance
- PII Protection: User profile data is restricted. Only Admins can see full employee details within an organization.
- Audit Logging: Every sensitive action (create, delete, status change) is captured in the
systemEventscollection via theEventBus. - AI Safety Guards:
responseSafety.tschecks all RAG responses for PII exposure before returning to users (see AI Engine docs).
Maintenance
Update this document when:- Adding a new
SystemRole. - Modifying the multi-tenancy rules in
firestore.rules. - Changing how
PermissionGuardresolves its logic.
Update Checklist
- Reflect changes in
src/shared/auth/contracts.ts. - Update the
permissionMatrix.tsin the code.