- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
261 lines
6.1 KiB
TypeScript
261 lines
6.1 KiB
TypeScript
/**
|
|
* Compliance Enforcer Service
|
|
* Enforces regulatory compliance and data residency rules
|
|
*/
|
|
|
|
import { getDb } from '../db/index.js'
|
|
import { logger } from '../lib/logger.js'
|
|
import { Context } from '../types/context.js'
|
|
|
|
export interface ComplianceResult {
|
|
compliant: boolean
|
|
violations: string[]
|
|
warnings: string[]
|
|
requiredActions: string[]
|
|
}
|
|
|
|
export enum RegulatoryFramework {
|
|
GDPR = 'GDPR',
|
|
CCPA = 'CCPA',
|
|
HIPAA = 'HIPAA',
|
|
PCI_DSS = 'PCI-DSS',
|
|
SOX = 'SOX',
|
|
CALEA = 'CALEA',
|
|
FERPA = 'FERPA',
|
|
FEDRAMP = 'FEDRAMP',
|
|
}
|
|
|
|
class ComplianceEnforcer {
|
|
/**
|
|
* Check data residency compliance
|
|
*/
|
|
async checkDataResidency(
|
|
context: Context,
|
|
data: any,
|
|
targetRegion: string
|
|
): Promise<boolean> {
|
|
const db = getDb()
|
|
|
|
// Get data residency rules for data type
|
|
const rulesResult = await db.query(
|
|
`SELECT * FROM data_residency_rules
|
|
WHERE data_type = $1`,
|
|
[data.type || 'default']
|
|
)
|
|
|
|
if (rulesResult.rows.length === 0) {
|
|
return true // No restrictions
|
|
}
|
|
|
|
for (const rule of rulesResult.rows) {
|
|
// Check if target region is prohibited
|
|
if (
|
|
rule.prohibited_regions &&
|
|
rule.prohibited_regions.includes(targetRegion)
|
|
) {
|
|
return false
|
|
}
|
|
|
|
// Check if target region is in allowed list
|
|
if (
|
|
rule.allowed_regions &&
|
|
rule.allowed_regions.length > 0 &&
|
|
!rule.allowed_regions.includes(targetRegion)
|
|
) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
/**
|
|
* Validate regulatory compliance
|
|
*/
|
|
async validateRegulatoryCompliance(
|
|
context: Context,
|
|
data: any,
|
|
operation: 'READ' | 'WRITE' | 'REPLICATE',
|
|
region: string,
|
|
frameworks: RegulatoryFramework[]
|
|
): Promise<ComplianceResult> {
|
|
const violations: string[] = []
|
|
const warnings: string[] = []
|
|
const requiredActions: string[] = []
|
|
|
|
for (const framework of frameworks) {
|
|
const result = await this.validateFramework(
|
|
framework,
|
|
data,
|
|
operation,
|
|
region
|
|
)
|
|
|
|
if (!result.compliant) {
|
|
violations.push(...result.violations)
|
|
}
|
|
|
|
warnings.push(...result.warnings)
|
|
requiredActions.push(...result.requiredActions)
|
|
}
|
|
|
|
return {
|
|
compliant: violations.length === 0,
|
|
violations,
|
|
warnings,
|
|
requiredActions,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate specific framework
|
|
*/
|
|
private async validateFramework(
|
|
framework: RegulatoryFramework,
|
|
data: any,
|
|
operation: string,
|
|
region: string
|
|
): Promise<ComplianceResult> {
|
|
const violations: string[] = []
|
|
const warnings: string[] = []
|
|
const requiredActions: string[] = []
|
|
|
|
switch (framework) {
|
|
case RegulatoryFramework.GDPR:
|
|
// GDPR: Data must remain in EU
|
|
if (operation === 'REPLICATE' && !this.isEURegion(region)) {
|
|
violations.push('GDPR: Data cannot be replicated outside EU')
|
|
}
|
|
if (data.personalData && !data.consent) {
|
|
violations.push('GDPR: Personal data requires consent')
|
|
}
|
|
break
|
|
|
|
case RegulatoryFramework.HIPAA:
|
|
// HIPAA: Healthcare data protection
|
|
if (data.healthcareData && !data.encrypted) {
|
|
violations.push('HIPAA: Healthcare data must be encrypted')
|
|
}
|
|
if (!data.auditLog) {
|
|
requiredActions.push('HIPAA: Audit logging required')
|
|
}
|
|
break
|
|
|
|
case RegulatoryFramework.PCI_DSS:
|
|
// PCI-DSS: Payment card data
|
|
if (data.cardholderData && !data.encrypted) {
|
|
violations.push('PCI-DSS: Cardholder data must be encrypted')
|
|
}
|
|
if (data.cardholderData && !data.accessRestricted) {
|
|
violations.push('PCI-DSS: Access to cardholder data must be restricted')
|
|
}
|
|
break
|
|
|
|
case RegulatoryFramework.SOX:
|
|
// SOX: Financial data integrity
|
|
if (data.financialData && !data.immutable) {
|
|
warnings.push('SOX: Financial data should be immutable')
|
|
}
|
|
if (!data.auditTrail) {
|
|
requiredActions.push('SOX: Audit trail required')
|
|
}
|
|
break
|
|
}
|
|
|
|
return {
|
|
compliant: violations.length === 0,
|
|
violations,
|
|
warnings,
|
|
requiredActions,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if region is in EU
|
|
*/
|
|
private isEURegion(region: string): boolean {
|
|
const euRegions = [
|
|
'eu-west-1',
|
|
'eu-west-2',
|
|
'eu-west-3',
|
|
'eu-central-1',
|
|
'eu-north-1',
|
|
'eu-south-1',
|
|
]
|
|
return euRegions.some((eu) => region.toLowerCase().includes(eu))
|
|
}
|
|
|
|
/**
|
|
* Enforce retention policy
|
|
*/
|
|
async enforceRetentionPolicy(
|
|
context: Context,
|
|
data: any,
|
|
region: string
|
|
): Promise<void> {
|
|
const db = getDb()
|
|
|
|
// Get retention policy for data type
|
|
const rulesResult = await db.query(
|
|
`SELECT retention_policy FROM data_residency_rules
|
|
WHERE data_type = $1`,
|
|
[data.type || 'default']
|
|
)
|
|
|
|
if (rulesResult.rows.length > 0) {
|
|
const policy = rulesResult.rows[0].retention_policy
|
|
const retentionDays = policy?.retentionDays || 365
|
|
|
|
// Check if data exceeds retention period
|
|
const dataAge = Date.now() - new Date(data.createdAt).getTime()
|
|
const ageInDays = dataAge / (1000 * 60 * 60 * 24)
|
|
|
|
if (ageInDays > retentionDays) {
|
|
logger.info('Data exceeds retention policy', {
|
|
dataId: data.id,
|
|
ageInDays,
|
|
retentionDays,
|
|
})
|
|
// In production, this would trigger data deletion
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Audit data access
|
|
*/
|
|
async auditDataAccess(
|
|
context: Context,
|
|
data: any,
|
|
user: any,
|
|
operation: string
|
|
): Promise<void> {
|
|
const db = getDb()
|
|
|
|
await db.query(
|
|
`INSERT INTO compliance_audit_logs (
|
|
data_id, user_id, operation, region, framework,
|
|
compliant, timestamp
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7)`,
|
|
[
|
|
data.id,
|
|
user.id,
|
|
operation,
|
|
data.region,
|
|
data.framework || 'GENERAL',
|
|
true,
|
|
new Date(),
|
|
]
|
|
)
|
|
|
|
logger.info('Data access audited', {
|
|
dataId: data.id,
|
|
userId: user.id,
|
|
operation,
|
|
})
|
|
}
|
|
}
|
|
|
|
export const complianceEnforcer = new ComplianceEnforcer()
|
|
|