# Security Architecture for Multi-Tenant SaaS When hundreds of organizations share the same platform, security isn't a feature — it's the foundation. Every architectural decision either strengthens or weakens the boundaries between tenants. There's no neutral ground. After building and operating a multi-tenant platform, here's the security architecture we've converged on. Not because it's theoretically optimal, but because each layer exists to compensate for the inevitable failure of another layer. ## The Defense-in-Depth Principle No single security measure is sufficient. Firewalls fail. Code has bugs. People make mistakes. The security architecture assumes that any individual layer will eventually fail and ensures that a failure in one layer doesn't cascade into a breach. Our architecture has seven layers. An attacker must breach all seven to access another tenant's data. Practically speaking, breaching even two simultaneously is extremely difficult. ## Layer 1: Network Security The outermost layer. All traffic enters through a reverse proxy that handles TLS termination, rate limiting, and basic threat detection. **What it prevents:** Network-level attacks, DDoS, unencrypted traffic. **Components:** Reverse proxy (Nginx/Caddy), TLS 1.3, rate limiting per IP and per tenant, geographic restrictions if required. **Failure mode:** A compromised reverse proxy exposes traffic, but encrypted data at rest and application-level security prevent data access. ## Layer 2: Authentication Every request must prove its identity. We use multi-factor authentication as the default, with SSO/SAML for enterprise tenants. **What it prevents:** Unauthorized access, credential stuffing, session hijacking. **Components:** JWT tokens with short expiration (15 minutes), secure refresh token rotation, MFA enforcement, SSO integration, brute-force protection with account lockout. **Failure mode:** A compromised authentication token grants access as that user only. RLS and RBAC limit what that user can see. ## Layer 3: Authorization (RBAC) Once authenticated, every action is checked against the user's permissions. Can this user read this resource? Can they modify it? Can they delete it? **What it prevents:** Privilege escalation, unauthorized data access within a tenant, unauthorized administrative actions. **Components:** Role-based access control with granular permissions, permission checks on every API endpoint, middleware that enforces authorization before route handlers execute. **Failure mode:** A misconfigured role might grant too much access, but only within the user's own tenant. RLS prevents cross-tenant access regardless of permissions. ## Layer 4: Row-Level Security (RLS) The database enforces tenant isolation. Every query is automatically filtered to the authenticated tenant's data. Even if the application has a bug that omits tenant filtering, the database returns only authorized rows. **What it prevents:** Cross-tenant data leaks, application-level filtering bugs, direct database access by unauthorized parties. **Components:** PostgreSQL RLS policies on every tenant-scoped table, session-level tenant context, default-deny policies (no policy = no access). **Failure mode:** An RLS misconfiguration on a specific table might expose data, but it's isolated to that table. Encryption at rest prevents reading raw data without application-level decryption. ## Layer 5: Encryption Data is encrypted at multiple levels: in transit (TLS), at rest (disk encryption), and at the application level (sensitive field encryption). **What it prevents:** Data exposure from physical theft, storage-level breaches, and database access without application context. **Components:** TLS 1.2+ for all connections, AES-256 disk encryption, application-level AES-256-GCM encryption for sensitive fields, per-tenant encryption keys, key management through a dedicated service. **Failure mode:** A compromised encryption key exposes data encrypted with that specific key. Per-tenant key isolation limits the blast radius. ## Layer 6: Audit Logging Every security-relevant action is logged immutably: authentication events, data access, permission changes, configuration modifications, and administrative actions. **What it prevents:** Doesn't prevent attacks directly — enables detection, investigation, and compliance. Without audit logs, you might never know a breach occurred. **Components:** Immutable append-only audit log, tamper detection, retention policies, alerting on anomalous patterns, log export for SIEM integration. **Failure mode:** If logging fails, the system should alert immediately and optionally halt operations (fail-closed) rather than continue without accountability. ## Layer 7: Input Validation Every piece of data entering the system is validated at the boundary. API inputs, file uploads, webhook payloads — everything is checked against a schema before processing. **What it prevents:** SQL injection, XSS, command injection, file upload attacks, malformed data that crashes the system. **Components:** Zod schemas for all API inputs, content-type verification, file upload scanning, parameterized queries (never string concatenation), output encoding. **Failure mode:** A missed validation might allow malicious input, but RLS prevents cross-tenant impact, and encryption protects stored data. ## How the Layers Interact The power of defense in depth is in the combinations: **Scenario: Compromised user credential** - Layer 2 (Auth): Attacker authenticates as the compromised user - Layer 3 (RBAC): Attacker has only the user's permissions, not admin - Layer 4 (RLS): Attacker sees only the user's tenant data - Layer 6 (Audit): Anomalous access patterns trigger alerts **Scenario: SQL injection in a new endpoint** - Layer 7 (Validation): Should catch it, but failed - Layer 4 (RLS): Database returns only the current tenant's data anyway - Layer 5 (Encryption): Sensitive fields are encrypted; raw query returns ciphertext - Layer 6 (Audit): Unusual query patterns are logged and flagged **Scenario: Insider threat (rogue employee at the platform company)** - Layer 4 (RLS): Database access requires tenant context; bulk extraction is blocked - Layer 5 (Encryption): Application-level encryption means database access alone doesn't expose sensitive data - Layer 6 (Audit): All database access is logged with identity ## Security Testing Architecture without testing is theory. We test the security architecture through: **Automated cross-tenant tests:** Every test suite includes tests that create data in Tenant A and verify it's inaccessible from Tenant B. These run on every deployment. **Penetration testing:** Annual third-party penetration tests with a scope that specifically includes multi-tenant isolation. **Dependency scanning:** Automated scanning of all dependencies for known vulnerabilities, blocking deployment if critical vulnerabilities are found. **Security architecture reviews:** Quarterly reviews of the security architecture with the full engineering team, updating threat models and verifying that new features don't introduce gaps. ## The Honest Assessment No system is perfectly secure. Our architecture is designed so that: 1. Single failures don't cause breaches (defense in depth) 2. Breaches are detected quickly (audit logging and monitoring) 3. The blast radius of any breach is limited (tenant isolation and per-tenant encryption) 4. Recovery is possible (immutable audit logs and encrypted backups) Security is a process, not a destination. The architecture evolves as threats evolve. What doesn't change is the principle: every layer assumes the others will fail.