Fix jwt-token
This commit is contained in:
277
TENANT_LIMITS_IMPLEMENTATION.md
Normal file
277
TENANT_LIMITS_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,277 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user