# 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.