Dynamic Gate Thresholds and Risk-Based Decisions

Dynamic Gate Thresholds and Risk-Based Decisions

Static security thresholds fail to account for context. A critical vulnerability in a proof-of-concept might be acceptable, while a medium vulnerability in payment processing code requires immediate attention. Dynamic thresholds adjust based on factors like deployment environment, data sensitivity, and business criticality.

// Dynamic threshold calculation for security gates
class DynamicSecurityGate {
    constructor(config) {
        this.baseThresholds = config.baseThresholds;
        this.riskFactors = config.riskFactors;
        this.environmentMultipliers = config.environmentMultipliers;
    }
    
    calculateThresholds(context) {
        const {
            environment,
            dataClassification,
            businessCriticality,
            exposureLevel,
            complianceRequirements
        } = context;
        
        // Start with base thresholds
        let thresholds = { ...this.baseThresholds };
        
        // Apply environment multiplier
        const envMultiplier = this.environmentMultipliers[environment] || 1.0;
        
        // Calculate risk score
        const riskScore = this.calculateRiskScore({
            dataClassification,
            businessCriticality,
            exposureLevel,
            complianceRequirements
        });
        
        // Adjust thresholds based on risk
        Object.keys(thresholds).forEach(severity => {
            thresholds[severity] = Math.floor(
                thresholds[severity] * envMultiplier / riskScore
            );
        });
        
        return thresholds;
    }
    
    calculateRiskScore(factors) {
        let score = 1.0;
        
        // Data classification impact
        const dataScores = {
            'public': 0.5,
            'internal': 1.0,
            'confidential': 2.0,
            'restricted': 3.0
        };
        score *= dataScores[factors.dataClassification] || 1.0;
        
        // Business criticality impact
        const criticalityScores = {
            'low': 0.5,
            'medium': 1.0,
            'high': 2.0,
            'critical': 3.0
        };
        score *= criticalityScores[factors.businessCriticality] || 1.0;
        
        // Exposure level impact
        const exposureScores = {
            'internal': 0.5,
            'partner': 1.0,
            'customer': 2.0,
            'public': 3.0
        };
        score *= exposureScores[factors.exposureLevel] || 1.0;
        
        // Compliance requirements impact
        if (factors.complianceRequirements.includes('pci')) score *= 2.0;
        if (factors.complianceRequirements.includes('hipaa')) score *= 2.0;
        if (factors.complianceRequirements.includes('gdpr')) score *= 1.5;
        
        return Math.max(score, 0.1); // Prevent division by zero
    }
    
    async evaluateGate(scanResults, context) {
        const thresholds = this.calculateThresholds(context);
        const decision = {
            passed: true,
            thresholds: thresholds,
            violations: [],
            context: context,
            timestamp: new Date().toISOString()
        };
        
        // Check each severity level
        for (const [severity, count] of Object.entries(scanResults.vulnerabilities)) {
            if (count > thresholds[severity]) {
                decision.passed = false;
                decision.violations.push({
                    severity: severity,
                    count: count,
                    threshold: thresholds[severity],
                    exceeded_by: count - thresholds[severity]
                });
            }
        }
        
        // Apply override logic
        if (!decision.passed) {
            const override = await this.checkForOverride(decision, context);
            if (override.approved) {
                decision.passed = true;
                decision.override = override;
            }
        }
        
        return decision;
    }
    
    async checkForOverride(decision, context) {
        // Check for pre-approved exceptions
        const exceptions = await this.loadExceptions();
        
        for (const exception of exceptions) {
            if (this.matchesException(decision, exception)) {
                return {
                    approved: true,
                    exception_id: exception.id,
                    approver: exception.approver,
                    expires: exception.expires,
                    reason: exception.reason
                };
            }
        }
        
        // Check for emergency override
        if (context.emergency_deployment && context.emergency_approvers) {
            return {
                approved: true,
                type: 'emergency',
                approvers: context.emergency_approvers,
                reason: context.emergency_reason
            };
        }
        
        return { approved: false };
    }
}