Security Model
12-layer security fortress designed to be "AI-resistant". Every query encrypted, every mutation audited, every session fingerprinted. DPDP Act compliant.
Security Layers
| # | Layer | Implementation | File |
| 1 | Field-Level Encryption | AES-256-GCM + HKDF per-society keys | crypto.ts |
| 2 | Session Management | 15min JWT + 7d httpOnly refresh cookie + device fingerprinting | sessionManager.ts |
| 3 | RBAC Permission Matrix | 15 roles, 67 permissions, KV-cached | rbac.ts |
| 4 | Rate Limiting | Per-user + per-IP + per-endpoint, 5 tiers | enhancedRateLimit.ts |
| 5 | Request Signing | HMAC-SHA256 nonce + timestamp | requestSigning.ts |
| 6 | Anomaly Detection | 6-signal behavioral analysis, auto MFA challenge | anomalyDetection.ts |
| 7 | Security Headers | Nonce-based CSP, HSTS, X-Frame-Options DENY | securityHeaders.ts |
| 8 | DPDP Act Compliance | 14 consent purposes, 6 data subject rights | dpdp.ts |
| 9 | Audit Log | Immutable hash-chain (prev_hash → record_hash) | auditLogger.ts |
| 10 | Output Sanitization | Auto-strip PII from responses | outputSanitization.ts |
| 11 | MFA (TOTP) | Secret + QR + backup codes + lockout | mfa.ts |
| 12 | Secure Storage | httpOnly refresh cookie, sessionStorage (not localStorage) | sessionManager.ts |
Encryption
// Field-level encryption: every PII field encrypted per-society
// Key derivation: HKDF from master ENCRYPTION_MASTER_KEY + society_id
// Algorithm: AES-256-GCM (authenticated encryption)
// Encrypted fields include:
// - users.phone, users.email (at rest)
// - mfa_secrets.totp_secret
// - encryption_keys.key_material
// - whatsapp_config.access_token
// - api_keys.key_hash
JWT Structure
{
"sub": "user-id",
"iat": 1720000000,
"exp": 1720000900, // 15 minutes
"active_context": {
"persona_id": "persona-uuid",
"tenant_id": "society-uuid",
"role": "SOCIETY_ADMIN",
"unit_id": "flat-uuid",
"permissions": ["billing.view", "billing.create", ...]
},
"available_contexts": [
{ "persona_id": "...", "role": "SOCIETY_ADMIN", "tenant_id": "..." },
{ "persona_id": "...", "role": "RESIDENT", "tenant_id": "..." }
]
}
MFA (Multi-Factor Authentication)
| Step | Flow |
| 1. Setup | POST /auth/mfa/setup → generates TOTP secret + QR data URL |
| 2. Verify | POST /auth/mfa/verify → user enters 6-digit code → secret saved |
| 3. Login | POST /auth/mfa/login → tempToken + TOTP code → full JWT pair |
| 4. Disable | POST /auth/mfa/disable → password recheck required |
Anomaly Detection Signals
| Signal | Detection Method | Response |
| Unusual request rate | Requests/min exceeds 2x user baseline | Rate limit + flag |
| Off-hours activity | Requests outside user's typical hours | Log + alert |
| New IP/device | IP or user-agent not in recent history | MFA challenge |
| Session hijacking | Concurrent sessions from different IPs | Revoke older session |
| Rapid endpoint traversal | Sequential access to unrelated endpoints | Flag + monitor |
| Privilege escalation | Accessing endpoints above user's role | Block + audit log |
DPDP Act Compliance
| Right | Implementation |
| Right to Access | GET /auth/dpdp/consent + data export |
| Right to Correction | PATCH /auth/profile |
| Right to Erasure | POST data_requests (ERASURE type) |
| Right to Portability | CSV/JSON data export |
| Right to Object | Withdraw consent via user_consents table |
| Right to Restrict | Account suspension (TEMPORARY/PERMANENT) |
| Breach Notification | 72-hour notification requirement (dpdp.ts) |
Audit Trail
// Immutable hash-chain audit log
// Each record includes prev_hash → record_hash
// Tamper-evident: modifying any record breaks the chain
CREATE TABLE audit_logs (
id TEXT PRIMARY KEY,
society_id TEXT NOT NULL,
user_id TEXT NOT NULL,
action TEXT NOT NULL, -- CREATE, UPDATE, DELETE, LOGIN, LOGOUT, etc.
entity_type TEXT,
entity_id TEXT,
old_value_json TEXT,
new_value_json TEXT,
ip_address TEXT,
user_agent TEXT,
prev_hash TEXT, -- hash of previous record
record_hash TEXT NOT NULL -- SHA-256(prev_hash + action + entity + timestamp)
);