DatabaseSecurityRules.java
package com.cloudforgeci.api.core.rules;
import com.cloudforge.core.annotation.ComplianceFramework;
import com.cloudforge.core.interfaces.FrameworkRules;
import com.cloudforgeci.api.core.SystemContext;
import com.cloudforge.core.enums.ComplianceMode;
import com.cloudforge.core.enums.SecurityProfile;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
* Database security compliance validation rules.
*
* <p>These rules enforce database security best practices across multiple
* compliance frameworks:</p>
* <ul>
* <li><b>PCI-DSS</b> - Req 3.4, 8.7: Database encryption and access control</li>
* <li><b>HIPAA</b> - §164.312(a)(2)(iv), §164.310(d): Database encryption and backup</li>
* <li><b>SOC 2</b> - CC6.1, A1.3: Data protection and availability</li>
* <li><b>GDPR</b> - Art.32, Art.25: Security and data protection by design</li>
* </ul>
*
* <h2>Controls Implemented</h2>
* <ul>
* <li>RDS encryption at rest enforcement</li>
* <li>RDS automated backup validation</li>
* <li>Multi-AZ deployment for production</li>
* <li>Database activity monitoring</li>
* <li>DynamoDB encryption and backup</li>
* </ul>
*
* <h2>Usage</h2>
* <pre>{@code
* // Automatically loaded via FrameworkLoader (v2.0 pattern)
* // Or manually: new DatabaseSecurityRules().install(ctx);
* }</pre>
*
* @since 3.0.0
*/
@ComplianceFramework(
value = "DatabaseSecurity",
priority = -5,
alwaysLoad = true,
displayName = "Database Security",
description = "Cross-framework database security validation"
)
public class DatabaseSecurityRules implements FrameworkRules<SystemContext> {
private static final Logger LOG = Logger.getLogger(DatabaseSecurityRules.class.getName());
/**
* Install database security validation rules.
* These rules apply primarily to PRODUCTION environments.
*
* @param ctx System context
*/
@Override
public void install(SystemContext ctx) {
LOG.info("Installing database security compliance validation rules for " + ctx.security);
ctx.getNode().addValidation(() -> {
List<ComplianceRule> rules = new ArrayList<>();
// RDS security validation
rules.addAll(validateRdsSecurity(ctx));
// DynamoDB security validation
rules.addAll(validateDynamoDbSecurity(ctx));
// Database monitoring
rules.addAll(validateDatabaseMonitoring(ctx));
// Get all failed rules
List<ComplianceRule> failedRules = rules.stream()
.filter(rule -> !rule.passed())
.toList();
if (!failedRules.isEmpty()) {
LOG.warning("Database Security validation found " + failedRules.size() + " recommendations");
failedRules.forEach(rule ->
LOG.warning(" - " + rule.description() + ": " + rule.errorMessage().orElse("")));
// For DEV, these are advisory only
if (ctx.security == SecurityProfile.DEV) {
return List.of();
}
// For PRODUCTION/STAGING, convert to error strings
return failedRules.stream()
.map(rule -> rule.description() + ": " + rule.errorMessage().orElse(""))
.toList();
} else {
LOG.info("Database Security validation passed (" + rules.size() + " checks)");
return List.of();
}
});
}
/**
* Validate RDS database security configuration.
*
* <p>Checks:</p>
* <ul>
* <li>Encryption at rest enabled</li>
* <li>Automated backups enabled</li>
* <li>Multi-AZ deployment for production</li>
* <li>Minor version auto-upgrade</li>
* </ul>
*/
private List<ComplianceRule> validateRdsSecurity(SystemContext ctx) {
List<ComplianceRule> rules = new ArrayList<>();
boolean rdsEnabled = getBooleanSetting(ctx, "rdsEnabled", false);
if (!rdsEnabled) {
// No RDS in use, skip validation
rules.add(ComplianceRule.pass(
"RDS-NOT-USED",
"RDS not enabled - validation skipped"
));
return rules;
}
// RDS encryption at rest
boolean rdsEncryptionEnabled = getBooleanSetting(ctx, "rdsEncryptionEnabled", false);
if (!rdsEncryptionEnabled) {
rules.add(ComplianceRule.fail(
"RDS-ENCRYPTION",
"RDS encryption at rest must be enabled",
"RdsEncryptionAtRestEnabled",
"Enable RDS encryption at rest for all database instances. " +
"PCI-DSS Req 3.4, HIPAA §164.312(a)(2)(iv), GDPR Art.32(1)(a). " +
"Set rdsEncryptionEnabled = true in deployment context."
));
} else {
rules.add(ComplianceRule.pass(
"RDS-ENCRYPTION",
"RDS encryption at rest enabled",
"RdsEncryptionAtRestEnabled"
));
}
// RDS automated backups
boolean rdsBackupEnabled = getBooleanSetting(ctx, "rdsBackupEnabled", true);
if (!rdsBackupEnabled) {
rules.add(ComplianceRule.fail(
"RDS-BACKUP",
"RDS automated backups must be enabled",
"RdsBackupEnabled",
"Enable automated backups for RDS instances (7-35 days retention). " +
"HIPAA §164.310(d)(2)(iii), SOC2 A1.3, GDPR Art.32(1)(c). " +
"Set rdsBackupEnabled = true in deployment context."
));
} else {
rules.add(ComplianceRule.pass(
"RDS-BACKUP",
"RDS automated backups enabled",
"RdsBackupEnabled"
));
}
// Multi-AZ for production - use ComplianceMatrix
boolean rdsMultiAz = getBooleanSetting(ctx, "rdsMultiAz", false);
String complianceFrameworks = ctx.cfc.complianceFrameworks();
ComplianceMode complianceMode = ctx.cfc.complianceMode();
ComplianceMatrix.ValidationResult multiAzResult = ComplianceMatrix.validateControlMultiFramework(
ComplianceMatrix.SecurityControl.DATABASE_MULTI_AZ,
complianceFrameworks,
rdsMultiAz,
complianceMode
);
if (ctx.security == SecurityProfile.PRODUCTION) {
if (multiAzResult == ComplianceMatrix.ValidationResult.FAIL) {
rules.add(ComplianceRule.fail(
"RDS-MULTI-AZ",
"RDS Multi-AZ deployment required for " + complianceFrameworks,
"RdsMultiAzEnabled",
"Enable Multi-AZ deployment for high availability. " +
"Set rdsMultiAz = true in deployment context."
));
} else if (multiAzResult == ComplianceMatrix.ValidationResult.WARN) {
LOG.warning("RDS Multi-AZ recommended but not required for " + complianceFrameworks);
rules.add(ComplianceRule.pass(
"RDS-MULTI-AZ",
"RDS Multi-AZ is advisory for " + complianceFrameworks + " (recommended but not required)",
"RdsMultiAzEnabled"
));
} else {
rules.add(ComplianceRule.pass(
"RDS-MULTI-AZ",
"RDS Multi-AZ deployment enabled",
"RdsMultiAzEnabled"
));
}
}
// Backup retention period
int rdsBackupRetentionDays = getIntSetting(ctx, "rdsBackupRetentionDays", 7);
if (ctx.security == SecurityProfile.PRODUCTION && rdsBackupRetentionDays < 7) {
rules.add(ComplianceRule.fail(
"RDS-BACKUP-RETENTION",
"RDS backup retention must be at least 7 days for production",
"Minimum 7 days backup retention required. Current: " + rdsBackupRetentionDays + " days. " +
"Set rdsBackupRetentionDays = 7 (or higher) in deployment context."
));
} else {
rules.add(ComplianceRule.pass(
"RDS-BACKUP-RETENTION",
"RDS backup retention configured: " + rdsBackupRetentionDays + " days"
));
}
// Minor version auto-upgrade (security patches)
boolean rdsAutoMinorVersionUpgrade = getBooleanSetting(ctx, "rdsAutoMinorVersionUpgrade", true);
if (!rdsAutoMinorVersionUpgrade && ctx.security == SecurityProfile.PRODUCTION) {
rules.add(ComplianceRule.fail(
"RDS-AUTO-UPGRADE",
"RDS automatic minor version upgrades recommended for production",
"Enable automatic minor version upgrades for security patches. " +
"PCI-DSS Req 6.2. Set rdsAutoMinorVersionUpgrade = true."
));
} else {
rules.add(ComplianceRule.pass(
"RDS-AUTO-UPGRADE",
"RDS automatic minor version upgrades enabled"
));
}
return rules;
}
/**
* Validate DynamoDB security configuration.
*
* <p>Checks:</p>
* <ul>
* <li>Encryption at rest enabled</li>
* <li>Point-in-time recovery enabled</li>
* <li>Backup enabled</li>
* </ul>
*/
private List<ComplianceRule> validateDynamoDbSecurity(SystemContext ctx) {
List<ComplianceRule> rules = new ArrayList<>();
boolean dynamoDbEnabled = getBooleanSetting(ctx, "dynamoDbEnabled", false);
if (!dynamoDbEnabled) {
// No DynamoDB in use, skip validation
rules.add(ComplianceRule.pass(
"DYNAMODB-NOT-USED",
"DynamoDB not enabled - validation skipped"
));
return rules;
}
// DynamoDB encryption at rest
boolean dynamoDbEncryptionEnabled = getBooleanSetting(ctx, "dynamoDbEncryptionEnabled", true);
if (!dynamoDbEncryptionEnabled) {
rules.add(ComplianceRule.fail(
"DYNAMODB-ENCRYPTION",
"DynamoDB encryption at rest must be enabled",
"DynamoDbEncryptionEnabled",
"Enable DynamoDB encryption at rest (KMS). " +
"PCI-DSS Req 3.4, HIPAA §164.312(a)(2)(iv), GDPR Art.32(1)(a). " +
"Set dynamoDbEncryptionEnabled = true in deployment context."
));
} else {
rules.add(ComplianceRule.pass(
"DYNAMODB-ENCRYPTION",
"DynamoDB encryption at rest enabled",
"DynamoDbEncryptionEnabled"
));
}
// DynamoDB Point-in-Time Recovery - use ComplianceMatrix
boolean dynamoDbPitrEnabled = getBooleanSetting(ctx, "dynamoDbPitrEnabled", false);
String complianceFrameworks = ctx.cfc.complianceFrameworks();
ComplianceMode complianceMode = ctx.cfc.complianceMode();
ComplianceMatrix.ValidationResult pitrResult = ComplianceMatrix.validateControlMultiFramework(
ComplianceMatrix.SecurityControl.DATABASE_PITR,
complianceFrameworks,
dynamoDbPitrEnabled,
complianceMode
);
if (ctx.security == SecurityProfile.PRODUCTION) {
if (pitrResult == ComplianceMatrix.ValidationResult.FAIL) {
rules.add(ComplianceRule.fail(
"DYNAMODB-PITR",
"DynamoDB Point-in-Time Recovery required for " + complianceFrameworks,
"DynamoDbPitrEnabled",
"Enable Point-in-Time Recovery for production tables. " +
"Set dynamoDbPitrEnabled = true in deployment context."
));
} else if (pitrResult == ComplianceMatrix.ValidationResult.WARN) {
LOG.warning("DynamoDB PITR recommended but not required for " + complianceFrameworks);
rules.add(ComplianceRule.pass(
"DYNAMODB-PITR",
"DynamoDB PITR is advisory for " + complianceFrameworks + " (recommended but not required)",
"DynamoDbPitrEnabled"
));
} else {
rules.add(ComplianceRule.pass(
"DYNAMODB-PITR",
"DynamoDB Point-in-Time Recovery enabled",
"DynamoDbPitrEnabled"
));
}
}
return rules;
}
/**
* Validate database monitoring and auditing.
*
* <p>Checks:</p>
* <ul>
* <li>Database activity monitoring enabled</li>
* <li>Performance Insights enabled</li>
* <li>Enhanced monitoring enabled</li>
* </ul>
*/
private List<ComplianceRule> validateDatabaseMonitoring(SystemContext ctx) {
List<ComplianceRule> rules = new ArrayList<>();
boolean rdsEnabled = getBooleanSetting(ctx, "rdsEnabled", false);
if (!rdsEnabled) {
return rules; // Skip if RDS not in use
}
// Database Activity Streams (audit logging)
boolean dbActivityStreamsEnabled = getBooleanSetting(ctx, "dbActivityStreamsEnabled", false);
if (ctx.security == SecurityProfile.PRODUCTION && !dbActivityStreamsEnabled) {
rules.add(ComplianceRule.fail(
"DB-ACTIVITY-STREAMS",
"Database Activity Streams recommended for production audit logging",
"Enable Database Activity Streams for real-time audit logging. " +
"PCI-DSS Req 10.2, HIPAA §164.312(b). " +
"Set dbActivityStreamsEnabled = true in deployment context."
));
} else if (dbActivityStreamsEnabled) {
rules.add(ComplianceRule.pass(
"DB-ACTIVITY-STREAMS",
"Database Activity Streams enabled"
));
}
// Performance Insights
boolean performanceInsightsEnabled = getBooleanSetting(ctx, "performanceInsightsEnabled", false);
if (performanceInsightsEnabled) {
rules.add(ComplianceRule.pass(
"DB-PERFORMANCE-INSIGHTS",
"RDS Performance Insights enabled"
));
// Performance Insights encryption
boolean performanceInsightsEncrypted = getBooleanSetting(ctx, "performanceInsightsEncrypted", true);
if (!performanceInsightsEncrypted) {
rules.add(ComplianceRule.fail(
"DB-PERFORMANCE-INSIGHTS-ENCRYPTION",
"Performance Insights data must be encrypted",
"Enable encryption for Performance Insights data. " +
"Set performanceInsightsEncrypted = true."
));
} else {
rules.add(ComplianceRule.pass(
"DB-PERFORMANCE-INSIGHTS-ENCRYPTION",
"Performance Insights encryption enabled"
));
}
}
// Enhanced Monitoring
boolean enhancedMonitoringEnabled = getBooleanSetting(ctx, "rdsEnhancedMonitoringEnabled", false);
if (ctx.security == SecurityProfile.PRODUCTION && !enhancedMonitoringEnabled) {
rules.add(ComplianceRule.fail(
"DB-ENHANCED-MONITORING",
"RDS Enhanced Monitoring recommended for production",
"Enable Enhanced Monitoring for real-time OS metrics. " +
"SOC2 CC7.2. Set rdsEnhancedMonitoringEnabled = true."
));
} else if (enhancedMonitoringEnabled) {
rules.add(ComplianceRule.pass(
"DB-ENHANCED-MONITORING",
"RDS Enhanced Monitoring enabled"
));
}
return rules;
}
/**
* Helper method to safely get boolean settings from deployment context.
*/
private boolean getBooleanSetting(SystemContext ctx, String key, boolean defaultValue) {
try {
String value = ctx.cfc.getContextValue(key, String.valueOf(defaultValue));
return Boolean.parseBoolean(value);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Helper method to safely get integer settings from deployment context.
*/
private int getIntSetting(SystemContext ctx, String key, int defaultValue) {
try {
String value = ctx.cfc.getContextValue(key, String.valueOf(defaultValue));
return Integer.parseInt(value);
} catch (Exception e) {
return defaultValue;
}
}
}