Improve AI logic
This commit is contained in:
600
docs/06-security/rbac-implementation.md
Normal file
600
docs/06-security/rbac-implementation.md
Normal file
@@ -0,0 +1,600 @@
|
||||
# Role-Based Access Control (RBAC) Implementation Guide
|
||||
|
||||
**Last Updated:** November 2025
|
||||
**Status:** Implementation in Progress
|
||||
**Platform:** Bakery-IA Microservices
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Role System Architecture](#role-system-architecture)
|
||||
3. [Access Control Implementation](#access-control-implementation)
|
||||
4. [Service-by-Service RBAC Matrix](#service-by-service-rbac-matrix)
|
||||
5. [Implementation Guidelines](#implementation-guidelines)
|
||||
6. [Testing Strategy](#testing-strategy)
|
||||
7. [Related Documentation](#related-documentation)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This guide provides comprehensive information about implementing Role-Based Access Control (RBAC) across the Bakery-IA platform, consisting of 15 microservices with 250+ API endpoints.
|
||||
|
||||
### Key Components
|
||||
|
||||
- **4 User Roles:** Viewer → Member → Admin → Owner (hierarchical)
|
||||
- **3 Subscription Tiers:** Starter → Professional → Enterprise
|
||||
- **250+ API Endpoints:** Requiring granular access control
|
||||
- **Tenant Isolation:** All services enforce tenant-level data isolation
|
||||
|
||||
### Implementation Status
|
||||
|
||||
**Implemented:**
|
||||
- ✅ JWT authentication across all services
|
||||
- ✅ Tenant isolation via path parameters
|
||||
- ✅ Basic admin role checks in auth service
|
||||
- ✅ Subscription tier checking framework
|
||||
|
||||
**In Progress:**
|
||||
- 🔧 Role decorators on service endpoints
|
||||
- 🔧 Subscription tier enforcement on premium features
|
||||
- 🔧 Fine-grained resource permissions
|
||||
- 🔧 Audit logging for sensitive operations
|
||||
|
||||
---
|
||||
|
||||
## Role System Architecture
|
||||
|
||||
### User Role Hierarchy
|
||||
|
||||
Defined in `shared/auth/access_control.py`:
|
||||
|
||||
```python
|
||||
class UserRole(Enum):
|
||||
VIEWER = "viewer" # Read-only access
|
||||
MEMBER = "member" # Read + basic write operations
|
||||
ADMIN = "admin" # Full operational access
|
||||
OWNER = "owner" # Full control including tenant settings
|
||||
|
||||
ROLE_HIERARCHY = {
|
||||
UserRole.VIEWER: 1,
|
||||
UserRole.MEMBER: 2,
|
||||
UserRole.ADMIN: 3,
|
||||
UserRole.OWNER: 4,
|
||||
}
|
||||
```
|
||||
|
||||
### Permission Matrix by Action
|
||||
|
||||
| Action Type | Viewer | Member | Admin | Owner |
|
||||
|-------------|--------|--------|-------|-------|
|
||||
| Read data | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create records | ✗ | ✓ | ✓ | ✓ |
|
||||
| Update records | ✗ | ✓ | ✓ | ✓ |
|
||||
| Delete records | ✗ | ✗ | ✓ | ✓ |
|
||||
| Manage users | ✗ | ✗ | ✓ | ✓ |
|
||||
| Configure settings | ✗ | ✗ | ✓ | ✓ |
|
||||
| Billing/subscription | ✗ | ✗ | ✗ | ✓ |
|
||||
| Delete tenant | ✗ | ✗ | ✗ | ✓ |
|
||||
|
||||
### Subscription Tier System
|
||||
|
||||
```python
|
||||
class SubscriptionTier(Enum):
|
||||
STARTER = "starter" # Basic features
|
||||
PROFESSIONAL = "professional" # Advanced analytics & ML
|
||||
ENTERPRISE = "enterprise" # Full feature set + priority support
|
||||
|
||||
TIER_HIERARCHY = {
|
||||
SubscriptionTier.STARTER: 1,
|
||||
SubscriptionTier.PROFESSIONAL: 2,
|
||||
SubscriptionTier.ENTERPRISE: 3,
|
||||
}
|
||||
```
|
||||
|
||||
### Tier Features Matrix
|
||||
|
||||
| Feature | Starter | Professional | Enterprise |
|
||||
|---------|---------|--------------|------------|
|
||||
| Basic Inventory | ✓ | ✓ | ✓ |
|
||||
| Basic Sales | ✓ | ✓ | ✓ |
|
||||
| Basic Recipes | ✓ | ✓ | ✓ |
|
||||
| ML Forecasting | ✓ (7-day) | ✓ (30+ day) | ✓ (unlimited) |
|
||||
| Model Training | ✓ (1/day, 1k rows) | ✓ (5/day, 10k rows) | ✓ (unlimited) |
|
||||
| Advanced Analytics | ✗ | ✓ | ✓ |
|
||||
| Custom Reports | ✗ | ✓ | ✓ |
|
||||
| Production Optimization | ✓ (basic) | ✓ (advanced) | ✓ (AI-powered) |
|
||||
| Historical Data | 7 days | 90 days | Unlimited |
|
||||
| Multi-location | 1 | 2 | Unlimited |
|
||||
| API Access | ✗ | ✗ | ✓ |
|
||||
| Priority Support | ✗ | ✗ | ✓ |
|
||||
| Max Users | 5 | 20 | Unlimited |
|
||||
| Max Products | 50 | 500 | Unlimited |
|
||||
|
||||
---
|
||||
|
||||
## Access Control Implementation
|
||||
|
||||
### Available Decorators
|
||||
|
||||
The platform provides these decorators in `shared/auth/access_control.py`:
|
||||
|
||||
#### Subscription Tier Enforcement
|
||||
```python
|
||||
# Require specific subscription tier(s)
|
||||
@require_subscription_tier(['professional', 'enterprise'])
|
||||
async def advanced_analytics(...):
|
||||
pass
|
||||
|
||||
# Convenience decorators
|
||||
@enterprise_tier_required
|
||||
async def enterprise_feature(...):
|
||||
pass
|
||||
|
||||
@analytics_tier_required # Requires professional or enterprise
|
||||
async def analytics_endpoint(...):
|
||||
pass
|
||||
```
|
||||
|
||||
#### Role-Based Enforcement
|
||||
```python
|
||||
# Require specific role(s)
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def delete_resource(...):
|
||||
pass
|
||||
|
||||
# Convenience decorators
|
||||
@admin_role_required
|
||||
async def admin_only(...):
|
||||
pass
|
||||
|
||||
@owner_role_required
|
||||
async def owner_only(...):
|
||||
pass
|
||||
```
|
||||
|
||||
#### Combined Enforcement
|
||||
```python
|
||||
# Require both tier and role
|
||||
@require_tier_and_role(['professional', 'enterprise'], ['admin', 'owner'])
|
||||
async def premium_admin_feature(...):
|
||||
pass
|
||||
```
|
||||
|
||||
### FastAPI Dependencies
|
||||
|
||||
Available in `shared/auth/tenant_access.py`:
|
||||
|
||||
```python
|
||||
from fastapi import Depends
|
||||
from shared.auth.tenant_access import (
|
||||
get_current_user_dep,
|
||||
verify_tenant_access_dep,
|
||||
verify_tenant_permission_dep
|
||||
)
|
||||
|
||||
# Basic authentication
|
||||
@router.get("/{tenant_id}/resource")
|
||||
async def get_resource(
|
||||
tenant_id: str,
|
||||
current_user: Dict = Depends(get_current_user_dep)
|
||||
):
|
||||
pass
|
||||
|
||||
# Tenant access verification
|
||||
@router.get("/{tenant_id}/resource")
|
||||
async def get_resource(
|
||||
tenant_id: str = Depends(verify_tenant_access_dep)
|
||||
):
|
||||
pass
|
||||
|
||||
# Resource permission check
|
||||
@router.delete("/{tenant_id}/resource/{id}")
|
||||
async def delete_resource(
|
||||
tenant_id: str = Depends(verify_tenant_permission_dep("resource", "delete"))
|
||||
):
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service-by-Service RBAC Matrix
|
||||
|
||||
### Authentication Service
|
||||
|
||||
**Critical Operations:**
|
||||
- User deletion requires **Admin** role + audit logging
|
||||
- Password changes should enforce strong password policy
|
||||
- Email verification prevents account takeover
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/register` | POST | Public | Any | Rate limited |
|
||||
| `/login` | POST | Public | Any | Rate limited (3-5 attempts) |
|
||||
| `/delete/{user_id}` | DELETE | **Admin** | Any | 🔴 CRITICAL - Audit logged |
|
||||
| `/change-password` | POST | Authenticated | Any | Own account only |
|
||||
| `/profile` | GET/PUT | Authenticated | Any | Own account only |
|
||||
|
||||
**Recommendations:**
|
||||
- ✅ IMPLEMENTED: Admin role check on deletion
|
||||
- 🔧 ADD: Rate limiting on login/register
|
||||
- 🔧 ADD: Audit log for user deletion
|
||||
- 🔧 ADD: MFA for admin accounts
|
||||
- 🔧 ADD: Password strength validation
|
||||
|
||||
### Tenant Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Tenant deletion/deactivation (Owner only)
|
||||
- Subscription changes (Owner only)
|
||||
- Role modifications (Admin+, prevent owner changes)
|
||||
- Member removal (Admin+)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}` | GET | **Viewer** | Any | Tenant member |
|
||||
| `/{tenant_id}` | PUT | **Admin** | Any | Admin+ only |
|
||||
| `/{tenant_id}/deactivate` | POST | **Owner** | Any | 🔴 CRITICAL - Owner only |
|
||||
| `/{tenant_id}/members` | GET | **Viewer** | Any | View team |
|
||||
| `/{tenant_id}/members` | POST | **Admin** | Any | Invite users |
|
||||
| `/{tenant_id}/members/{user_id}/role` | PUT | **Admin** | Any | Change roles |
|
||||
| `/{tenant_id}/members/{user_id}` | DELETE | **Admin** | Any | 🔴 Remove member |
|
||||
| `/subscriptions/{tenant_id}/upgrade` | POST | **Owner** | Any | 🔴 CRITICAL |
|
||||
| `/subscriptions/{tenant_id}/cancel` | POST | **Owner** | Any | 🔴 CRITICAL |
|
||||
|
||||
**Recommendations:**
|
||||
- ✅ IMPLEMENTED: Role checks for member management
|
||||
- 🔧 ADD: Prevent removing the last owner
|
||||
- 🔧 ADD: Prevent owner from changing their own role
|
||||
- 🔧 ADD: Subscription change confirmation
|
||||
- 🔧 ADD: Audit log for all tenant modifications
|
||||
|
||||
### Sales Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Sales record deletion (affects financial reports)
|
||||
- Product deletion (affects historical data)
|
||||
- Bulk imports (data integrity)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}/sales` | GET | **Viewer** | Any | Read sales data |
|
||||
| `/{tenant_id}/sales` | POST | **Member** | Any | Create sales |
|
||||
| `/{tenant_id}/sales/{id}` | DELETE | **Admin** | Any | 🔴 Affects reports |
|
||||
| `/{tenant_id}/products/{id}` | DELETE | **Admin** | Any | 🔴 Affects history |
|
||||
| `/{tenant_id}/analytics/*` | GET | **Viewer** | **Professional** | 💰 Premium |
|
||||
|
||||
**Recommendations:**
|
||||
- 🔧 ADD: Soft delete for sales records (audit trail)
|
||||
- 🔧 ADD: Subscription tier check on analytics endpoints
|
||||
- 🔧 ADD: Prevent deletion of products with sales history
|
||||
|
||||
### Inventory Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Ingredient deletion (affects recipes)
|
||||
- Manual stock adjustments (inventory manipulation)
|
||||
- Compliance record deletion (regulatory violation)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}/ingredients` | GET | **Viewer** | Any | List ingredients |
|
||||
| `/{tenant_id}/ingredients/{id}` | DELETE | **Admin** | Any | 🔴 Affects recipes |
|
||||
| `/{tenant_id}/stock/adjustments` | POST | **Admin** | Any | 🔴 Manual adjustment |
|
||||
| `/{tenant_id}/analytics/*` | GET | **Viewer** | **Professional** | 💰 Premium |
|
||||
| `/{tenant_id}/reports/cost-analysis` | GET | **Admin** | **Professional** | 💰 Sensitive |
|
||||
|
||||
**Recommendations:**
|
||||
- 🔧 ADD: Prevent deletion of ingredients used in recipes
|
||||
- 🔧 ADD: Audit log for all stock adjustments
|
||||
- 🔧 ADD: Compliance records cannot be deleted
|
||||
- 🔧 ADD: Role check: only Admin+ can see cost data
|
||||
|
||||
### Production Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Batch deletion (affects inventory and tracking)
|
||||
- Schedule changes (affects production timeline)
|
||||
- Quality check modifications (compliance)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}/batches` | GET | **Viewer** | Any | View batches |
|
||||
| `/{tenant_id}/batches/{id}` | DELETE | **Admin** | Any | 🔴 Affects tracking |
|
||||
| `/{tenant_id}/schedules/{id}` | PUT | **Admin** | Any | Schedule changes |
|
||||
| `/{tenant_id}/capacity/optimize` | POST | **Admin** | Any | Basic optimization |
|
||||
| `/{tenant_id}/efficiency-trends` | GET | **Viewer** | **Professional** | 💰 Historical trends |
|
||||
| `/{tenant_id}/capacity-analysis` | GET | **Admin** | **Professional** | 💰 Advanced analysis |
|
||||
|
||||
**Tier-Based Features:**
|
||||
- **Starter:** Basic capacity, 7-day history, simple optimization
|
||||
- **Professional:** Advanced metrics, 90-day history, advanced algorithms
|
||||
- **Enterprise:** Predictive maintenance, unlimited history, AI-powered
|
||||
|
||||
**Recommendations:**
|
||||
- 🔧 ADD: Optimization depth limits per tier
|
||||
- 🔧 ADD: Historical data limits (7/90/unlimited days)
|
||||
- 🔧 ADD: Prevent deletion of completed batches
|
||||
|
||||
### Forecasting Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Forecast generation (consumes ML resources)
|
||||
- Bulk operations (resource intensive)
|
||||
- Scenario creation (computational cost)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}/forecasts` | GET | **Viewer** | Any | View forecasts |
|
||||
| `/{tenant_id}/forecasts/generate` | POST | **Admin** | Any | Trigger ML forecast |
|
||||
| `/{tenant_id}/scenarios` | GET | **Viewer** | **Enterprise** | 💰 Scenario modeling |
|
||||
| `/{tenant_id}/scenarios` | POST | **Admin** | **Enterprise** | 💰 Create scenario |
|
||||
| `/{tenant_id}/analytics/accuracy` | GET | **Viewer** | **Professional** | 💰 Model metrics |
|
||||
|
||||
**Tier-Based Limits:**
|
||||
- **Starter:** 7-day forecasts, 10/day quota
|
||||
- **Professional:** 30+ day forecasts, 100/day quota, accuracy metrics
|
||||
- **Enterprise:** Unlimited forecasts, scenario modeling, custom parameters
|
||||
|
||||
**Recommendations:**
|
||||
- 🔧 ADD: Forecast horizon limits per tier
|
||||
- 🔧 ADD: Rate limiting based on tier (ML cost)
|
||||
- 🔧 ADD: Quota limits per subscription tier
|
||||
- 🔧 ADD: Scenario modeling only for Enterprise
|
||||
|
||||
### Training Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Model training (expensive ML operations)
|
||||
- Model deployment (affects production forecasts)
|
||||
- Model retraining (overwrites existing models)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}/training-jobs` | POST | **Admin** | Any | Start training |
|
||||
| `/{tenant_id}/training-jobs/{id}/cancel` | POST | **Admin** | Any | Cancel training |
|
||||
| `/{tenant_id}/models/{id}/deploy` | POST | **Admin** | Any | 🔴 Deploy model |
|
||||
| `/{tenant_id}/models/{id}/artifacts` | GET | **Admin** | **Enterprise** | 💰 Download artifacts |
|
||||
| `/ws/{tenant_id}/training` | WebSocket | **Admin** | Any | Real-time updates |
|
||||
|
||||
**Tier-Based Quotas:**
|
||||
- **Starter:** 1 training job/day, 1k rows max, simple Prophet
|
||||
- **Professional:** 5 jobs/day, 10k rows max, model versioning
|
||||
- **Enterprise:** Unlimited jobs, unlimited rows, custom parameters
|
||||
|
||||
**Recommendations:**
|
||||
- 🔧 ADD: Training quota per subscription tier
|
||||
- 🔧 ADD: Dataset size limits per tier
|
||||
- 🔧 ADD: Queue priority based on subscription
|
||||
- 🔧 ADD: Artifact download only for Enterprise
|
||||
|
||||
### Orders Service
|
||||
|
||||
**Critical Operations:**
|
||||
- Order cancellation (affects production and customer)
|
||||
- Customer deletion (GDPR compliance required)
|
||||
- Procurement scheduling (affects inventory)
|
||||
|
||||
| Endpoint | Method | Min Role | Min Tier | Notes |
|
||||
|----------|--------|----------|----------|-------|
|
||||
| `/{tenant_id}/orders` | GET | **Viewer** | Any | View orders |
|
||||
| `/{tenant_id}/orders/{id}/cancel` | POST | **Admin** | Any | 🔴 Cancel order |
|
||||
| `/{tenant_id}/customers/{id}` | DELETE | **Admin** | Any | 🔴 GDPR compliance |
|
||||
| `/{tenant_id}/procurement/requirements` | GET | **Admin** | **Professional** | 💰 Planning |
|
||||
| `/{tenant_id}/procurement/schedule` | POST | **Admin** | **Professional** | 💰 Scheduling |
|
||||
|
||||
**Recommendations:**
|
||||
- 🔧 ADD: Order cancellation requires reason/notes
|
||||
- 🔧 ADD: Customer deletion with GDPR-compliant export
|
||||
- 🔧 ADD: Soft delete for orders (audit trail)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Guidelines
|
||||
|
||||
### Step 1: Add Role Decorators
|
||||
|
||||
```python
|
||||
from shared.auth.access_control import require_user_role
|
||||
|
||||
@router.delete("/{tenant_id}/sales/{sale_id}")
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def delete_sale(
|
||||
tenant_id: str,
|
||||
sale_id: str,
|
||||
current_user: Dict = Depends(get_current_user_dep)
|
||||
):
|
||||
# Existing logic...
|
||||
pass
|
||||
```
|
||||
|
||||
### Step 2: Add Subscription Tier Checks
|
||||
|
||||
```python
|
||||
from shared.auth.access_control import require_subscription_tier
|
||||
|
||||
@router.post("/{tenant_id}/forecasts/generate")
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def generate_forecast(
|
||||
tenant_id: str,
|
||||
horizon_days: int,
|
||||
current_user: Dict = Depends(get_current_user_dep)
|
||||
):
|
||||
# Check tier-based limits
|
||||
tier = current_user.get('subscription_tier', 'starter')
|
||||
max_horizon = {
|
||||
'starter': 7,
|
||||
'professional': 90,
|
||||
'enterprise': 365
|
||||
}
|
||||
|
||||
if horizon_days > max_horizon.get(tier, 7):
|
||||
raise HTTPException(
|
||||
status_code=402,
|
||||
detail=f"Forecast horizon limited to {max_horizon[tier]} days for {tier} tier"
|
||||
)
|
||||
|
||||
# Check daily quota
|
||||
daily_quota = {'starter': 10, 'professional': 100, 'enterprise': None}
|
||||
if not await check_quota(tenant_id, 'forecasts', daily_quota[tier]):
|
||||
raise HTTPException(
|
||||
status_code=429,
|
||||
detail=f"Daily forecast quota exceeded for {tier} tier"
|
||||
)
|
||||
|
||||
# Existing logic...
|
||||
```
|
||||
|
||||
### Step 3: Add Audit Logging
|
||||
|
||||
```python
|
||||
from shared.audit import log_audit_event
|
||||
|
||||
@router.delete("/{tenant_id}/customers/{customer_id}")
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def delete_customer(
|
||||
tenant_id: str,
|
||||
customer_id: str,
|
||||
current_user: Dict = Depends(get_current_user_dep)
|
||||
):
|
||||
# Existing deletion logic...
|
||||
|
||||
# Add audit log
|
||||
await log_audit_event(
|
||||
tenant_id=tenant_id,
|
||||
user_id=current_user["user_id"],
|
||||
action="customer.delete",
|
||||
resource_type="customer",
|
||||
resource_id=customer_id,
|
||||
severity="high"
|
||||
)
|
||||
```
|
||||
|
||||
### Step 4: Implement Rate Limiting
|
||||
|
||||
```python
|
||||
from shared.rate_limit import check_quota
|
||||
|
||||
@router.post("/{tenant_id}/training-jobs")
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def create_training_job(
|
||||
tenant_id: str,
|
||||
dataset_rows: int,
|
||||
current_user: Dict = Depends(get_current_user_dep)
|
||||
):
|
||||
tier = current_user.get('subscription_tier', 'starter')
|
||||
|
||||
# Check daily quota
|
||||
daily_limits = {'starter': 1, 'professional': 5, 'enterprise': None}
|
||||
if not await check_quota(tenant_id, 'training_jobs', daily_limits[tier], period=86400):
|
||||
raise HTTPException(
|
||||
status_code=429,
|
||||
detail=f"Daily training job limit reached for {tier} tier ({daily_limits[tier]}/day)"
|
||||
)
|
||||
|
||||
# Check dataset size limit
|
||||
dataset_limits = {'starter': 1000, 'professional': 10000, 'enterprise': None}
|
||||
if dataset_limits[tier] and dataset_rows > dataset_limits[tier]:
|
||||
raise HTTPException(
|
||||
status_code=402,
|
||||
detail=f"Dataset size limited to {dataset_limits[tier]} rows for {tier} tier"
|
||||
)
|
||||
|
||||
# Existing logic...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```python
|
||||
# Test role enforcement
|
||||
def test_delete_requires_admin_role():
|
||||
response = client.delete(
|
||||
"/api/v1/tenant123/sales/sale456",
|
||||
headers={"Authorization": f"Bearer {member_token}"}
|
||||
)
|
||||
assert response.status_code == 403
|
||||
assert "insufficient_permissions" in response.json()["detail"]["error"]
|
||||
|
||||
# Test subscription tier enforcement
|
||||
def test_forecasting_horizon_limit_starter():
|
||||
response = client.post(
|
||||
"/api/v1/tenant123/forecasts/generate",
|
||||
json={"horizon_days": 30}, # Exceeds 7-day limit
|
||||
headers={"Authorization": f"Bearer {starter_user_token}"}
|
||||
)
|
||||
assert response.status_code == 402 # Payment Required
|
||||
assert "limited to 7 days" in response.json()["detail"]
|
||||
|
||||
# Test training job quota
|
||||
def test_training_job_daily_quota_starter():
|
||||
# First job succeeds
|
||||
response1 = client.post(
|
||||
"/api/v1/tenant123/training-jobs",
|
||||
json={"dataset_rows": 500},
|
||||
headers={"Authorization": f"Bearer {starter_admin_token}"}
|
||||
)
|
||||
assert response1.status_code == 200
|
||||
|
||||
# Second job on same day fails (1/day limit)
|
||||
response2 = client.post(
|
||||
"/api/v1/tenant123/training-jobs",
|
||||
json={"dataset_rows": 500},
|
||||
headers={"Authorization": f"Bearer {starter_admin_token}"}
|
||||
)
|
||||
assert response2.status_code == 429 # Too Many Requests
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
```python
|
||||
# Test tenant isolation
|
||||
def test_user_cannot_access_other_tenant():
|
||||
response = client.get(
|
||||
"/api/v1/tenant456/sales", # Different tenant
|
||||
headers={"Authorization": f"Bearer {user_token}"}
|
||||
)
|
||||
assert response.status_code == 403
|
||||
```
|
||||
|
||||
### Security Tests
|
||||
|
||||
```python
|
||||
# Test rate limiting
|
||||
def test_training_job_rate_limit():
|
||||
for i in range(6):
|
||||
response = client.post(
|
||||
"/api/v1/tenant123/training-jobs",
|
||||
headers={"Authorization": f"Bearer {admin_token}"}
|
||||
)
|
||||
assert response.status_code == 429 # Too Many Requests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
### Security Documentation
|
||||
- [Database Security](./database-security.md) - Database security implementation
|
||||
- [TLS Configuration](./tls-configuration.md) - TLS/SSL setup details
|
||||
- [Security Checklist](./security-checklist.md) - Deployment checklist
|
||||
|
||||
### Source Reports
|
||||
- [RBAC Analysis Report](../RBAC_ANALYSIS_REPORT.md) - Complete analysis
|
||||
|
||||
### Code References
|
||||
- `shared/auth/access_control.py` - Role and tier decorators
|
||||
- `shared/auth/tenant_access.py` - FastAPI dependencies
|
||||
- `services/tenant/app/models/tenants.py` - Tenant member model
|
||||
|
||||
---
|
||||
|
||||
**Document Version:** 1.0
|
||||
**Last Review:** November 2025
|
||||
**Next Review:** February 2026
|
||||
**Owner:** Security & Platform Team
|
||||
Reference in New Issue
Block a user