277 lines
7.6 KiB
Markdown
277 lines
7.6 KiB
Markdown
# Tenant Limits Implementation
|
|
|
|
## Overview
|
|
|
|
This document explains how tenant subscription limits are enforced in the UAM-ILS Drone Detection System. All the issues you identified have been resolved:
|
|
|
|
## ✅ Issues Fixed
|
|
|
|
### 1. **User Creation Limits**
|
|
- **Problem**: Tenants could create unlimited users regardless of their subscription limits
|
|
- **Solution**: Added `enforceUserLimit()` middleware to `POST /tenant/users`
|
|
- **Implementation**: Counts existing users and validates against `tenant.features.max_users`
|
|
|
|
### 2. **Device Creation Limits**
|
|
- **Problem**: Tenants could add unlimited devices regardless of their subscription limits
|
|
- **Solution**: Added `enforceDeviceLimit()` middleware to `POST /devices`
|
|
- **Implementation**: Counts existing devices and validates against `tenant.features.max_devices`
|
|
|
|
### 3. **API Rate Limiting**
|
|
- **Problem**: No proper API rate limiting per tenant shared among users
|
|
- **Solution**: Implemented `enforceApiRateLimit()` middleware
|
|
- **Implementation**:
|
|
- Tracks actual API requests (not page views)
|
|
- Rate limit is shared among ALL users in a tenant
|
|
- Uses sliding window algorithm
|
|
- Applied to all authenticated API endpoints
|
|
|
|
### 4. **Data Retention**
|
|
- **Problem**: Old data was never cleaned up automatically
|
|
- **Solution**: Created `DataRetentionService` with cron job
|
|
- **Implementation**:
|
|
- Runs daily at 2:00 AM UTC
|
|
- Deletes detections, heartbeats, and logs older than `tenant.features.data_retention_days`
|
|
- Respects unlimited retention (`-1` value)
|
|
- Provides preview endpoint to see what would be deleted
|
|
|
|
## 🔧 Technical Implementation
|
|
|
|
### Middleware: `server/middleware/tenant-limits.js`
|
|
|
|
```javascript
|
|
// User limit enforcement
|
|
enforceUserLimit() - Prevents user creation when limit reached
|
|
enforceDeviceLimit() - Prevents device creation when limit reached
|
|
enforceApiRateLimit() - Rate limits API requests per tenant
|
|
getTenantLimitsStatus() - Returns current usage vs limits
|
|
```
|
|
|
|
### Service: `server/services/dataRetention.js`
|
|
|
|
```javascript
|
|
DataRetentionService {
|
|
start() - Starts daily cron job
|
|
performCleanup() - Cleans all tenants based on retention policies
|
|
previewCleanup(tenantId) - Shows what would be deleted
|
|
getStats() - Returns cleanup statistics
|
|
}
|
|
```
|
|
|
|
### API Endpoints
|
|
|
|
```bash
|
|
GET /api/tenant/limits
|
|
# Returns current usage and limits for the tenant
|
|
{
|
|
"users": { "current": 3, "limit": 5, "unlimited": false },
|
|
"devices": { "current": 7, "limit": 10, "unlimited": false },
|
|
"api_requests": { "current_minute": 45, "limit_per_minute": 1000 },
|
|
"data_retention": { "days": 90, "unlimited": false }
|
|
}
|
|
|
|
GET /api/tenant/data-retention/preview
|
|
# Shows what data would be deleted by retention cleanup
|
|
{
|
|
"tenantSlug": "tenant1",
|
|
"retentionDays": 90,
|
|
"cutoffDate": "2024-06-24T02:00:00.000Z",
|
|
"toDelete": {
|
|
"detections": 1250,
|
|
"heartbeats": 4500,
|
|
"logs": 89
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🚦 How Rate Limiting Works
|
|
|
|
### API Rate Limiting Details
|
|
- **Granularity**: Per tenant (shared among all users)
|
|
- **Window**: 1 minute sliding window
|
|
- **Storage**: In-memory with automatic cleanup
|
|
- **Headers**: Standard rate limit headers included
|
|
- **Tracking**: Only actual API requests count (not static files/page views)
|
|
|
|
### Example Rate Limit Response
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "API rate limit exceeded. Maximum 1000 requests per 60 seconds for your tenant.",
|
|
"error_code": "TENANT_API_RATE_LIMIT_EXCEEDED",
|
|
"max_requests": 1000,
|
|
"window_seconds": 60,
|
|
"retry_after_seconds": 15
|
|
}
|
|
```
|
|
|
|
## 📊 Subscription Tiers
|
|
|
|
The system supports different subscription tiers with these default limits:
|
|
|
|
```javascript
|
|
// Free tier
|
|
{
|
|
max_devices: 2,
|
|
max_users: 1,
|
|
api_rate_limit: 100,
|
|
data_retention_days: 7
|
|
}
|
|
|
|
// Pro tier
|
|
{
|
|
max_devices: 10,
|
|
max_users: 5,
|
|
api_rate_limit: 1000,
|
|
data_retention_days: 90
|
|
}
|
|
|
|
// Business tier
|
|
{
|
|
max_devices: 50,
|
|
max_users: 20,
|
|
api_rate_limit: 5000,
|
|
data_retention_days: 365
|
|
}
|
|
|
|
// Enterprise tier
|
|
{
|
|
max_devices: -1, // Unlimited
|
|
max_users: -1, // Unlimited
|
|
api_rate_limit: -1, // Unlimited
|
|
data_retention_days: -1 // Unlimited
|
|
}
|
|
```
|
|
|
|
## 🔒 Security Features
|
|
|
|
### Limit Enforcement Security
|
|
- All limit checks are done server-side (cannot be bypassed)
|
|
- Security events are logged when limits are exceeded
|
|
- Failed attempts include IP address, user agent, and user details
|
|
- Graceful error messages prevent information disclosure
|
|
|
|
### Error Response Format
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Tenant has reached the maximum number of users (5). Please upgrade your subscription or remove existing users.",
|
|
"error_code": "TENANT_USER_LIMIT_EXCEEDED",
|
|
"current_count": 5,
|
|
"max_allowed": 5
|
|
}
|
|
```
|
|
|
|
## 🕒 Data Retention Schedule
|
|
|
|
### Cleanup Process
|
|
1. **Trigger**: Daily at 2:00 AM UTC via cron job
|
|
2. **Process**: For each active tenant:
|
|
- Check `tenant.features.data_retention_days`
|
|
- Skip if unlimited (`-1`)
|
|
- Calculate cutoff date
|
|
- Delete old detections, heartbeats, logs
|
|
- Log security events for significant cleanups
|
|
3. **Performance**: Batched operations with error handling per tenant
|
|
|
|
### Manual Operations
|
|
```javascript
|
|
// Preview what would be deleted
|
|
const service = new DataRetentionService();
|
|
const preview = await service.previewCleanup(tenantId);
|
|
|
|
// Manually trigger cleanup (admin only)
|
|
await service.triggerManualCleanup();
|
|
|
|
// Get cleanup statistics
|
|
const stats = service.getStats();
|
|
```
|
|
|
|
## 🔧 Docker Integration
|
|
|
|
### Package Dependencies
|
|
Added to `server/package.json`:
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"node-cron": "^3.0.2"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Service Initialization
|
|
All services start automatically when the Docker container boots:
|
|
```javascript
|
|
// In server/index.js
|
|
const dataRetentionService = new DataRetentionService();
|
|
dataRetentionService.start();
|
|
console.log('🗂️ Data retention service: ✅ Started');
|
|
```
|
|
|
|
## 🧪 Testing the Implementation
|
|
|
|
### Test User Limits
|
|
```bash
|
|
# Create users until limit is reached
|
|
curl -X POST /api/tenant/users \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-d '{"username":"test6","email":"test6@example.com","password":"password"}'
|
|
|
|
# Should return 403 when limit exceeded
|
|
```
|
|
|
|
### Test Device Limits
|
|
```bash
|
|
# Create devices until limit is reached
|
|
curl -X POST /api/devices \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-d '{"id":"device-11","name":"Test Device 11"}'
|
|
|
|
# Should return 403 when limit exceeded
|
|
```
|
|
|
|
### Test API Rate Limits
|
|
```bash
|
|
# Send rapid requests to trigger rate limit
|
|
for i in {1..1100}; do
|
|
curl -X GET /api/detections -H "Authorization: Bearer $TOKEN" &
|
|
done
|
|
|
|
# Should return 429 after limit reached
|
|
```
|
|
|
|
### Test Data Retention
|
|
```bash
|
|
# Preview what would be deleted
|
|
curl -X GET /api/tenant/data-retention/preview \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
|
|
# Check tenant limits status
|
|
curl -X GET /api/tenant/limits \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
```
|
|
|
|
## 📈 Monitoring & Logging
|
|
|
|
### Security Logs
|
|
All limit violations are logged with full context:
|
|
- User ID and username
|
|
- Tenant ID and slug
|
|
- IP address and user agent
|
|
- Specific limit exceeded and current usage
|
|
- Timestamp and action details
|
|
|
|
### Performance Monitoring
|
|
- Rate limit middleware tracks response times
|
|
- Data retention service logs cleanup duration and counts
|
|
- Memory usage monitoring for rate limit store
|
|
- Database query performance for limit checks
|
|
|
|
## 🔄 Upgrade Path
|
|
|
|
When tenants upgrade their subscription:
|
|
1. Update `tenant.features` with new limits
|
|
2. Limits take effect immediately
|
|
3. No restart required
|
|
4. Historical data respects new retention policy on next cleanup
|
|
|
|
This comprehensive implementation ensures that tenant limits are properly enforced across all aspects of the system, preventing abuse while providing clear feedback to users about their subscription status. |