- Update TEST_COVERAGE_MAP with current requirements - Refresh ADR-004 with C++ implementation details - Update architecture, deployment, and security docs - Improve CLI/TUI UX contract documentation
6.1 KiB
6.1 KiB
Multi-Tenant Security Implementation Summary
Overview
This document summarizes the Multi-Tenant Server Security features implemented for tenant isolation, cross-tenant access prevention, resource quotas, worker sanitization, and per-tenant audit logging.
Tenant Isolation
Tenant Manager (internal/worker/tenant/manager.go)
Core Types:
Tenant- Represents an isolated tenant with metadata, config, and lifecycle stateTenantConfig- Holds tenant-specific configuration including quotas and security policiesIsolationLevel- Defines isolation degree:soft,hard, ordedicated
Key Methods:
CreateTenant()- Creates isolated tenant workspace with subdirectories (artifacts, snapshots, logs, cache)GetTenant()- Retrieves active tenant by IDDeactivateTenant()- Soft-delete tenantGetTenantWorkspace()- Returns isolated workspace path for tenantListTenants()- Returns all active tenants
Workspace Isolation:
/tenants/
├── {tenant-id}/
│ ├── artifacts/
│ ├── snapshots/
│ ├── logs/
│ └── cache/
Security Defaults (DefaultTenantConfig):
- IsolationLevel:
hard(container-level) - RequireEncryption: true
- RequireAuditLogging: true
- RequireSandbox: true
- NetworkPolicy: "restricted"
Cross-Tenant Access Prevention
Middleware (internal/worker/tenant/middleware.go)
HTTP Middleware:
Middleware.Handler()- Validates tenant ID from headers/query params/contextExtractTenantID()- Extracts tenant ID from request (header:X-Tenant-ID, query param, or context)- Automatic audit logging of all tenant requests
Resource Access Control:
ResourceAccessChecker- Validates cross-tenant resource accessCheckAccess()- Denies all cross-tenant access by defaultCheckResourceOwnership()- Validates resource belongs to requesting tenantValidateResourcePath()- Ensures path within tenant workspace
Cross-Tenant Denial:
// All cross-tenant access denied by default
if requestingTenantID != resourceTenantID {
return fmt.Errorf("cross-tenant access denied")
}
Resource Quotas per Tenant
Quota Manager (internal/worker/tenant/quota.go)
ResourceQuota Structure:
- MaxConcurrentJobs - Job concurrency limit
- MaxGPUs - GPU allocation limit
- MaxMemoryGB - Memory usage limit
- MaxStorageGB - Storage quota
- MaxCPUCores - CPU core limit
- MaxRuntimeHours - Maximum job runtime
- MaxArtifactsPerHour - Artifact creation rate limit
QuotaManager Features:
CheckQuota()- Validates resource request against tenant limitsAllocate()- Reserves resources for tenantRelease()- Frees resources when doneRecordArtifact()- Tracks artifact creation rate- Automatic hourly counter reset
Default Quotas:
MaxConcurrentJobs: 5
MaxGPUs: 1
MaxMemoryGB: 32
MaxStorageGB: 100
MaxCPUCores: 8
MaxRuntimeHours: 24
MaxArtifactsPerHour: 10
Worker Sanitization Between Tenants
Sanitization (internal/worker/tenant/manager.go)
SanitizeForTenant():
- Clears tenant-specific caches
- Logs tenant transition for audit
- Prepares worker environment for different tenant
Called When:
- Worker switches between tenant tasks
- New tenant session begins
Audit Event: AuditWorkerSanitized
Per-Tenant Audit Logging
Audit Logger (internal/worker/tenant/quota.go)
AuditEvent Types:
AuditTenantCreated- Tenant provisionedAuditTenantDeactivated- Tenant deactivatedAuditTenantUpdated- Configuration changedAuditResourceAccess- Resource accessedAuditResourceCreated- Resource createdAuditResourceDeleted- Resource deletedAuditJobSubmitted- Job queuedAuditJobCompleted- Job finishedAuditJobFailed- Job errorAuditCrossTenantDeny- Cross-tenant blockedAuditQuotaExceeded- Quota violationAuditWorkerSanitized- Worker cleanedAuditEncryptionOp- Encryption operationAuditDecryptionOp- Decryption operation
Audit Log Structure:
/tenants/
└── {tenant-id}/
└── audit.log (JSON format)
Features:
- Per-tenant isolated log files
- Structured JSON format
- IP address tracking
- Success/failure status
- Detailed context in
Detailsfield
Files Created
Core Implementation
internal/worker/tenant/manager.go- Tenant lifecycle and isolationinternal/worker/tenant/quota.go- Resource quotas and audit logginginternal/worker/tenant/middleware.go- HTTP middleware and access control
Worker Integration
internal/worker/worker.go- AddedTenantManagerfield to Worker struct
Testing
Build verification:
make dev # Successful
All Go packages compile on:
- macOS (Darwin)
- Linux
- Windows
Security Impact
| Feature | Threat Mitigated | Implementation |
|---|---|---|
| Tenant Isolation | Data leakage between tenants | Hard isolation with dedicated workspaces |
| Cross-Tenant Access | Unauthorized data access | Deny-by-default with audit logging |
| Resource Quotas | Resource exhaustion / DoS | Per-tenant limits with enforcement |
| Worker Sanitization | Cross-contamination | State clearing between tenant switches |
| Per-Tenant Audit | Compliance gaps | Isolated audit logs per tenant |
HIPAA Compliance
All features support HIPAA compliance:
- Tenant isolation ensures data separation
- Cross-tenant access prevention blocks unauthorized access
- Per-tenant audit logs enable compliance tracking
- Resource quotas prevent resource-based DoS
Integration Points
Worker Usage:
// Initialize tenant manager
w.TenantManager, _ = tenant.NewManager("/tenants", w.Logger)
// Create tenant
tenant, _ := w.TenantManager.CreateTenant(ctx, "tenant-1", "Acme Corp", config)
// Validate resource access
err := w.TenantManager.ValidateTenantAccess(ctx, requestingTenant, resourceTenant)
// Sanitize between tenants
w.TenantManager.SanitizeForTenant(ctx, newTenantID)
HTTP Middleware Usage:
middleware := tenant.NewMiddleware(tenantManager, logger)
http.Handle("/api/", middleware.Handler(apiHandler))