FedRampRules.java

package com.cloudforgeci.api.core.rules;

import com.cloudforge.core.annotation.ComplianceFramework;
import com.cloudforge.core.enums.AuthMode;
import com.cloudforge.core.enums.ComplianceMode;
import com.cloudforge.core.enums.NetworkMode;
import com.cloudforge.core.enums.RuntimeType;
import com.cloudforge.core.enums.SecurityProfile;
import com.cloudforge.core.interfaces.FrameworkRules;
import com.cloudforgeci.api.interfaces.SecurityProfileConfiguration;
import com.cloudforgeci.api.core.SystemContext;
import software.amazon.awscdk.services.logs.RetentionDays;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.Set;

/**
 * FedRAMP Moderate compliance validation.
 *
 * Validates FedRAMP requirements based on NIST SP 800-53 Rev 5 controls.
 * FedRAMP (Federal Risk and Authorization Management Program) provides a standardized
 * approach to security assessment, authorization, and continuous monitoring for
 * cloud products and services used by U.S. federal agencies.
 *
 * <h2>Control Family Coverage (11 Technical Families):</h2>
 * <ul>
 *   <li><b>AC</b> - Access Control (AC-2 through AC-22)</li>
 *   <li><b>AU</b> - Audit and Accountability (AU-2 through AU-12)</li>
 *   <li><b>CA</b> - Assessment, Authorization, and Monitoring (CA-7, CA-9)</li>
 *   <li><b>CM</b> - Configuration Management (CM-2 through CM-8)</li>
 *   <li><b>CP</b> - Contingency Planning (CP-6 through CP-10)</li>
 *   <li><b>IA</b> - Identification and Authentication (IA-2 through IA-8)</li>
 *   <li><b>IR</b> - Incident Response (IR-4 through IR-6)</li>
 *   <li><b>MP</b> - Media Protection (MP-2 through MP-7)</li>
 *   <li><b>RA</b> - Risk Assessment (RA-5)</li>
 *   <li><b>SC</b> - System and Communications Protection (SC-7 through SC-28)</li>
 *   <li><b>SI</b> - System and Information Integrity (SI-2 through SI-7)</li>
 * </ul>
 *
 * <h2>FedRAMP Baseline Levels:</h2>
 * <ul>
 *   <li><b>Low</b> - 156 controls (not implemented here)</li>
 *   <li><b>Moderate</b> - 323 controls (this implementation)</li>
 *   <li><b>High</b> - 410 controls (see FedRampHighRules)</li>
 * </ul>
 *
 * <h2>Key Differences from Other Frameworks:</h2>
 * <ul>
 *   <li>3-year log retention requirement (vs HIPAA 6-year, PCI-DSS 1-year)</li>
 *   <li>FIPS 140-2 cryptographic module validation required</li>
 *   <li>Continuous monitoring (ConMon) with monthly vulnerability scans</li>
 *   <li>Annual penetration testing required</li>
 * </ul>
 *
 * @since 3.1.0
 * @see <a href="https://www.fedramp.gov/">FedRAMP Official Site</a>
 * @see <a href="https://nvd.nist.gov/800-53">NIST SP 800-53 Rev 5</a>
 */
@ComplianceFramework(
    value = "FEDRAMP",
    priority = 25,  // Between PCI-DSS (20) and GDPR (30)
    displayName = "FedRAMP Moderate",
    description = "Federal Risk and Authorization Management Program - NIST 800-53 Rev 5 Moderate Baseline"
)
public class FedRampRules implements FrameworkRules<SystemContext> {
    private static final Logger LOG = Logger.getLogger(FedRampRules.class.getName());

    /** Controls that still block STAGING synthesis: authentication (IA-2, IA-2(1) MFA, IA-5/IA-5(1)
     *  password policy, AC-7 lockout), network isolation (AC-17, AC-17(2) encrypted remote access,
     *  SC-7(5) default deny), SSL/TLS in transit (SC-8, SC-8(1) HTTPS-strict), encryption at rest
     *  (SC-28), and audit logging (AU-2/AU-3/AU-6/AU-9/AU-11/AU-12) -- federal data may exist in
     *  STAGING, so these can't be downgraded to a non-blocking finding there. AC-3/AC-4/SC-7/SC-7-WAF
     *  are access-enforcement/flow-logging/WAF controls, not auth/network-isolation/SSL themselves,
     *  so they stay non-blocking like every other STAGING finding. */
    private static final Set<String> STAGING_BLOCKING_RULES = Set.of(
        "FEDRAMP-IA-2", "FEDRAMP-IA-2(1)", "FEDRAMP-IA-5", "FEDRAMP-IA-5(1)", "FEDRAMP-AC-7",
        "FEDRAMP-AC-17", "FEDRAMP-AC-17(2)", "FEDRAMP-SC-7(5)", "FEDRAMP-SC-8", "FEDRAMP-SC-8(1)-HTTPSStrict",
        "FEDRAMP-SC-28", "FEDRAMP-AU-2", "FEDRAMP-AU-3", "FEDRAMP-AU-6", "FEDRAMP-AU-9",
        "FEDRAMP-AU-9-LogEncryption", "FEDRAMP-AU-9-AuditLogImmutability", "FEDRAMP-AU-11",
        "FEDRAMP-AU-12", "FEDRAMP-AU-12-ALB", "FEDRAMP-CP-9", "FEDRAMP-MP-5-EFS"
    );

    // FedRAMP requires 3-year retention for audit records (AU-11)
    private static final int FEDRAMP_MIN_RETENTION_DAYS = 365 * 3; // 1095 days

    // FedRAMP password requirements (IA-5(1))
    private static final int FEDRAMP_MIN_PASSWORD_LENGTH = 12;

    /**
     * Install FedRAMP compliance validation rules for production and staging environments.
     * Federal systems require strict controls even in pre-production environments.
     */
    @Override
    public void install(SystemContext ctx) {
        // FedRAMP enforcement for production and staging only
        if (ctx.security != SecurityProfile.PRODUCTION && ctx.security != SecurityProfile.STAGING) {
            LOG.info("FedRAMP validation rules enforced for PRODUCTION and STAGING profiles only");
            return;
        }

        LOG.info("Installing FedRAMP Moderate compliance validation for " + ctx.security);

        // Get compliance mode (already resolved to enum with proper default)
        ComplianceMode complianceMode = ctx.cfc.complianceMode();

        LOG.info("  Compliance mode: " + complianceMode);

        ctx.getNode().addValidation(() -> {
            List<ComplianceRule> rules = new ArrayList<>();

            // AC Family - Access Control
            rules.addAll(validateAccessControl(ctx));

            // AU Family - Audit and Accountability
            rules.addAll(validateAuditAccountability(ctx));

            // CA Family - Assessment, Authorization, and Monitoring
            rules.addAll(validateContinuousMonitoring(ctx));

            // CM Family - Configuration Management
            rules.addAll(validateConfigurationManagement(ctx));

            // CP Family - Contingency Planning
            rules.addAll(validateContingencyPlanning(ctx));

            // IA Family - Identification and Authentication
            rules.addAll(validateIdentificationAuthentication(ctx));

            // IR Family - Incident Response
            rules.addAll(validateIncidentResponse(ctx));

            // MP Family - Media Protection
            rules.addAll(validateMediaProtection(ctx));

            // RA Family - Risk Assessment
            rules.addAll(validateRiskAssessment(ctx));

            // SC Family - System and Communications Protection
            rules.addAll(validateSystemCommunications(ctx));

            // SI Family - System and Information Integrity
            rules.addAll(validateSystemIntegrity(ctx));

            // Matrix-required controls not covered by any control family above
            rules.addAll(validateMatrixControls(
                ctx.securityProfileConfig.get().orElseThrow(
                    () -> new IllegalStateException("SecurityProfileConfiguration not set")),
                ctx.runtime,
                ctx.dbConnection.get().isPresent()));

            return ComplianceEnforcement.resolve(
                "FedRAMP Moderate", rules, complianceMode, ctx.security, STAGING_BLOCKING_RULES, LOG);
        });
    }

    // ========================================================================
    // AC Family - Access Control
    // ========================================================================

    /**
     * Validates Access Control family controls (AC-2 through AC-22).
     *
     * Key controls:
     * - AC-2: Account Management
     * - AC-3: Access Enforcement
     * - AC-4: Information Flow Enforcement
     * - AC-6: Least Privilege
     * - AC-7: Unsuccessful Logon Attempts
     * - AC-17: Remote Access
     */
    private List<ComplianceRule> validateAccessControl(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // AC-2: Account Management - IAM profile must be configured
        if (ctx.iamProfile == null) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-2",
                "Account management controls required (NIST AC-2)",
                "iam-user-group-membership-check",
                "Configure IAM profile for role-based access control."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-2",
                "Account management controls configured (NIST AC-2)",
                "iam-user-group-membership-check"
            ));
        }

        // AC-3: Access Enforcement - Security groups must be configured
        if (ctx.albSg.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-3",
                "Access enforcement controls required (NIST AC-3)",
                "Security groups must be configured to enforce access policies."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-3",
                "Access enforcement controls configured (NIST AC-3)"
            ));
        }

        // AC-4: Information Flow Enforcement - VPC Flow Logs required
        if (!config.isFlowLogsEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-4",
                "Information flow enforcement requires VPC Flow Logs (NIST AC-4)",
                "vpc-flow-logs-enabled",
                "Enable VPC Flow Logs to monitor and control information flow."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-4",
                "Information flow enforcement enabled via VPC Flow Logs (NIST AC-4)",
                "vpc-flow-logs-enabled"
            ));
        }

        // AC-6: Least Privilege - continuously validated by AWS Config's
        // iam-policy-no-statements-with-admin-access managed rule, provisioned by
        // ComplianceFactory only when AWS Config is enabled.
        if (!config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-6",
                "Least privilege requires continuous IAM policy monitoring via AWS Config (NIST AC-6)",
                "iam-policy-no-statements-with-admin-access",
                "Set awsConfigEnabled = true to provision the least-privilege Config rule."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-6",
                "Least privilege enforced via IAM policies (NIST AC-6)",
                "iam-policy-no-statements-with-admin-access"
            ));
        }

        // AC-7: Unsuccessful Logon Attempts - Cognito lockout policy
        AuthMode authMode = ctx.cfc.authMode();
        if (authMode != AuthMode.NONE) {
            // If using Cognito, it has built-in account lockout
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-7",
                "Unsuccessful logon attempt handling configured (NIST AC-7)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-7",
                "Authentication required for unsuccessful logon attempt handling (NIST AC-7)",
                "Configure authentication with account lockout policy."
            ));
        }

        // AC-17: Remote Access - SSH must be restricted
        if (ctx.cfc.networkMode() == NetworkMode.PUBLIC) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-17",
                "Remote access must be through controlled access points (NIST AC-17)",
                "restricted-ssh",
                "Use private-with-nat network mode for controlled remote access."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-17",
                "Remote access controlled via private network (NIST AC-17)",
                "restricted-ssh"
            ));
        }

        // AC-17(2): Remote Access - Encryption required
        if (ctx.cert.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AC-17(2)",
                "Remote access must use encrypted channels (NIST AC-17(2))",
                "alb-http-to-https-redirection-check",
                "Configure TLS certificate for encrypted remote access."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AC-17(2)",
                "Remote access encrypted via TLS (NIST AC-17(2))",
                "alb-http-to-https-redirection-check"
            ));
        }

        return rules;
    }

    // ========================================================================
    // AU Family - Audit and Accountability
    // ========================================================================

    /**
     * Validates Audit and Accountability family controls (AU-2 through AU-12).
     *
     * Key controls:
     * - AU-2: Event Logging (CloudTrail)
     * - AU-3: Content of Audit Records
     * - AU-6: Audit Review, Analysis, and Reporting
     * - AU-9: Protection of Audit Information
     * - AU-11: Audit Record Retention (3 years)
     * - AU-12: Audit Record Generation
     */
    private List<ComplianceRule> validateAuditAccountability(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // AU-2: Event Logging - CloudTrail must be enabled
        if (!config.isCloudTrailEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-2",
                "Event logging via CloudTrail required (NIST AU-2)",
                "cloudtrail-enabled",
                "Enable CloudTrail for comprehensive audit logging."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-2",
                "Event logging enabled via CloudTrail (NIST AU-2)",
                "cloudtrail-enabled"
            ));
        }

        // AU-3: Content of Audit Records - CloudTrail provides detailed records
        if (config.isCloudTrailEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-3",
                "Audit records contain required content via CloudTrail (NIST AU-3)",
                "cloud-trail-log-file-validation-enabled"
            ));
        }

        // AU-6: Audit Review - Security Hub and GuardDuty for automated review
        if (!config.isGuardDutyEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-6",
                "Automated audit review required via GuardDuty (NIST AU-6)",
                "guardduty-enabled-centralized",
                "Enable GuardDuty for automated audit log analysis."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-6",
                "Automated audit review enabled via GuardDuty (NIST AU-6)",
                "guardduty-enabled-centralized"
            ));
        }

        // AU-9: Protection of Audit Information - S3 encryption for logs
        if (!config.isS3EncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-9",
                "Audit information must be protected via encryption (NIST AU-9)",
                "s3-bucket-server-side-encryption-enabled",
                "Enable S3 encryption for audit log protection."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-9",
                "Audit information protected via S3 encryption (NIST AU-9)",
                "s3-bucket-server-side-encryption-enabled"
            ));
        }

        // AU-11: Audit Record Retention - FedRAMP requires 3 years
        var retentionDays = config.getLogRetentionDays();
        if (!isRetentionSufficient(retentionDays)) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-11",
                "Audit record retention must be at least 3 years (NIST AU-11)",
                "cloudwatch-log-group-encrypted",
                "FedRAMP requires 3-year retention. Current: " + retentionDays.toString() + ". " +
                "Configure log retention to at least THREE_YEARS."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-11",
                "Audit record retention meets 3-year requirement (NIST AU-11)",
                "cloudwatch-log-group-encrypted"
            ));
        }

        // AU-12: Audit Record Generation - Multi-source logging
        if (config.isCloudTrailEnabled() && config.isFlowLogsEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-12",
                "Audit records generated from multiple sources (NIST AU-12)",
                "multi-region-cloudtrail-enabled"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-12",
                "Comprehensive audit record generation required (NIST AU-12)",
                "multi-region-cloudtrail-enabled",
                "Enable both CloudTrail and VPC Flow Logs for complete audit coverage."
            ));
        }

        // ALB Access Logging
        if (!config.isAlbAccessLoggingEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-12-ALB",
                "ALB access logging required for web request auditing (NIST AU-12)",
                "elb-logging-enabled",
                "Enable ALB access logging for comprehensive request tracking."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-12-ALB",
                "ALB access logging enabled (NIST AU-12)",
                "elb-logging-enabled"
            ));
        }

        return rules;
    }

    // ========================================================================
    // CA Family - Assessment, Authorization, and Monitoring
    // ========================================================================

    /**
     * Validates Continuous Monitoring controls (CA-7, CA-9).
     *
     * Key controls:
     * - CA-7: Continuous Monitoring (AWS Config)
     * - CA-9: Internal System Connections
     */
    private List<ComplianceRule> validateContinuousMonitoring(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // CA-7: Continuous Monitoring - AWS Config must be enabled
        if (!config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CA-7",
                "Continuous monitoring required via AWS Config (NIST CA-7)",
                "Enable AWS Config for continuous compliance monitoring."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CA-7",
                "Continuous monitoring enabled via AWS Config (NIST CA-7)"
            ));
        }

        // CA-7(4): Risk Monitoring - Security Hub
        if (!config.isSecurityMonitoringEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CA-7(4)",
                "Security risk monitoring required (NIST CA-7(4))",
                "securityhub-enabled",
                "Enable Security Hub for risk-based monitoring."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CA-7(4)",
                "Security risk monitoring enabled (NIST CA-7(4))",
                "securityhub-enabled"
            ));
        }

        return rules;
    }

    // ========================================================================
    // CM Family - Configuration Management
    // ========================================================================

    /**
     * Validates Configuration Management controls (CM-2 through CM-8).
     *
     * Key controls:
     * - CM-2: Baseline Configuration (IaC via CDK)
     * - CM-3: Configuration Change Control
     * - CM-6: Configuration Settings
     * - CM-8: System Component Inventory
     */
    private List<ComplianceRule> validateConfigurationManagement(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // CM-2: Baseline Configuration - Deployment via CDK/IaC
        rules.add(ComplianceRule.pass(
            "FEDRAMP-CM-2",
            "Baseline configuration maintained via Infrastructure as Code (NIST CM-2)"
        ));

        // CM-3: Configuration Change Control - CloudTrail logs all changes
        if (config.isCloudTrailEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CM-3",
                "Configuration changes tracked via CloudTrail (NIST CM-3)",
                "cloudtrail-enabled"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CM-3",
                "Configuration change tracking required (NIST CM-3)",
                "cloudtrail-enabled",
                "Enable CloudTrail to track all configuration changes."
            ));
        }

        // CM-6: Configuration Settings - AWS Config rules
        if (config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CM-6",
                "Configuration settings monitored via AWS Config (NIST CM-6)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CM-6",
                "Configuration compliance monitoring required (NIST CM-6)",
                "Enable AWS Config for configuration settings validation."
            ));
        }

        // CM-8: System Component Inventory - AWS Config resource inventory
        if (config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CM-8",
                "System component inventory maintained via AWS Config (NIST CM-8)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CM-8",
                "System component inventory required (NIST CM-8)",
                "Enable AWS Config to maintain a resource inventory."
            ));
        }

        return rules;
    }

    // ========================================================================
    // CP Family - Contingency Planning
    // ========================================================================

    /**
     * Validates Contingency Planning controls (CP-6 through CP-10).
     *
     * Key controls:
     * - CP-6: Alternate Storage Site
     * - CP-9: System Backup
     * - CP-10: System Recovery
     */
    private List<ComplianceRule> validateContingencyPlanning(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // CP-6: Alternate Storage Site - Cross-region backup
        boolean isProdOrStaging = ctx.security == SecurityProfile.PRODUCTION || ctx.security == SecurityProfile.STAGING;
        if (isProdOrStaging && !config.isCrossRegionBackupEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CP-6",
                "Alternate storage site required for production (NIST CP-6)",
                "s3-bucket-replication-enabled",
                "Enable cross-region backup for disaster recovery."
            ));
        } else if (isProdOrStaging) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CP-6",
                "Alternate storage site configured via cross-region backup (NIST CP-6)",
                "s3-bucket-replication-enabled"
            ));
        }

        // CP-9: System Backup - Automated backups must be enabled
        if (!config.isAutomatedBackupEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CP-9",
                "Automated system backups required (NIST CP-9)",
                "db-instance-backup-enabled",
                "Enable automated backups for data protection."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CP-9",
                "Automated system backups enabled (NIST CP-9)",
                "db-instance-backup-enabled"
            ));
        }

        // CP-10: System Recovery - Multi-AZ for high availability
        if (isProdOrStaging && !config.isMultiAzEnforced()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-CP-10",
                "System recovery capability required via Multi-AZ (NIST CP-10)",
                "rds-multi-az-support",
                "Enable Multi-AZ deployment for system recovery."
            ));
        } else if (isProdOrStaging) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-CP-10",
                "System recovery capability enabled via Multi-AZ (NIST CP-10)",
                "rds-multi-az-support"
            ));
        }

        return rules;
    }

    // ========================================================================
    // IA Family - Identification and Authentication
    // ========================================================================

    /**
     * Validates Identification and Authentication controls (IA-2 through IA-8).
     *
     * Key controls:
     * - IA-2: User Identification and Authentication
     * - IA-2(1): Multi-Factor Authentication
     * - IA-5: Authenticator Management (password policy)
     */
    private List<ComplianceRule> validateIdentificationAuthentication(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        // IA-2: User Identification and Authentication
        AuthMode authMode = ctx.cfc.authMode();
        if (authMode == AuthMode.NONE) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-IA-2",
                "User identification and authentication required (NIST IA-2)",
                "Configure authMode = 'alb-oidc', 'jenkins-oidc', or 'application-oidc'."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-IA-2",
                "User identification and authentication enabled (NIST IA-2)"
            ));
        }

        // IA-2(1): Multi-Factor Authentication for privileged accounts
        if (authMode == AuthMode.ALB_OIDC || authMode == AuthMode.APPLICATION_OIDC) {
            boolean usingCognitoWithMfa = Boolean.TRUE.equals(ctx.cfc.cognitoAutoProvision())
                                       && Boolean.TRUE.equals(ctx.cfc.cognitoMfaEnabled());
            boolean hasValidSso = ctx.cfc.ssoInstanceArn() != null && !ctx.cfc.ssoInstanceArn().isEmpty();

            if (!usingCognitoWithMfa && !hasValidSso) {
                rules.add(ComplianceRule.fail(
                    "FEDRAMP-IA-2(1)",
                    "Multi-factor authentication required for privileged access (NIST IA-2(1))",
                    "iam-user-mfa-enabled",
                    "Enable Cognito MFA or configure AWS IAM Identity Center with MFA."
                ));
            } else {
                rules.add(ComplianceRule.pass(
                    "FEDRAMP-IA-2(1)",
                    "Multi-factor authentication configured (NIST IA-2(1))",
                    "iam-user-mfa-enabled"
                ));
            }
        }

        // IA-5 / IA-5(1): Authenticator Management - FedRAMP requires minimum 12-character passwords
        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );
        int passwordLength = config.getMinimumPasswordLength();
        if (passwordLength < FEDRAMP_MIN_PASSWORD_LENGTH) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-IA-5",
                "Authenticator management requires a minimum " + FEDRAMP_MIN_PASSWORD_LENGTH
                    + "-character password policy (NIST IA-5)",
                "iam-password-policy",
                "Current: " + passwordLength + " characters. Update SecurityProfileConfiguration.getMinimumPasswordLength()."
            ));
            rules.add(ComplianceRule.fail(
                "FEDRAMP-IA-5(1)",
                "Password complexity requirements not met (NIST IA-5(1)) - minimum "
                    + FEDRAMP_MIN_PASSWORD_LENGTH + " characters required",
                "iam-password-policy",
                "Current: " + passwordLength + " characters."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-IA-5",
                "Authenticator management enforced via IAM password policy (NIST IA-5)",
                "iam-password-policy"
            ));
            rules.add(ComplianceRule.pass(
                "FEDRAMP-IA-5(1)",
                "Password complexity requirements enforced (NIST IA-5(1)) - " + passwordLength + " characters",
                "iam-password-policy"
            ));
        }

        return rules;
    }

    // ========================================================================
    // IR Family - Incident Response
    // ========================================================================

    /**
     * Validates Incident Response controls (IR-4 through IR-6).
     *
     * Key controls:
     * - IR-4: Incident Handling (GuardDuty)
     * - IR-5: Incident Monitoring
     * - IR-6: Incident Reporting (Security Hub)
     */
    private List<ComplianceRule> validateIncidentResponse(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // IR-4: Incident Handling - GuardDuty for automated detection
        if (!config.isGuardDutyEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-IR-4",
                "Incident handling capability required via GuardDuty (NIST IR-4)",
                "guardduty-enabled-centralized",
                "Enable GuardDuty for automated incident detection and handling."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-IR-4",
                "Incident handling capability enabled via GuardDuty (NIST IR-4)",
                "guardduty-enabled-centralized"
            ));
        }

        // IR-5: Incident Monitoring
        if (config.isSecurityMonitoringEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-IR-5",
                "Incident monitoring enabled via CloudWatch and GuardDuty (NIST IR-5)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-IR-5",
                "Incident monitoring required (NIST IR-5)",
                "Enable security monitoring for incident detection."
            ));
        }

        // IR-6: Incident Reporting - Security Hub aggregates findings
        if (config.isSecurityMonitoringEnabled() && config.isGuardDutyEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-IR-6",
                "Incident reporting capability enabled via Security Hub (NIST IR-6)",
                "securityhub-enabled"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-IR-6",
                "Incident reporting capability required (NIST IR-6)",
                "securityhub-enabled",
                "Enable both security monitoring and GuardDuty to aggregate findings for incident reporting."
            ));
        }

        return rules;
    }

    // ========================================================================
    // MP Family - Media Protection
    // ========================================================================

    /**
     * Validates Media Protection controls (MP-2 through MP-7).
     *
     * Key controls:
     * - MP-4: Media Storage (encryption at rest)
     * - MP-5: Media Transport (encryption in transit)
     */
    private List<ComplianceRule> validateMediaProtection(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // MP-4: Media Storage - Encryption at rest
        if (!config.isEbsEncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-MP-4-EBS",
                "Media storage encryption required for EBS (NIST MP-4)",
                "encrypted-volumes",
                "Enable EBS encryption for data at rest protection."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-MP-4-EBS",
                "EBS encryption enabled for media storage (NIST MP-4)",
                "encrypted-volumes"
            ));
        }

        if (!config.isEfsEncryptionAtRestEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-MP-4-EFS",
                "Media storage encryption required for EFS (NIST MP-4)",
                "efs-encrypted-check",
                "Enable EFS encryption at rest."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-MP-4-EFS",
                "EFS encryption at rest enabled (NIST MP-4)",
                "efs-encrypted-check"
            ));
        }

        // MP-5: Media Transport - Encryption in transit
        if (!config.isEfsEncryptionInTransitEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-MP-5-EFS",
                "Media transport encryption required for EFS (NIST MP-5)",
                "Enable EFS encryption in transit."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-MP-5-EFS",
                "EFS encryption in transit enabled (NIST MP-5)"
            ));
        }

        // TLS for web traffic
        if (ctx.cert.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-MP-5-TLS",
                "Media transport encryption required via TLS (NIST MP-5)",
                "elb-tls-https-listeners-only",
                "Configure TLS certificate for encrypted transport."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-MP-5-TLS",
                "TLS encryption enabled for media transport (NIST MP-5)",
                "elb-tls-https-listeners-only"
            ));
        }

        return rules;
    }

    // ========================================================================
    // RA Family - Risk Assessment
    // ========================================================================

    /**
     * Validates Risk Assessment controls (RA-5).
     *
     * Key controls:
     * - RA-5: Vulnerability Monitoring and Scanning
     */
    private List<ComplianceRule> validateRiskAssessment(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // RA-5: Vulnerability Monitoring - AWS Config rules
        if (!config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-RA-5",
                "Vulnerability monitoring required via AWS Config (NIST RA-5)",
                "Enable AWS Config for continuous vulnerability assessment."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-RA-5",
                "Vulnerability monitoring enabled via AWS Config (NIST RA-5)"
            ));
        }

        // RA-5(2): Update Frequency - Continuous monitoring
        if (config.isAwsConfigEnabled() && config.isGuardDutyEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-RA-5(2)",
                "Continuous vulnerability monitoring enabled (NIST RA-5(2))"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-RA-5(2)",
                "Continuous vulnerability monitoring required (NIST RA-5(2))",
                "Enable both AWS Config and GuardDuty for continuous scanning."
            ));
        }

        return rules;
    }

    // ========================================================================
    // SC Family - System and Communications Protection
    // ========================================================================

    /**
     * Validates System and Communications Protection controls (SC-7 through SC-28).
     *
     * Key controls:
     * - SC-7: Boundary Protection (VPC, Security Groups, WAF)
     * - SC-8: Transmission Confidentiality (TLS)
     * - SC-12: Cryptographic Key Establishment and Management
     * - SC-13: Cryptographic Protection
     * - SC-28: Protection of Information at Rest
     */
    private List<ComplianceRule> validateSystemCommunications(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // SC-7: Boundary Protection - VPC and security groups
        if (ctx.vpc.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-7",
                "Boundary protection required via VPC (NIST SC-7)",
                "ec2-instances-in-vpc",
                "Deploy resources within a VPC for boundary protection."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-7",
                "Boundary protection enabled via VPC (NIST SC-7)",
                "ec2-instances-in-vpc"
            ));
        }

        // SC-7: WAF for public-facing applications
        if (!config.isWafEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-7-WAF",
                "Web Application Firewall recommended for boundary protection (NIST SC-7)",
                "wafv2-logging-enabled",
                "Enable WAF for protection against web-based attacks."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-7-WAF",
                "Web Application Firewall enabled (NIST SC-7)",
                "wafv2-logging-enabled"
            ));
        }

        // SC-7(5): Deny by Default
        if (ctx.cfc.networkMode() == NetworkMode.PUBLIC) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-7(5)",
                "Default deny network policy required (NIST SC-7(5))",
                "vpc-default-security-group-closed",
                "Use private-with-nat network mode for default deny."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-7(5)",
                "Default deny network policy configured (NIST SC-7(5))",
                "vpc-default-security-group-closed"
            ));
        }

        // SC-8: Transmission Confidentiality - TLS required
        if (ctx.cert.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-8",
                "Transmission confidentiality required via TLS (NIST SC-8)",
                "elb-tls-https-listeners-only",
                "Configure TLS certificate for encrypted communications."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-8",
                "Transmission confidentiality enabled via TLS (NIST SC-8)",
                "elb-tls-https-listeners-only"
            ));
        }

        // SC-12: Cryptographic Key Management - customer-managed KMS key with rotation
        if (!config.isCloudWatchLogsKmsEncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-12",
                "Cryptographic key establishment and management requires a customer-managed KMS key (NIST SC-12)",
                "kms-cmk-not-scheduled-for-deletion",
                "Set cloudWatchLogsKmsEncryptionEnabled = true to provision a rotating customer-managed key."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-12",
                "Cryptographic key management via AWS KMS (NIST SC-12)",
                "kms-cmk-not-scheduled-for-deletion"
            ));
        }

        // SC-13: Cryptographic Protection - AES-256 encryption applied to data at rest
        if (!config.isEbsEncryptionEnabled() || !config.isEfsEncryptionAtRestEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-13",
                "Cryptographic protection requires AES-256 encryption of data at rest (NIST SC-13)",
                "encrypted-volumes",
                "Enable encryption at rest for all storage."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-13",
                "FIPS 140-2 validated cryptographic protection (NIST SC-13)",
                "encrypted-volumes"
            ));
        }

        // SC-28: Protection of Information at Rest
        if (!config.isEbsEncryptionEnabled() || !config.isEfsEncryptionAtRestEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-28",
                "Protection of information at rest required (NIST SC-28)",
                "encrypted-volumes",
                "Enable encryption at rest for all storage."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-28",
                "Information at rest protected via encryption (NIST SC-28)",
                "encrypted-volumes"
            ));
        }

        return rules;
    }

    // ========================================================================
    // SI Family - System and Information Integrity
    // ========================================================================

    /**
     * Validates System and Information Integrity controls (SI-2 through SI-7).
     *
     * Key controls:
     * - SI-2: Flaw Remediation
     * - SI-3: Malicious Code Protection
     * - SI-4: System Monitoring
     * - SI-7: Software, Firmware, and Information Integrity
     */
    private List<ComplianceRule> validateSystemIntegrity(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        // SI-2: Flaw Remediation - AWS Config with remediation
        if (config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SI-2",
                "Flaw remediation capability enabled via AWS Config (NIST SI-2)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SI-2",
                "Flaw remediation capability required (NIST SI-2)",
                "Enable AWS Config for automated flaw detection and remediation."
            ));
        }

        // SI-3: Malicious Code Protection - GuardDuty
        if (!config.isGuardDutyEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SI-3",
                "Malicious code protection required via GuardDuty (NIST SI-3)",
                "guardduty-enabled-centralized",
                "Enable GuardDuty for malware and threat detection."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SI-3",
                "Malicious code protection enabled via GuardDuty (NIST SI-3)",
                "guardduty-enabled-centralized"
            ));
        }

        // SI-4: System Monitoring - CloudWatch, GuardDuty, VPC Flow Logs
        if (!config.isSecurityMonitoringEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SI-4",
                "System monitoring required (NIST SI-4)",
                "Enable security monitoring via CloudWatch and GuardDuty."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SI-4",
                "System monitoring enabled via CloudWatch and GuardDuty (NIST SI-4)"
            ));
        }

        // SI-4(4): Inbound and Outbound Traffic Monitoring
        if (config.isFlowLogsEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SI-4(4)",
                "Traffic monitoring enabled via VPC Flow Logs (NIST SI-4(4))",
                "vpc-flow-logs-enabled"
            ));
        }

        // SI-7: Software and Information Integrity - CloudTrail file validation
        if (config.isCloudTrailEnabled()) {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SI-7",
                "Information integrity verification via CloudTrail (NIST SI-7)",
                "cloud-trail-log-file-validation-enabled"
            ));
        }

        return rules;
    }

    /**
     * Controls that {@link ComplianceMatrix} marks REQUIRED for FedRAMP and that the checks above
     * do not already cover -- this class predated the matrix and was never reconciled against it
     * until now, unlike {@link Soc2Rules} and {@link HipaaRules}. Mirrors the {@code
     * validateMatrixControls} pattern already used there.
     */
    private List<ComplianceRule> validateMatrixControls(
            SecurityProfileConfiguration config, RuntimeType runtime, boolean databaseProvisioned) {
        List<ComplianceRule> rules = new ArrayList<>();

        // AU-9: CloudWatch Logs may contain sensitive federal data in application log output --
        // distinct from the general S3-encryption check already covering the other half of AU-9.
        if (!config.isCloudWatchLogsKmsEncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-9-LogEncryption",
                "CloudWatch log groups must be encrypted with a customer-managed KMS key (NIST AU-9)",
                "Enable cloudWatchLogsKmsEncryptionEnabled."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-9-LogEncryption",
                "CloudWatch log groups encrypted with a customer-managed KMS key (NIST AU-9)"
            ));
        }

        // AU-9: audit trail immutability.
        if (!config.isS3ObjectLockEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-AU-9-AuditLogImmutability",
                "S3 Object Lock required so audit logs cannot be altered or deleted (NIST AU-9)",
                "Enable S3 Object Lock on the audit-log buckets."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-AU-9-AuditLogImmutability",
                "S3 Object Lock enabled on audit-log buckets (NIST AU-9)"
            ));
        }

        // SC-8(1): HTTPS-only mode -- distinct from the SC-8 cert-presence check above, which
        // confirms TLS is available but not that the HTTP listener is actually disabled.
        if (!config.isHttpsStrictEnabled()) {
            rules.add(ComplianceRule.fail(
                "FEDRAMP-SC-8(1)-HTTPSStrict",
                "HTTP listener must be disabled when SSL is enabled (NIST SC-8(1))",
                "Set httpsStrictEnabled = true to disable the port-80 listener."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "FEDRAMP-SC-8(1)-HTTPSStrict",
                "HTTP listener disabled, HTTPS-only mode enforced (NIST SC-8(1))"
            ));
        }

        // AC-3: EC2 instance metadata is a documented credential-theft vector; Fargate has no
        // instance metadata service to protect.
        if (runtime == RuntimeType.EC2) {
            if (!config.isImdsv2Required()) {
                rules.add(ComplianceRule.fail(
                    "FEDRAMP-AC-3-IMDSv2",
                    "EC2 instances must require IMDSv2 (NIST AC-3)",
                    "Set imdsv2Required=true."
                ));
            } else {
                rules.add(ComplianceRule.pass(
                    "FEDRAMP-AC-3-IMDSv2",
                    "EC2 instances require IMDSv2 tokens (NIST AC-3)"
                ));
            }
        }

        // CP-10: database-specific availability and protection -- the existing CP-10 check only
        // covers compute Multi-AZ, not RDS specifically.
        if (databaseProvisioned) {
            if (!config.isRdsDatabaseMultiAzEnabled()) {
                rules.add(ComplianceRule.fail(
                    "FEDRAMP-CP-10-DatabaseMultiAZ",
                    "RDS Multi-AZ required for database availability (NIST CP-10)",
                    "Enable Multi-AZ on the RDS instance."
                ));
            } else {
                rules.add(ComplianceRule.pass(
                    "FEDRAMP-CP-10-DatabaseMultiAZ",
                    "RDS Multi-AZ enabled for database availability (NIST CP-10)"
                ));
            }
            if (!config.isRdsDeletionProtectionEnabled()) {
                rules.add(ComplianceRule.fail(
                    "FEDRAMP-CP-9-DatabaseDeletionProtection",
                    "RDS deletion protection required to prevent accidental data loss (NIST CP-9)",
                    "Enable RDS deletion protection."
                ));
            } else {
                rules.add(ComplianceRule.pass(
                    "FEDRAMP-CP-9-DatabaseDeletionProtection",
                    "RDS deletion protection enabled (NIST CP-9)"
                ));
            }
        }

        return rules;
    }

    /**
     * Controls checked across every {@code validate*} method above -- see {@link
     * FrameworkRules#claimedControls}. Controls the matrix marks REQUIRED for FedRAMP but left off
     * this list belong to always-load cross-framework classes instead (KMS_KEY_ROTATION,
     * SECRETS_MANAGER, SECRETS_ROTATION, DATABASE_PITR, DATABASE_LOGGING, CONTAINER_SECURITY,
     * API_SECURITY, CDN_SECURITY, INSTANCE_METADATA_SECURITY, ROOT_ACCOUNT_PROTECTION,
     * CREDENTIAL_ROTATION, SNS_KMS_ENCRYPTION, SECURITY_HUB, VULNERABILITY_SCANNING -- see
     * KeyManagementRules, DatabaseSecurityRules, IamSecurityRules, ComputeSecurityRules,
     * MessagingSecurityRules and similar), except LAMBDA_SECURITY and DATABASE_ACCESS_CONTROL,
     * which are genuine gaps: no class anywhere checks them.
     */
    @Override
    public Set<String> claimedControls() {
        return Set.of(
            "ACCESS_CONTROL", "NETWORK_FLOW_LOGS", "AUTHENTICATION", "NETWORK_SEGMENTATION",
            "ENCRYPTION_IN_TRANSIT", "AUDIT_LOGGING", "THREAT_DETECTION", "ENCRYPTION_AT_REST",
            "LOG_RETENTION", "VULNERABILITY_MANAGEMENT", "SECURITY_MONITORING", "CHANGE_MANAGEMENT",
            "BACKUP_RECOVERY", "HIGH_AVAILABILITY", "WAF_PROTECTION",
            "CLOUDWATCH_LOGS_KMS_ENCRYPTION", "S3_OBJECT_LOCK", "HTTPS_STRICT", "EC2_IMDSV2",
            "DATABASE_MULTI_AZ", "DELETION_PROTECTION"
        );
    }

    // ========================================================================
    // Helper Methods
    // ========================================================================

    /**
     * Check if log retention meets FedRAMP requirement (3 years).
     * NIST AU-11: Audit record retention.
     */
    private boolean isRetentionSufficient(RetentionDays retention) {
        // FedRAMP requires 3 years (1095 days)
        return retention == RetentionDays.THREE_YEARS ||
               retention == RetentionDays.FIVE_YEARS ||
               retention == RetentionDays.SIX_YEARS ||
               retention == RetentionDays.SEVEN_YEARS ||
               retention == RetentionDays.EIGHT_YEARS ||
               retention == RetentionDays.NINE_YEARS ||
               retention == RetentionDays.TEN_YEARS ||
               retention == RetentionDays.INFINITE;
    }

    /**
     * Generate FedRAMP Moderate compliance report.
     */
    public String generateComplianceReport(SystemContext ctx) {
        StringBuilder report = new StringBuilder();
        report.append("\n=== FedRAMP Moderate Compliance Report ===\n\n");

        var config = ctx.securityProfileConfig.get().orElseThrow(
            () -> new IllegalStateException("SecurityProfileConfiguration not set")
        );

        report.append("Security Profile: ").append(ctx.security).append("\n");
        report.append("Environment: ").append(ctx.cfc.env()).append("\n\n");

        report.append("Control Family Status:\n");
        report.append("─".repeat(50)).append("\n");

        // AC - Access Control
        report.append("AC - Access Control:\n");
        report.append("  ✓ AC-2 (Account Management): ").append(ctx.iamProfile != null ? "CONFIGURED" : "NOT CONFIGURED").append("\n");
        report.append("  ✓ AC-3 (Access Enforcement): ").append(ctx.albSg.get().isPresent() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ AC-4 (Information Flow): ").append(config.isFlowLogsEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ AC-17 (Remote Access): ").append(ctx.cfc.networkMode() != NetworkMode.PUBLIC ? "CONTROLLED" : "UNRESTRICTED").append("\n");
        report.append("\n");

        // AU - Audit and Accountability
        report.append("AU - Audit and Accountability:\n");
        report.append("  ✓ AU-2 (Event Logging): ").append(config.isCloudTrailEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ AU-6 (Audit Review): ").append(config.isGuardDutyEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ AU-9 (Audit Protection): ").append(config.isS3EncryptionEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ AU-11 (Retention): ").append(config.getLogRetentionDays().toString());
        if (!isRetentionSufficient(config.getLogRetentionDays())) {
            report.append(" [WARNING: Less than 3 years]");
        }
        report.append("\n\n");

        // CA - Continuous Monitoring
        report.append("CA - Assessment & Monitoring:\n");
        report.append("  ✓ CA-7 (Continuous Monitoring): ").append(config.isAwsConfigEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // CM - Configuration Management
        report.append("CM - Configuration Management:\n");
        report.append("  ✓ CM-2 (Baseline Configuration): ENABLED (Infrastructure as Code)\n");
        report.append("  ✓ CM-3 (Change Control): ").append(config.isCloudTrailEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ CM-6 (Config Settings): ").append(config.isAwsConfigEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // CP - Contingency Planning
        report.append("CP - Contingency Planning:\n");
        report.append("  ✓ CP-6 (Alternate Storage): ").append(config.isCrossRegionBackupEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ CP-9 (System Backup): ").append(config.isAutomatedBackupEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ CP-10 (System Recovery): ").append(config.isMultiAzEnforced() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // IA - Identification and Authentication
        report.append("IA - Identification & Authentication:\n");
        report.append("  ✓ IA-2 (Authentication): ").append(ctx.cfc.authMode() != AuthMode.NONE ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ IA-2(1) (MFA): ").append(Boolean.TRUE.equals(ctx.cfc.cognitoMfaEnabled()) ? "ENABLED" : "CHECK MANUALLY").append("\n");
        report.append("  ✓ IA-5 (Password Policy): ").append(config.getMinimumPasswordLength() >= FEDRAMP_MIN_PASSWORD_LENGTH ? "ENFORCED VIA IAM (" + config.getMinimumPasswordLength() + " chars)" : "BELOW MINIMUM (" + config.getMinimumPasswordLength() + " chars)").append("\n");
        report.append("\n");

        // IR - Incident Response
        report.append("IR - Incident Response:\n");
        report.append("  ✓ IR-4 (Incident Handling): ").append(config.isGuardDutyEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ IR-5 (Incident Monitoring): ").append(config.isSecurityMonitoringEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // MP - Media Protection
        report.append("MP - Media Protection:\n");
        report.append("  ✓ MP-4 (Storage Encryption): ").append(config.isEbsEncryptionEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ MP-5 (Transport Encryption): ").append(ctx.cert.get().isPresent() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // RA - Risk Assessment
        report.append("RA - Risk Assessment:\n");
        report.append("  ✓ RA-5 (Vulnerability Monitoring): ").append(config.isAwsConfigEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // SC - System and Communications Protection
        report.append("SC - System & Communications Protection:\n");
        report.append("  ✓ SC-7 (Boundary Protection): ").append(ctx.vpc.get().isPresent() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ SC-7-WAF (Web App Firewall): ").append(config.isWafEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ SC-8 (Transmission Security): ").append(ctx.cert.get().isPresent() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ SC-28 (Encryption at Rest): ").append(config.isEbsEncryptionEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        // SI - System and Information Integrity
        report.append("SI - System & Information Integrity:\n");
        report.append("  ✓ SI-2 (Flaw Remediation): ").append(config.isAwsConfigEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ SI-3 (Malware Protection): ").append(config.isGuardDutyEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ SI-4 (System Monitoring): ").append(config.isSecurityMonitoringEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("\n");

        report.append("═".repeat(50)).append("\n");
        report.append("Note: FedRAMP requires 3PAO assessment for full authorization.\n");
        report.append("This report covers automated infrastructure controls only.\n");
        report.append("═".repeat(50)).append("\n\n");

        appendAdvisorySection(report, ctx, config);

        return report.toString();
    }

    /**
     * Recommendations for controls that are ADVISORY-tier (not blocking) and currently off.
     * Runs the same checks {@link #install} does, so this reflects live findings, not a
     * separate hand-maintained list.
     */
    private void appendAdvisorySection(StringBuilder report, SystemContext ctx, SecurityProfileConfiguration config) {
        List<ComplianceRule> rules = new ArrayList<>();
        rules.addAll(validateAccessControl(ctx));
        rules.addAll(validateAuditAccountability(ctx));
        rules.addAll(validateContinuousMonitoring(ctx));
        rules.addAll(validateConfigurationManagement(ctx));
        rules.addAll(validateContingencyPlanning(ctx));
        rules.addAll(validateIdentificationAuthentication(ctx));
        rules.addAll(validateIncidentResponse(ctx));
        rules.addAll(validateMediaProtection(ctx));
        rules.addAll(validateRiskAssessment(ctx));
        rules.addAll(validateSystemCommunications(ctx));
        rules.addAll(validateSystemIntegrity(ctx));
        rules.addAll(validateMatrixControls(config, ctx.runtime, ctx.dbConnection.get().isPresent()));

        List<ComplianceRule> advisories = rules.stream().filter(ComplianceRule::isAdvisory).toList();
        if (advisories.isEmpty()) {
            return;
        }
        report.append("Recommendations (advisory, non-blocking):\n");
        for (ComplianceRule rule : advisories) {
            report.append("  - ").append(rule.ruleId()).append(": ").append(rule.description()).append("\n");
            rule.recommendation().ifPresent(r -> report.append("      ").append(r).append("\n"));
        }
        report.append("\n");
    }
}