PciDssRules.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.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;

/**
 * PCI-DSS compliance validation rules.
 *
 * These rules enforce PCI-DSS requirements for environments processing cardholder data.
 *
 * PCI-DSS Requirements Coverage:
 * - Requirement 1: Install and maintain a firewall configuration
 * - Requirement 2: Do not use vendor-supplied defaults
 * - Requirement 3: Protect stored cardholder data
 * - Requirement 4: Encrypt transmission of cardholder data
 * - Requirement 6: Develop and maintain secure systems
 * - Requirement 7: Restrict access to cardholder data by business need to know
 * - Requirement 8: Identify and authenticate access to system components
 * - Requirement 10: Track and monitor all access to network resources
 * - Requirement 11: Regularly test security systems and processes
 */
@ComplianceFramework(
    value = "PCI-DSS",
    priority = 20,
    displayName = "PCI DSS v4.0.1",
    description = "Validates PCI DSS v4.0.1 requirements for cardholder data protection"
)
public class PciDssRules implements FrameworkRules<SystemContext> {
    private static final Logger LOG = Logger.getLogger(PciDssRules.class.getName());

    /** Controls that still block STAGING synthesis: authentication, network isolation,
     *  SSL/TLS in transit, encryption at rest, and audit logging -- cardholder data may exist
     *  in STAGING, so these can't be downgraded to a non-blocking finding there.
     *  Everything else in STAGING is a visible, non-blocking finding. */
    private static final Set<String> STAGING_BLOCKING_RULES = Set.of(
        "PCI-DSS-Req-8.2-Auth", "PCI-DSS-Req-1.3-Network", "PCI-DSS-Req-4.1-SSL", "PCI-DSS-Req-4.1-TLS",
        "PCI-DSS-Req-4.1-HTTPSStrict",
        "PCI-DSS-Req-3.4-EBS", "PCI-DSS-Req-3.4-EFS", "PCI-DSS-Req-3.4-S3", "PCI-DSS-Req-3.4-LogEncryption",
        "PCI-DSS-Req-10.2-CloudTrail", "PCI-DSS-Req-10.3-FlowLogs", "PCI-DSS-Req-10.5-ALB",
        "PCI-DSS-Req-10.7-AuditLogImmutability", "PCI-DSS-Req-8.3-MFA", "PCI-DSS-Req-4.1-EFS-Transit",
        "PCI-DSS-Req-8.3.6-Password", "PCI-DSS-Req-10.7-Retention"
    );

    // PCI DSS v4.0 Req 8.3.6: Minimum 12 character passwords (increased from 7 in v3.2.1)
    private static final int MIN_PASSWORD_LENGTH = 12;

    /**
     * Check if log retention period meets PCI-DSS requirement (at least 1 year).
     * PCI-DSS Requirement 10.7: Retain audit trail history for at least one year.
     */
    private boolean isRetentionSufficient(RetentionDays retention) {
        // PCI-DSS requires at least 1 year (365 days)
        // Acceptable values: ONE_YEAR (365), THIRTEEN_MONTHS (400), EIGHTEEN_MONTHS (545), and higher
        return retention == RetentionDays.ONE_YEAR ||
               retention == RetentionDays.THIRTEEN_MONTHS ||
               retention == RetentionDays.EIGHTEEN_MONTHS ||
               retention == RetentionDays.TWO_YEARS ||
               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;
    }

    /**
     * Install PCI-DSS compliance validation rules.
     * PCI-DSS applies to environments processing cardholder data.
     * Only enforced when security profile is PRODUCTION.
     *
     * @since 3.0.0
     */
    @Override
    public void install(SystemContext ctx) {
        // PCI-DSS enforcement for production and staging (cardholder data environments may exist in both)
        if (ctx.security != SecurityProfile.PRODUCTION && ctx.security != SecurityProfile.STAGING) {
            LOG.info("PCI-DSS validation rules enforced for PRODUCTION and STAGING profiles only");
            return;
        }

        LOG.info("Installing PCI-DSS compliance validation rules");

        // 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<>();

            // Requirement 1: Network Segmentation & Firewall
            rules.addAll(validateNetworkSecurity(ctx));

            // Requirement 2: Vendor Defaults
            rules.addAll(validateVendorDefaults(ctx));

            // Requirement 3 & 4: Encryption
            rules.addAll(validateEncryption(ctx));

            // Requirement 6: Web Application Firewall (PCI-DSS 6.6)
            rules.addAll(validateWebApplicationSecurity(ctx));

            // Requirement 7 & 8: Access Control
            rules.addAll(validateAccessControl(ctx));

            // Requirement 10: Audit Logging
            rules.addAll(validateAuditLogging(ctx));

            // Requirement 11: Security Monitoring
            rules.addAll(validateSecurityMonitoring(ctx));

            // Matrix-required controls not covered above
            rules.addAll(validateMatrixControls(ctx));

            // Advisory findings never block synthesis, logged regardless of complianceMode so they
            // show up in the compliance report and the matrix runner's log capture.
            List<ComplianceRule> advisoryRules = rules.stream().filter(ComplianceRule::isAdvisory).toList();
            if (!advisoryRules.isEmpty()) {
                LOG.info("PCI-DSS validation found " + advisoryRules.size() + " advisory recommendations (non-blocking):");
                advisoryRules.forEach(r -> LOG.info("  [ADVISORY] " + r.ruleId() + ": " + r.description()));
            }

            return ComplianceEnforcement.resolve(
                "PCI-DSS", rules, complianceMode, ctx.security, STAGING_BLOCKING_RULES, LOG);
        });
    }

    /**
     * PCI-DSS Requirement 1: Install and maintain a firewall configuration.
     * Validates network segmentation and firewall rules.
     */
    private List<ComplianceRule> validateNetworkSecurity(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        // Requirement 1.2.1: Network segmentation
        if (ctx.vpc.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-1.2.1-VPC",
                "VPC required for network segmentation",
                "PCI-DSS Req 1.2.1: VPC required for network segmentation"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-1.2.1-VPC",
                "VPC network segmentation enabled"
            ));
        }

        // Requirement 1.3: Prohibit direct public access
        if (ctx.cfc.networkMode() == NetworkMode.PUBLIC) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-1.3-Network",
                "Private network mode required for cardholder data environment",
                "PCI-DSS Req 1.3: Public network mode prohibited for cardholder data environment. " +
                "Use 'private-with-nat' for production systems processing card data."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-1.3-Network",
                "Private network mode configured"
            ));
        }

        // Requirement 1.3.1: Security groups must restrict traffic
        if (ctx.albSg.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-1.3.1-ALB-SG",
                "ALB security group required for traffic restrictions",
                "PCI-DSS Req 1.3.1: ALB security group required for traffic restrictions"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-1.3.1-ALB-SG",
                "ALB security group configured"
            ));
        }

        if (ctx.efsSg.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-1.3.1-EFS-SG",
                "EFS security group required for storage access restrictions",
                "PCI-DSS Req 1.3.1: EFS security group required for storage access restrictions"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-1.3.1-EFS-SG",
                "EFS security group configured"
            ));
        }

        return rules;
    }

    /**
     * PCI-DSS Requirement 3 & 4: Protect stored and transmitted cardholder data.
     * Validates encryption settings.
     */
    private List<ComplianceRule> validateEncryption(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

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

        // Requirement 3.4: Encryption of cardholder data at rest
        if (!config.isEbsEncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-3.4-EBS",
                "EBS encryption must be enabled for cardholder data at rest",
                "EbsEncryptionRule",
                "PCI-DSS Req 3.4: EBS encryption must be enabled for cardholder data at rest"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-3.4-EBS",
                "EBS encryption enabled",
                "EbsEncryptionRule"
            ));
        }

        if (!config.isEfsEncryptionAtRestEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-3.4-EFS",
                "EFS encryption at rest must be enabled for cardholder data storage",
                "PCI-DSS Req 3.4: EFS encryption at rest must be enabled for cardholder data storage"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-3.4-EFS",
                "EFS encryption at rest enabled"
            ));
        }

        if (!config.isS3EncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-3.4-S3",
                "S3 encryption must be enabled for cardholder data backups",
                "S3BucketEncryptionRule",
                "PCI-DSS Req 3.4: S3 encryption must be enabled for cardholder data backups"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-3.4-S3",
                "S3 encryption enabled",
                "S3BucketEncryptionRule"
            ));
        }

        // Requirement 4.1: Strong cryptography for data transmission
        if (!config.isEfsEncryptionInTransitEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-4.1-EFS-Transit",
                "EFS encryption in transit (TLS) must be enabled",
                "PCI-DSS Req 4.1: EFS encryption in transit (TLS) must be enabled"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-4.1-EFS-Transit",
                "EFS encryption in transit enabled"
            ));
        }

        // Requirement 4.1: SSL/TLS must be enabled for encrypted transmission
        if (!ctx.cfc.enableSsl()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-4.1-SSL",
                "SSL/TLS must be enabled for encrypted transmission of cardholder data",
                "PCI-DSS Req 4.1: enableSsl must be true for production PCI-DSS compliance"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-4.1-SSL",
                "SSL/TLS enabled"
            ));
        }

        // Validate TLS certificate is configured
        if (ctx.cert.get().isEmpty()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-4.1-TLS",
                "TLS certificate required for encrypted transmission of cardholder data",
                "PCI-DSS Req 4.1: TLS certificate required for encrypted transmission of cardholder data"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-4.1-TLS",
                "TLS certificate configured"
            ));
        }

        return rules;
    }

    /**
     * PCI-DSS Requirement 6.6: Protect public-facing web applications.
     * Either WAF or application-layer security review required.
     */
    private List<ComplianceRule> validateWebApplicationSecurity(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

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

        // Requirement 6.6: WAF or application security review
        // WAF is REQUIRED for PRODUCTION environments processing cardholder data
        if (!config.isWafEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-6.6-WAF",
                "Web Application Firewall (WAF) REQUIRED for PCI-DSS compliance in PRODUCTION",
                "WafEnabled",
                "PCI-DSS Req 6.6: Protect all public-facing web applications from known attacks by " +
                "installing a web application firewall. WAF is required for PRODUCTION environments " +
                "processing cardholder data. Set wafEnabled = true in deployment context."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-6.6-WAF",
                "WAF protection enabled for PCI-DSS compliance",
                "WafEnabled"
            ));
        }

        return rules;
    }

    /**
     * PCI DSS Requirement 7 & 8: Restrict access and authenticate users.
     * Validates access control and authentication configuration.
     */
    private List<ComplianceRule> validateAccessControl(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

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

        // Req 8.3.6: Minimum 12 character passwords
        int passwordLength = config.getMinimumPasswordLength();
        if (passwordLength < MIN_PASSWORD_LENGTH) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-8.3.6-Password",
                "Minimum password length must be " + MIN_PASSWORD_LENGTH + " characters (PCI DSS v4.0 Req 8.3.6)",
                "IAMPasswordPolicyRule",
                "Current: " + passwordLength + " characters. Update SecurityProfileConfiguration.getMinimumPasswordLength()."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-8.3.6-Password",
                "Password length requirement met (" + passwordLength + " characters)",
                "IAMPasswordPolicyRule"
            ));
        }

        // Requirement 7.1: Limit access by business need to know
        // IAM validation is handled by IAMRules, but we verify it's configured
        if (ctx.iamProfile == null) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-7.1-IAM",
                "IAM profile must be configured for least privilege access control",
                "IAMPasswordPolicyRule",
                "PCI-DSS Req 7.1: IAM profile must be configured for least privilege access control"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-7.1-IAM",
                "IAM profile configured for access control",
                "IAMPasswordPolicyRule"
            ));
        }

        // Requirement 8.2: Multi-factor authentication
        AuthMode authMode = ctx.cfc.authMode();
        if (authMode == AuthMode.NONE) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-8.2-Auth",
                "Authentication must be enabled for production environments",
                "PCI-DSS Req 8.2: Authentication must be enabled for production environments. " +
                "Configure authMode = 'alb-oidc', 'jenkins-oidc', or 'application-oidc' with MFA-enabled identity provider. " +
                "Users must use multi-factor authentication to access cardholder data."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-8.2-Auth",
                "Authentication enabled"
            ));
        }

        // Requirement 8.3: Strong authentication with MFA
        if (authMode == AuthMode.ALB_OIDC || authMode == AuthMode.APPLICATION_OIDC) {
            // Check if using Cognito with MFA (compliant) or SSO (requires ssoInstanceArn)
            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(
                    "PCI-DSS-Req-8.3-MFA",
                    "Multi-factor authentication required for OIDC mode",
                    "PCI-DSS Req 8.3: Multi-factor authentication required for OIDC mode. " +
                    "Either: (1) Enable Cognito MFA: cognitoAutoProvision = true, cognitoMfaEnabled = true " +
                    "OR (2) Configure AWS IAM Identity Center: provide ssoInstanceArn with MFA enforcement."
                ));
            } else {
                rules.add(ComplianceRule.pass(
                    "PCI-DSS-Req-8.3-MFA",
                    "Multi-factor authentication configured"
                ));
            }
        }

        return rules;
    }

    /**
     * PCI-DSS Requirement 10: Track and monitor all access.
     * Validates audit logging configuration.
     */
    private List<ComplianceRule> validateAuditLogging(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

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

        // Requirement 10.2: Automated audit trails
        if (!config.isCloudTrailEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-10.2-CloudTrail",
                "CloudTrail must be enabled for API activity audit logging",
                "CloudTrailEnabledRule",
                "PCI-DSS Req 10.2: CloudTrail must be enabled for API activity audit logging"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-10.2-CloudTrail",
                "CloudTrail enabled for audit logging",
                "CloudTrailEnabledRule"
            ));
        }

        // Requirement 10.3: Record specific events
        if (!config.isFlowLogsEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-10.3-FlowLogs",
                "VPC Flow Logs must be enabled for network activity tracking",
                "PCI-DSS Req 10.3: VPC Flow Logs must be enabled for network activity tracking"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-10.3-FlowLogs",
                "VPC Flow Logs enabled"
            ));
        }

        // Requirement 10.5: Secure audit trails
        if (!config.isAlbAccessLoggingEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-10.5-ALB",
                "ALB access logging must be enabled for web traffic audit trails",
                "PCI-DSS Req 10.5: ALB access logging must be enabled for web traffic audit trails"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-10.5-ALB",
                "ALB access logging enabled"
            ));
        }

        // Requirement 10.7: Retain audit trail for at least one year
        var retentionDays = config.getLogRetentionDays();
        if (!isRetentionSufficient(retentionDays)) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-10.7-Retention",
                "Log retention must be at least ONE_YEAR (365 days)",
                "PCI-DSS Req 10.7: Log retention must be at least ONE_YEAR (365 days). Current: " +
                retentionDays.toString()
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-10.7-Retention",
                "Log retention configured for at least one year"
            ));
        }

        return rules;
    }

    /**
     * PCI-DSS Requirement 11: Regularly test security systems.
     * Validates security monitoring and intrusion detection.
     */
    private List<ComplianceRule> validateSecurityMonitoring(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

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

        // Requirement 11.4: Intrusion detection/prevention systems
        if (!config.isGuardDutyEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-11.4-GuardDuty",
                "GuardDuty (threat detection) must be enabled for production",
                "GuardDutyEnabled",
                "PCI-DSS Req 11.4: GuardDuty (threat detection) must be enabled for production"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-11.4-GuardDuty",
                "GuardDuty threat detection enabled",
                "GuardDutyEnabled"
            ));
        }

        // Requirement 10 & 11: Track and monitor all access to network resources
        // VPC Flow Logs are required for network traffic monitoring and audit trail
        if (!config.isFlowLogsEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-10.11-FlowLogs",
                "VPC Flow Logs required for network monitoring (PCI-DSS Req 10 & 11)",
                "FlowLogsEnabled",
                "PCI-DSS Requirement 10 (logging and monitoring) and Requirement 11 (security testing) " +
                "require tracking and monitoring all access to network resources and cardholder data. " +
                "Enable VPC Flow Logs to capture network traffic for audit trail and anomaly detection. " +
                "Set flowLogsEnabled = true in deployment context."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-10.11-FlowLogs",
                "VPC Flow Logs enabled for network monitoring",
                "FlowLogsEnabled"
            ));
        }

        // Requirement 11.5: File integrity monitoring
        if (!config.isSecurityMonitoringEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-11.5-Monitoring",
                "Security monitoring must be enabled for alerting",
                "PCI-DSS Req 11.5: Security monitoring must be enabled for alerting"
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-11.5-Monitoring",
                "Security monitoring enabled"
            ));
        }

        // Requirement 11.6: Change detection (AWS Config)
        if (!config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-11.6-Config",
                "AWS Config recommended for continuous compliance monitoring",
                "PCI-DSS Req 11.6: AWS Config recommended for continuous compliance monitoring. " +
                "Set awsConfigEnabled = true in deployment context."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-11.6-Config",
                "AWS Config enabled for compliance monitoring"
            ));
        }

        return rules;
    }

    /**
     * PCI-DSS Requirement 2: Do not use vendor-supplied defaults.
     * Validates that default configurations have been changed.
     *
     * For PRODUCTION security profile, these operational controls are assumed to be
     * implemented as part of the organization's security program and are auto-approved.
     */
    private List<ComplianceRule> validateVendorDefaults(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

        // For PRODUCTION and STAGING profiles, assume operational controls are in place
        // This matches the infrastructure-centric approach of SOC2 rules
        boolean isProduction = ctx.security == SecurityProfile.PRODUCTION || ctx.security == SecurityProfile.STAGING;

        // Requirement 2.1: Default passwords must be changed
        // PRODUCTION profile requires strong IAM policies and authentication
        if (isProduction || getBooleanSetting(ctx, "customConfigurationApplied", false)) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-2.1-CustomConfig",
                "Custom configuration applied - vendor defaults changed (PRODUCTION profile)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-2.1-CustomConfig",
                "Custom configuration required - vendor defaults must be changed",
                "Verify default passwords, SNMP strings, and credentials have been changed. " +
                "PCI-DSS Req 2.1: Change all vendor-supplied defaults before deploying. " +
                "Set customConfigurationApplied = true after verification or use PRODUCTION security profile."
            ));
        }

        // Requirement 2.2: Configuration standards
        // PRODUCTION profile applies hardened security configurations
        if (isProduction || getBooleanSetting(ctx, "securityHardeningApplied", false)) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-2.2-Hardening",
                "Security hardening standards applied (PRODUCTION profile)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-2.2-Hardening",
                "Security hardening configuration standards required",
                "Apply CIS benchmarks or NIST hardening guidelines. " +
                "PCI-DSS Req 2.2: Develop configuration standards for all system components. " +
                "Set securityHardeningApplied = true after implementing hardening or use PRODUCTION security profile."
            ));
        }

        // Requirement 2.2.2: Enable only necessary services
        // PRODUCTION profile enforces minimal service exposure via security groups
        if (isProduction || getBooleanSetting(ctx, "unnecessaryServicesDisabled", false)) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-2.2.2-Services",
                "Unnecessary services disabled (PRODUCTION profile enforces minimal exposure)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-2.2.2-Services",
                "Disable unnecessary services and protocols",
                "PCI-DSS Req 2.2.2: Enable only necessary services, protocols, and daemons. " +
                "Remove or disable FTP, telnet, and other insecure services. " +
                "Set unnecessaryServicesDisabled = true after verification or use PRODUCTION security profile."
            ));
        }

        // Requirement 2.2.5: Remove unnecessary functionality
        // PRODUCTION profile assumes minimal images are used for production deployments
        if (isProduction || getBooleanSetting(ctx, "minimalBaseImageUsed", false)) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-2.2.5-MinimalImage",
                "Minimal base image in use (PRODUCTION profile)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-2.2.5-MinimalImage",
                "Use minimal base images without unnecessary functionality",
                "PCI-DSS Req 2.2.5: Remove unnecessary functionality (scripts, utilities, etc). " +
                "Use minimal container images or hardened AMIs. " +
                "Set minimalBaseImageUsed = true when using minimal images or use PRODUCTION security profile."
            ));
        }

        // Requirement 2.3: Encrypt non-console administrative access
        // Already covered by TLS certificate validation in validateEncryption()
        if (ctx.cert.get().isPresent()) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-2.3-EncryptAdmin",
                "Administrative access encrypted (HTTPS/TLS)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-2.3-EncryptAdmin",
                "Encrypt all non-console administrative access",
                "PCI-DSS Req 2.3: Use SSH, VPN, TLS for remote admin access"
            ));
        }

        // Requirement 2.4: Maintain inventory of system components
        // AWS Config provides continuous inventory for PRODUCTION deployments
        var config = ctx.securityProfileConfig.get().orElse(null);
        if ((config != null && config.isAwsConfigEnabled()) || getBooleanSetting(ctx, "systemInventoryMaintained", false)) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-2.4-Inventory",
                "System inventory maintained (AWS Config enabled)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-2.4-Inventory",
                "Maintain inventory of system components in scope for PCI-DSS",
                "PCI-DSS Req 2.4: Keep inventory of all systems in cardholder data environment. " +
                "Use AWS Systems Manager Inventory or Config. " +
                "Set systemInventoryMaintained = true when inventory system is active or enable AWS Config."
            ));
        }

        return rules;
    }

    /**
     * Helper method to safely get boolean settings from deployment context.
     */
    private static 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;
        }
    }

    /**
     * Controls that {@link ComplianceMatrix} marks REQUIRED for PCI-DSS and that the checks above
     * do not already cover. VULNERABILITY_SCANNING, BACKUP_RECOVERY and HIGH_AVAILABILITY are
     * REQUIRED too, but are already covered by always-load cross-framework classes (AdvancedMonitoringRules/
     * ThreatProtectionRules, DatabaseSecurityRules/IncidentResponseRules, ElbSecurityRules), so they're
     * not duplicated here. LAMBDA_SECURITY and DATABASE_ACCESS_CONTROL still have no check anywhere
     * in the codebase -- see the compliance backlog for tracking those as their own fix.
     */
    private List<ComplianceRule> validateMatrixControls(SystemContext ctx) {
        List<ComplianceRule> rules = new ArrayList<>();

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

        // Req 4.1: HTTPS-only mode -- distinct from "SSL/TLS enabled" (validateEncryption already
        // checks that): this verifies the HTTP listener is actually disabled, not just that HTTPS
        // is also available alongside it.
        if (!config.isHttpsStrictEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-4.1-HTTPSStrict",
                "HTTP listener must be disabled when SSL is enabled (PCI-DSS Req 4.1)",
                "Set httpsStrictEnabled = true to disable the port-80 listener."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-4.1-HTTPSStrict",
                "HTTP listener disabled, HTTPS-only mode enforced (PCI-DSS Req 4.1)"
            ));
        }

        // Req 3.4: CloudWatch Logs may contain cardholder data in application log output.
        if (!config.isCloudWatchLogsKmsEncryptionEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-3.4-LogEncryption",
                "CloudWatch log groups must be encrypted with a customer-managed KMS key (PCI-DSS Req 3.4)",
                "Enable cloudWatchLogsKmsEncryptionEnabled."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-3.4-LogEncryption",
                "CloudWatch log groups encrypted with a customer-managed KMS key (PCI-DSS Req 3.4)"
            ));
        }

        // Req 10.7: audit logs must be tamper-evident.
        if (!config.isS3ObjectLockEnabled()) {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-10.7-AuditLogImmutability",
                "S3 Object Lock required so audit logs cannot be altered or deleted (PCI-DSS Req 10.7)",
                "Enable S3 Object Lock on the audit-log buckets."
            ));
        } else {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-10.7-AuditLogImmutability",
                "S3 Object Lock enabled on audit-log buckets (PCI-DSS Req 10.7)"
            ));
        }

        // Req 6.4.5: change control -- CloudTrail plus AWS Config together give a record of every
        // change and detect drift from the deployed baseline.
        if (config.isCloudTrailEnabled() && config.isAwsConfigEnabled()) {
            rules.add(ComplianceRule.pass(
                "PCI-DSS-Req-6.4.5-ChangeManagement",
                "Change tracking enabled via CloudTrail and AWS Config (PCI-DSS Req 6.4.5)"
            ));
        } else {
            rules.add(ComplianceRule.fail(
                "PCI-DSS-Req-6.4.5-ChangeManagement",
                "Change control tracking required (PCI-DSS Req 6.4.5)",
                "Enable both CloudTrail and AWS Config to track and detect infrastructure changes."
            ));
        }

        // EC2_IMDSV2 is ADVISORY for PCI-DSS (defense in depth, not a PCI-DSS requirement itself),
        // unlike HIPAA/SOC2/FedRAMP where it's REQUIRED; only checked here for EC2 -- Fargate has
        // no instance metadata service to protect.
        if (ctx.runtime == RuntimeType.EC2) {
            if (config.isImdsv2Required()) {
                rules.add(ComplianceRule.pass(
                    "PCI-DSS-Req-2.2-IMDSv2",
                    "EC2 instances require IMDSv2 tokens (PCI-DSS Req 2.2 defense in depth)"
                ));
            } else {
                rules.add(ComplianceRule.advisory(
                    "PCI-DSS-Req-2.2-IMDSv2",
                    "IMDSv2 is advisory for PCI-DSS (recommended defense in depth, not required)",
                    "Set imdsv2Required = true to block the legacy IMDSv1 endpoint."
                ));
            }
        }

        return rules;
    }

    /**
     * Controls checked across every {@code validate*} method above -- see {@link
     * com.cloudforge.core.interfaces.FrameworkRules#claimedControls}. Controls the matrix marks
     * REQUIRED for PCI-DSS but left off this list belong to always-load cross-framework classes
     * instead (KMS_KEY_ROTATION, SECRETS_MANAGER, SECRETS_ROTATION, DATABASE_MULTI_AZ,
     * DATABASE_PITR, DATABASE_LOGGING, CONTAINER_SECURITY, API_SECURITY, CDN_SECURITY,
     * INSTANCE_METADATA_SECURITY, ROOT_ACCOUNT_PROTECTION, CREDENTIAL_ROTATION,
     * SNS_KMS_ENCRYPTION, VULNERABILITY_SCANNING, BACKUP_RECOVERY, HIGH_AVAILABILITY -- see
     * KeyManagementRules, DatabaseSecurityRules, IamSecurityRules, 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(
            "NETWORK_SEGMENTATION", "ENCRYPTION_AT_REST", "ENCRYPTION_IN_TRANSIT",
            "WAF_PROTECTION", "AUTHENTICATION", "ACCESS_CONTROL", "AUDIT_LOGGING",
            "NETWORK_FLOW_LOGS", "LOG_RETENTION", "THREAT_DETECTION", "SECURITY_MONITORING",
            "VULNERABILITY_MANAGEMENT", "HTTPS_STRICT", "CLOUDWATCH_LOGS_KMS_ENCRYPTION",
            "S3_OBJECT_LOCK", "CHANGE_MANAGEMENT"
        );
    }

    /**
     * Generate PCI-DSS compliance report showing which requirements are met.
     */
    public String generateComplianceReport(SystemContext ctx) {
        StringBuilder report = new StringBuilder();
        report.append("\n=== PCI-DSS 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("Network Mode: ").append(ctx.cfc.networkMode()).append("\n");
        report.append("Authentication: ").append(ctx.cfc.authMode()).append("\n\n");

        report.append("Infrastructure Controls:\n");
        report.append("  ✓ Network Segmentation (Req 1.2.1): ").append(ctx.vpc.get().isPresent() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ Private Network (Req 1.3): ").append(ctx.cfc.networkMode() == NetworkMode.PRIVATE_WITH_NAT ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ EBS Encryption (Req 3.4): ").append(config.isEbsEncryptionEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ EFS Encryption at Rest (Req 3.4): ").append(config.isEfsEncryptionAtRestEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ EFS Encryption in Transit (Req 4.1): ").append(config.isEfsEncryptionInTransitEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ S3 Encryption (Req 3.4): ").append(config.isS3EncryptionEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ TLS Certificate (Req 4.1): ").append(ctx.cert.get().isPresent() ? "CONFIGURED" : "MISSING").append("\n");
        report.append("  ✓ WAF Protection (Req 6.6): ").append(config.isWafEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ Authentication (Req 8.2): ").append(ctx.cfc.authMode() != AuthMode.NONE ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ CloudTrail (Req 10.2): ").append(config.isCloudTrailEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ VPC Flow Logs (Req 10.3): ").append(config.isFlowLogsEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ ALB Access Logs (Req 10.5): ").append(config.isAlbAccessLoggingEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ Log Retention (Req 10.7): ").append(config.getLogRetentionDays().toString()).append("\n");
        report.append("  ✓ GuardDuty (Req 11.4): ").append(config.isGuardDutyEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ Security Monitoring (Req 11.5): ").append(config.isSecurityMonitoringEnabled() ? "ENABLED" : "DISABLED").append("\n");
        report.append("  ✓ AWS Config (Req 11.6): ").append(config.isAwsConfigEnabled() ? "ENABLED" : "DISABLED").append("\n");

        report.append("\n");

        appendAdvisorySection(report, ctx);

        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) {
        List<ComplianceRule> rules = new ArrayList<>();
        rules.addAll(validateNetworkSecurity(ctx));
        rules.addAll(validateEncryption(ctx));
        rules.addAll(validateWebApplicationSecurity(ctx));
        rules.addAll(validateAccessControl(ctx));
        rules.addAll(validateAuditLogging(ctx));
        rules.addAll(validateSecurityMonitoring(ctx));
        rules.addAll(validateVendorDefaults(ctx));
        rules.addAll(validateMatrixControls(ctx));

        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");
    }
}