Skip to main content
Pulumi logo Pulumi logo
  1. Docs
  2. Reference
  3. Pre-built Policy Packs
  4. NIST
  5. AWS

NIST SP 800-53 - AWS

    This page lists all 139 policies in the NIST SP 800-53 pack for AWS, as published in nist-aws version 1.0.2.

    Policies by control

    AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.

    AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.

    AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.

    AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.

    AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.

    AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.

    AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.

    AU-5 Response to Audit Processing Failures — The information system alerts designated organizational officials in the event of an audit processing failure and takes additional actions.

    AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.

    AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.

    CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.

    CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.

    CM-3 Configuration Change Control — The organization determines the types of changes to the information system that are configuration-controlled.

    CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.

    CP-10 Information System Recovery and Reconstitution — The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.

    CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.

    CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.

    IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).

    IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.

    IR-4 Incident Handling — The organization implements incident handling capability for security incidents that includes preparation, detection and analysis, containment, eradication, and recovery.

    MP-6 Media Sanitization — The organization sanitizes information system media, both paper and digital, prior to disposal, release out of organizational control, or release for reuse.

    SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.

    SC-20 Secure Name / Address Resolution Service (Authoritative Source) — The information system provides additional data origin and integrity artifacts along with the authoritative name resolution data the system returns in response to external name/address resolution queries.

    SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.

    SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.

    SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.

    SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.

    SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.

    SI-3 Malicious Code Protection — The organization implements malicious code protection mechanisms at information system entry and exit points.

    SI-4 Information System Monitoring — The organization monitors the information system to detect attacks and indicators of potential attacks.

    SI-7 Software, Firmware, and Information Integrity — The organization employs integrity verification tools to detect unauthorized changes to software, firmware, and information.

    Policy details

    api-gateway-access-logging

    Severity: medium · Enforcement: advisory

    Ensures API Gateway stages have access logging enabled

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Access Logging for API Gateway Stage

    Configure the accessLogSettings property with a CloudWatch Log Group ARN to enable comprehensive audit logging:

    const logGroup = new aws.cloudwatch.LogGroup("api-logs", {
        retentionInDays: 30,
    });
    
    const stage = new aws.apigateway.Stage("my-stage", {
        restApi: api.id,
        stageName: "prod",
        deployment: deployment.id,
        accessLogSettings: { // Enable access logging
            destinationArn: logGroup.arn, // Specify CloudWatch Log Group
            format: "$context.requestId",
        },
    });
    

    api-gateway-cache-encryption-enabled

    Severity: medium · Enforcement: advisory

    Ensures API Gateway method settings have cache data encryption enabled when caching is configured.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable cache data encryption for API Gateway method settings

    When enabling caching for API Gateway methods, ensure cache data encryption is also enabled to protect sensitive data at rest.

    import * as aws from "@pulumi/aws";
    
    const methodSettings = new aws.apigateway.MethodSettings("example-method-settings", {
        restApi: restApi.id,
        stageName: stage.stageName,
        methodPath: "*/*",
        settings: {
            cachingEnabled: true,
            cacheDataEncrypted: true,  // Enable cache encryption at rest
            cacheTtlInSeconds: 300,
        },
    });
    

    api-gateway-ssl-certificate-required

    Severity: high · Enforcement: advisory

    Ensures API Gateway REST API stages have client certificates configured for SSL/TLS authentication to protect data in transit.

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure Client Certificate for API Gateway Stage

    First, create a client certificate:

    import * as aws from "@pulumi/aws";
    
    // Create a client certificate for SSL/TLS authentication
    const clientCert = new aws.apigateway.ClientCertificate("api-client-cert", {
        description: "Client certificate for API Gateway SSL authentication",
    });
    

    Then, associate the certificate with your API Gateway stage:

    const stage = new aws.apigateway.Stage("api-stage", {
        restApi: restApi.id,
        deployment: deployment.id,
        stageName: "production",
        clientCertificateId: clientCert.id, // Add this property to enable SSL certificate validation
    });
    

    api-gateway-v2-access-logging

    Severity: medium · Enforcement: advisory

    Ensures API Gateway V2 stages have access logging enabled

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Access Logging for API Gateway V2 Stage

    Configure the accessLogSettings property with a CloudWatch Log Group ARN to enable comprehensive audit logging:

    const logGroup = new aws.cloudwatch.LogGroup("api-v2-logs", {
        retentionInDays: 30,
    });
    
    const stage = new aws.apigatewayv2.Stage("my-stage", {
        apiId: api.id,
        name: "prod",
        accessLogSettings: { // Enable access logging
            destinationArn: logGroup.arn, // Specify CloudWatch Log Group
            format: "$context.requestId",
        },
    });
    

    api-gateway-waf-enabled

    Severity: critical · Enforcement: advisory

    Ensures API Gateway stages have WAF Web ACL associations for protection against web attacks.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Associate a WAF Web ACL with your API Gateway stage

    Create a WebAclAssociation resource to link your WAF Web ACL to the API Gateway stage:

    import * as aws from "@pulumi/aws";
    
    // Your existing API Gateway stage
    const apiStage = new aws.apigateway.Stage("api-stage", {
        restApi: restApi.id,
        stageName: "prod",
        deployment: deployment.id,
    });
    
    // Create or reference a WAF Web ACL
    const webAcl = new aws.wafv2.WebAcl("web-acl", {
        scope: "REGIONAL",
        defaultAction: { allow: {} },
        rules: [/* your WAF rules */],
        visibilityConfig: {
            cloudwatchMetricsEnabled: true,
            metricName: "webAclMetric",
            sampledRequestsEnabled: true,
        },
    });
    
    // Associate the WAF Web ACL with the API Gateway stage
    const wafAssociation = new aws.wafv2.WebAclAssociation("stage-waf", {
        resourceArn: apiStage.arn, // Link to the API Gateway stage
        webAclArn: webAcl.arn,
    });
    

    autoscaling-health-checks-enabled

    Severity: medium · Enforcement: advisory

    Ensures Auto Scaling groups with load balancers have ELB health checks configured for proper monitoring.

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Configure ELB Health Checks for Auto Scaling Group

    Set the healthCheckType to “ELB” and configure an appropriate healthCheckGracePeriod (minimum 300 seconds) for Auto Scaling groups that use load balancers:

    const asg = new aws.autoscaling.Group("my-asg", {
        minSize: 1,
        maxSize: 3,
        targetGroupArns: [targetGroup.arn],
        healthCheckType: "ELB", // Enable ELB health checks
        healthCheckGracePeriod: 300, // Set grace period to at least 300 seconds
        vpcZoneIdentifiers: subnetIds,
        launchTemplate: {
            id: launchTemplate.id,
            version: "$Latest",
        },
    });
    

    cloudtrail-cloudwatch-logs-integration

    Severity: medium · Enforcement: advisory

    Ensures CloudTrail trails have CloudWatch Logs integration enabled for real-time monitoring and analysis.

    • AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.
    Remediation
    Fix: Configure CloudWatch Logs Integration for CloudTrail

    Add the CloudWatch Logs group ARN and IAM role ARN to your CloudTrail trail configuration:

    const logGroup = new aws.cloudwatch.LogGroup("trail-log-group", {
        retentionInDays: 90,
    });
    
    const trailRole = new aws.iam.Role("trail-cloudwatch-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { Service: "cloudtrail.amazonaws.com" },
                Action: "sts:AssumeRole",
            }],
        }),
    });
    
    const trail = new aws.cloudtrail.Trail("my-trail", {
        s3BucketName: bucket.id,
        cloudWatchLogsGroupArn: logGroup.arn,  // Add this field
        cloudWatchLogsRoleArn: trailRole.arn,  // Add this field
    });
    

    cloudtrail-enabled

    Severity: critical · Enforcement: advisory

    Ensures CloudTrail is enabled with at least one active trail for audit logging.

    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    Remediation
    Fix: Enable CloudTrail for audit logging

    Create a CloudTrail trail to capture API activity and management events:

    import * as aws from "@pulumi/aws";
    
    // Create an S3 bucket for CloudTrail logs
    const trailBucket = new aws.s3.Bucket("cloudtrail-logs", {
        forceDestroy: true, // Only for demo - remove in production
    });
    
    // Create CloudTrail trail
    const trail = new aws.cloudtrail.Trail("main-trail", {
        s3BucketName: trailBucket.bucket,
        isMultiRegionTrail: true, // Enable for all regions
        includeGlobalServiceEvents: true,
        enableLogFileValidation: true, // Ensure log integrity
    });
    

    Key configuration:

    • Set isMultiRegionTrail: true to capture events across all AWS regions
    • Enable includeGlobalServiceEvents to capture IAM and STS events
    • Use enableLogFileValidation to ensure log integrity

    cloudtrail-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures CloudTrail trails have encryption enabled using KMS keys.

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Enable KMS Encryption for CloudTrail

    Add a customer-managed KMS key to your CloudTrail trail configuration:

    import * as aws from "@pulumi/aws";
    
    // Create or reference a KMS key for CloudTrail encryption
    const trailKey = new aws.kms.Key("trail-key", {
        description: "KMS key for CloudTrail log encryption",
        enableKeyRotation: true,
    });
    
    const trail = new aws.cloudtrail.Trail("my-trail", {
        s3BucketName: bucket.id,
        kmsKeyId: trailKey.arn, // Add the KMS key ARN to enable encryption
    });
    

    cloudtrail-log-file-validation-enabled

    Severity: high · Enforcement: advisory

    Ensures CloudTrail trails have log file validation enabled to protect audit log integrity.

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Enable CloudTrail Log File Validation

    Update your CloudTrail trail configuration to enable log file validation:

    import * as aws from "@pulumi/aws";
    
    const trail = new aws.cloudtrail.Trail("my-trail", {
        s3BucketName: "my-cloudtrail-bucket",
        enableLogFileValidation: true, // Enable log file validation to ensure audit log integrity
    });
    

    This ensures CloudTrail logs are cryptographically signed, allowing you to verify they haven’t been modified after delivery.

    cloudtrail-multi-region-enabled

    Severity: high · Enforcement: advisory

    Ensures CloudTrail trails are configured as multi-region trails for comprehensive audit coverage.

    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    Remediation
    Fix: Enable Multi-Region Trail Configuration

    Set the isMultiRegionTrail property to true to enable comprehensive audit coverage across all AWS regions.

    const trail = new aws.cloudtrail.Trail("audit-trail", {
        s3BucketName: bucket.bucket,
        isMultiRegionTrail: true, // Enable multi-region trail for system-wide audit coverage
    });
    

    cloudtrail-s3-bucket-public-access-denied

    Severity: critical · Enforcement: advisory

    Ensures S3 buckets used for CloudTrail logging deny public access to protect audit information.

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Configure S3 Bucket Public Access Block for CloudTrail

    Add a BucketPublicAccessBlock resource to the CloudTrail S3 bucket with all public access settings enabled:

    import * as aws from "@pulumi/aws";
    
    const cloudtrailBucket = new aws.s3.Bucket("cloudtrail-logs", {
        bucket: "my-cloudtrail-logs"
    });
    
    // Enable public access block to protect audit logs
    const publicAccessBlock = new aws.s3.BucketPublicAccessBlock("cloudtrail-public-access-block", {
        bucket: cloudtrailBucket.id,
        blockPublicAcls: true,        // Block public ACLs
        blockPublicPolicy: true,      // Block public bucket policies
        ignorePublicAcls: true,       // Ignore existing public ACLs
        restrictPublicBuckets: true,  // Restrict public bucket access
    });
    

    cloudtrail-s3-data-events-enabled

    Severity: medium · Enforcement: advisory

    Ensures CloudTrail trails have S3 data events enabled for comprehensive object-level logging.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable S3 Data Events in CloudTrail

    Configure your CloudTrail trail to log S3 object-level operations by adding event selectors:

    import * as aws from "@pulumi/aws";
    
    const trail = new aws.cloudtrail.Trail("my-trail", {
        s3BucketName: trailBucket.bucket,
        // Enable S3 data events for all buckets
        eventSelectors: [{
            readWriteType: "All", // Log both read and write operations
            includeManagementEvents: true,
            dataResources: [{
                type: "AWS::S3::Object",
                values: ["arn:aws:s3:::*/*"], // Monitor all S3 objects
            }],
        }],
    });
    

    Alternatively, use advanced event selectors for more granular control:

    const trail = new aws.cloudtrail.Trail("my-trail", {
        s3BucketName: trailBucket.bucket,
        advancedEventSelectors: [{
            name: "Log S3 data events",
            fieldSelectors: [
                {
                    field: "eventCategory",
                    equals: ["Data"], // Data events category
                },
                {
                    field: "resources.type",
                    equals: ["AWS::S3::Object"], // S3 object operations
                },
            ],
        }],
    });
    

    cloudwatch-alarms-actions-required

    Severity: medium · Enforcement: advisory

    Ensures CloudWatch alarms have actions enabled and configured for proper incident response.

    • IR-4 Incident Handling — The organization implements incident handling capability for security incidents that includes preparation, detection and analysis, containment, eradication, and recovery.
    Remediation
    Fix: Enable CloudWatch Alarm Actions

    Configure your CloudWatch alarm to have actions enabled and specify at least one action for the ALARM state:

    import * as aws from "@pulumi/aws";
    
    // Create SNS topic for alarm notifications
    const alarmTopic = new aws.sns.Topic("alarm-topic", {
        displayName: "CloudWatch Alarm Notifications",
    });
    
    // Create CloudWatch alarm with actions enabled
    const alarm = new aws.cloudwatch.MetricAlarm("my-alarm", {
        comparisonOperator: "GreaterThanThreshold",
        evaluationPeriods: 2,
        metricName: "CPUUtilization",
        namespace: "AWS/EC2",
        period: 120,
        statistic: "Average",
        threshold: 80,
        actionsEnabled: true,  // Enable actions (default: true)
        alarmActions: [alarmTopic.arn],  // Add SNS topic ARN for ALARM state
    });
    

    cloudwatch-log-group-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures CloudWatch log groups have encryption enabled using KMS keys.

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Enable KMS Encryption for CloudWatch Log Group

    Add a KMS key to your CloudWatch log group resource to enable encryption at rest:

    import * as aws from "@pulumi/aws";
    
    const logGroup = new aws.cloudwatch.LogGroup("my-log-group", {
        name: "/aws/my-application",
        kmsKeyId: kmsKey.arn,  // Add KMS key ARN to enable encryption
        retentionInDays: 30,
    });
    

    cloudwatch-log-retention

    Severity: medium · Enforcement: advisory

    Ensures CloudWatch log groups have appropriate retention periods for compliance.

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    Remediation
    Fix: Configure CloudWatch Log Group Retention Period

    Set the retentionInDays property to at least 365 days to meet audit record retention requirements.

    import * as aws from "@pulumi/aws";
    
    const logGroup = new aws.cloudwatch.LogGroup("my-log-group", {
        name: "/aws/lambda/my-function",
        retentionInDays: 365, // Set retention to at least 365 days for compliance
    });
    

    config-recorder-enabled

    Severity: high · Enforcement: advisory

    Ensures AWS Config configuration recorders are enabled for tracking and auditing resource changes.

    • CM-3 Configuration Change Control — The organization determines the types of changes to the information system that are configuration-controlled.
    Remediation
    Fix: Enable AWS Config Recorder

    Create a Config Recorder with RecorderStatus to track all resource changes:

    import * as aws from "@pulumi/aws";
    
    // Create Config Recorder
    const recorder = new aws.cfg.Recorder("config-recorder", {
        recordingGroup: {
            allSupported: true,  // Record all supported resource types
            includeGlobalResourceTypes: true,  // Include global resources (IAM, etc.)
        },
        roleArn: configRole.arn,  // IAM role with Config permissions
    });
    
    // Activate the recorder
    const recorderStatus = new aws.cfg.RecorderStatus("config-recorder-status", {
        name: recorder.name,
        isEnabled: true,  // Enable the recorder
    });
    

    config-rule-auto-remediation-enabled

    Severity: medium · Enforcement: advisory

    Ensures AWS Config rules have automatic remediation configured for integrity violations.

    • SI-7 Software, Firmware, and Information Integrity — The organization employs integrity verification tools to detect unauthorized changes to software, firmware, and information.
    Remediation
    Fix: Enable Automatic Remediation for Config Rules

    Create an AWS Config RemediationConfiguration resource for each Config rule to automatically respond to compliance violations.

    import * as aws from "@pulumi/aws";
    
    // Your existing Config rule
    const myConfigRule = new aws.cfg.Rule("my-rule", {
        name: "my-compliance-rule",
        source: {
            owner: "AWS",
            sourceIdentifier: "S3_BUCKET_PUBLIC_READ_PROHIBITED",
        },
    });
    
    // Add automatic remediation configuration
    const remediation = new aws.cfg.RemediationConfiguration("my-rule-remediation", {
        configRuleName: myConfigRule.name,
        targetType: "SSM_DOCUMENT",
        targetIdentifier: "AWS-PublishSNSNotification", // Use appropriate SSM document
        automatic: true, // Enable automatic remediation
        maximumAutomaticAttempts: 5,
        retryAttemptSeconds: 60,
        parameters: [
            {
                name: "AutomationAssumeRole",
                staticValue: "arn:aws:iam::123456789012:role/RemediationRole",
            },
            {
                name: "Message",
                staticValue: "Remediating compliance violation",
            },
        ],
    });
    

    config-snapshot-retention

    Severity: medium · Enforcement: advisory

    Ensures AWS Config retention configuration meets minimum 7-year requirement for compliance auditing.

    • CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.
    Remediation
    Fix: Set AWS Config retention period to minimum 7 years

    Configure the AWS Config retention configuration to retain snapshots for at least 2555 days (7 years):

    import * as aws from "@pulumi/aws";
    
    const configRetention = new aws.cfg.RetentionConfiguration("config-retention", {
        retentionPeriodInDays: 2555, // Set to 7 years (minimum required)
    });
    

    dms-no-public-access

    Severity: critical · Enforcement: advisory

    Ensures DMS replication instances are not publicly accessible to maintain security.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Public Accessibility
    const replicationInstance = new aws.dms.ReplicationInstance("my-replication-instance", {
        replicationInstanceClass: "dms.t3.micro",
        publiclyAccessible: false,  // Set to false to prevent public access
        // ... other config
    });
    

    docdb-clusterinstance-managed-service-patching

    Severity: medium · Enforcement: advisory

    Ensures DocumentDB cluster instances have automated minor version upgrades enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Automatic Minor Version Upgrades for DocumentDB Cluster Instance

    Set the autoMinorVersionUpgrade property to true to enable automated patching for managed service security updates:

    const clusterInstance = new aws.docdb.ClusterInstance("my-cluster-instance", {
        clusterIdentifier: cluster.id,
        instanceClass: "db.r5.large",
        autoMinorVersionUpgrade: true, // Enable automatic minor version upgrades
    });
    

    dynamodb-auto-scaling-enabled

    Severity: medium · Enforcement: advisory

    Ensures DynamoDB tables have auto-scaling or on-demand mode enabled for capacity management.

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Enable DynamoDB Auto-Scaling or On-Demand Mode

    Configure auto-scaling targets and policies for your DynamoDB table’s read and write capacity, or switch to on-demand billing mode:

    import * as aws from "@pulumi/aws";
    
    const table = new aws.dynamodb.Table("myTable", {
        name: "my-table",
        billingMode: "PROVISIONED", // Use provisioned mode with auto-scaling
        readCapacity: 5,
        writeCapacity: 5,
        attributes: [{ name: "id", type: "S" }],
        hashKey: "id",
    });
    
    // Configure read capacity auto-scaling
    const readTarget = new aws.appautoscaling.Target("readTarget", {
        resourceId: pulumi.interpolate`table/${table.name}`,
        scalableDimension: "dynamodb:table:ReadCapacityUnits",
        serviceNamespace: "dynamodb",
        minCapacity: 5,
        maxCapacity: 100, // Set appropriate scaling limits
    });
    
    new aws.appautoscaling.Policy("readPolicy", {
        resourceId: readTarget.resourceId,
        scalableDimension: readTarget.scalableDimension,
        serviceNamespace: readTarget.serviceNamespace,
        policyType: "TargetTrackingScaling",
        targetTrackingScalingPolicyConfiguration: {
            targetValue: 70.0, // Target utilization percentage
            predefinedMetricSpecification: {
                predefinedMetricType: "DynamoDBReadCapacityUtilization",
            },
        },
    });
    
    // Configure write capacity auto-scaling
    const writeTarget = new aws.appautoscaling.Target("writeTarget", {
        resourceId: pulumi.interpolate`table/${table.name}`,
        scalableDimension: "dynamodb:table:WriteCapacityUnits",
        serviceNamespace: "dynamodb",
        minCapacity: 5,
        maxCapacity: 100,
    });
    
    new aws.appautoscaling.Policy("writePolicy", {
        resourceId: writeTarget.resourceId,
        scalableDimension: writeTarget.scalableDimension,
        serviceNamespace: writeTarget.serviceNamespace,
        policyType: "TargetTrackingScaling",
        targetTrackingScalingPolicyConfiguration: {
            targetValue: 70.0,
            predefinedMetricSpecification: {
                predefinedMetricType: "DynamoDBWriteCapacityUtilization",
            },
        },
    });
    
    // Alternative: Use on-demand billing mode (no auto-scaling needed)
    // const table = new aws.dynamodb.Table("myTable", {
    //     billingMode: "PAY_PER_REQUEST", // On-demand mode handles scaling automatically
    //     attributes: [{ name: "id", type: "S" }],
    //     hashKey: "id",
    // });
    

    dynamodb-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures DynamoDB tables have encryption enabled using KMS keys.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed KMS Encryption for DynamoDB Table

    Configure the DynamoDB table with a customer-managed KMS key for encryption at rest:

    import * as aws from "@pulumi/aws";
    
    // Create or reference a customer-managed KMS key
    const kmsKey = new aws.kms.Key("table-encryption-key", {
        description: "KMS key for DynamoDB table encryption",
        deletionWindowInDays: 10,
    });
    
    const table = new aws.dynamodb.Table("my-table", {
        // ... other configuration ...
        serverSideEncryption: {
            enabled: true,  // Enable encryption
            kmsKeyArn: kmsKey.arn,  // Use customer-managed KMS key (not AWS-managed)
        },
    });
    

    dynamodb-point-in-time-recovery-enabled

    Severity: medium · Enforcement: advisory

    DynamoDB tables must have point-in-time recovery enabled

    • CP-10 Information System Recovery and Reconstitution — The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.
    Remediation
    Fix: Enable Point-in-Time Recovery on DynamoDB Table

    Add the pointInTimeRecovery property to your DynamoDB table configuration and set enabled to true.

    const table = new aws.dynamodb.Table("my-table", {
        name: "my-table",
        attributes: [
            { name: "id", type: "S" },
        ],
        hashKey: "id",
        billingMode: "PAY_PER_REQUEST",
        // Enable point-in-time recovery for backup and recovery capabilities
        pointInTimeRecovery: {
            enabled: true,  // Set to true to enable PITR
        },
    });
    

    ebs-unused-volumes-prohibited

    Severity: low · Enforcement: advisory

    EBS volumes must be removed when unused

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Attach EBS volume to an EC2 instance or delete if unused

    Either attach the unattached EBS volume to an EC2 instance, or delete it if no longer needed:

    import * as aws from "@pulumi/aws";
    
    // Option 1: Attach the volume to an EC2 instance
    const volumeAttachment = new aws.ec2.VolumeAttachment("my-volume-attachment", {
        instanceId: instance.id,
        volumeId: volume.id,  // Attach the previously unattached volume
        deviceName: "/dev/sdh",
    });
    
    // Option 2: Delete the unused volume resource from your Pulumi program
    // Simply remove the aws.ebs.Volume resource definition if no longer needed
    

    ebs-volume-disallow-unencrypted-volume

    Severity: high · Enforcement: advisory

    Checks that EBS volumes are encrypted.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable EBS Volume Encryption

    Set the encrypted property to true on the EBS volume:

    const volume = new aws.ebs.Volume("my-volume", {
        availabilityZone: "us-west-2a",
        size: 100,
        encrypted: true, // Enable encryption for the volume
    });
    

    ec2-ebs-optimized-required

    Severity: low · Enforcement: advisory

    EC2 instances must be EBS optimized

    • CP-10 Information System Recovery and Reconstitution — The organization provides for the recovery and reconstitution of the information system to a known state after a disruption, compromise, or failure.
    Remediation
    Fix: Enable EBS optimization for EC2 instances

    Set the ebsOptimized property to true on your EC2 instance resource:

    const instance = new aws.ec2.Instance("my-instance", {
        instanceType: "t3.medium",
        ami: "ami-0c55b159cbfafe1f0",
        ebsOptimized: true, // Enable EBS optimization
    });
    

    Note: Ensure your instance type supports EBS optimization. Most modern instance types (t3, m5, c5, etc.) support it by default.

    ec2-iam-profile-required

    Severity: medium · Enforcement: advisory

    EC2 instances must have IAM profile attached

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Attach IAM Instance Profile
    const role = new aws.iam.Role("ec2-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Action: "sts:AssumeRole",
                Effect: "Allow",
                Principal: { Service: "ec2.amazonaws.com" },
            }],
        }),
    });
    
    const profile = new aws.iam.InstanceProfile("ec2-profile", {
        role: role.name,
    });
    
    const instance = new aws.ec2.Instance("app-server", {
        ami: "ami-12345678",
        instanceType: "t3.medium",
        iamInstanceProfile: profile.name,  // Attach IAM instance profile for role-based access
        subnetId: subnet.id,
    });
    

    ec2-imdsv2-required

    Severity: medium · Enforcement: advisory

    EC2 instances must use IMDSv2

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable IMDSv2 for EC2 Instance

    Configure the EC2 instance to require IMDSv2 by setting metadataOptions.httpTokens to "required":

    new aws.ec2.Instance("my-instance", {
        instanceType: "t3.micro",
        ami: "ami-12345678",
        metadataOptions: {
            httpTokens: "required",  // Enforce IMDSv2
        },
    });
    

    ec2-instance-disallow-public-ip

    Severity: high · Enforcement: advisory

    Checks that EC2 instances do not have a public IP address.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Public IP Address Assignment

    Set associatePublicIpAddress to false to prevent the instance from receiving a public IP address:

    const instance = new ec2.Instance("my-instance", {
        instanceType: "t3.micro",
        ami: "ami-12345678",
        associatePublicIpAddress: false, // Disable public IP assignment
        subnetId: privateSubnet.id,
    });
    

    ec2-instance-disallow-unencrypted-block-device

    Severity: high · Enforcement: advisory

    Checks that EC2 instances do not have unencrypted block devices.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Encryption for EBS Block Devices

    Set the encrypted property to true for all EBS block devices attached to EC2 instances:

    const instance = new aws.ec2.Instance("my-instance", {
        ami: "ami-12345678",
        instanceType: "t3.micro",
        ebsBlockDevices: [{
            deviceName: "/dev/sdf",
            volumeSize: 20,
            encrypted: true, // Enable encryption for the EBS volume
        }],
    });
    

    ec2-instance-disallow-unencrypted-root-block-device

    Severity: high · Enforcement: advisory

    Checks that EC2 instances does not have unencrypted root volumes.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Encryption for Root Block Device

    Set the encrypted property to true in the rootBlockDevice configuration:

    const instance = new aws.ec2.Instance("my-instance", {
        instanceType: "t3.micro",
        ami: "ami-12345678",
        rootBlockDevice: {
            encrypted: true, // Enable encryption for root volume
        },
    });
    

    ec2-monitoring-enabled

    Severity: low · Enforcement: advisory

    EC2 instances must have detailed monitoring enabled

    • SI-4 Information System Monitoring — The organization monitors the information system to detect attacks and indicators of potential attacks.
    Remediation
    Fix: Enable Detailed Monitoring on EC2 Instance

    Set the monitoring property to true on your EC2 instance resource:

    const instance = new aws.ec2.Instance("my-instance", {
        ami: "ami-12345678",
        instanceType: "t3.micro",
        monitoring: true, // Enable detailed (1-minute interval) monitoring
    });
    

    ec2-vpc-placement-required

    Severity: high · Enforcement: advisory

    EC2 instances must be placed in VPC for network isolation

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Place EC2 Instance in a VPC Subnet

    Add the subnetId property to your EC2 instance resource to ensure it’s deployed within a VPC for proper network isolation.

    new aws.ec2.Instance("my-instance", {
        ami: "ami-12345678",
        instanceType: "t3.micro",
        subnetId: mySubnet.id, // Specify a subnet to place instance in VPC
        // ... other configuration
    });
    

    ecs-task-non-privileged-required

    Severity: high · Enforcement: advisory

    ECS task definitions must use non-privileged user for host mode

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Remove Privileged Container Settings
    const taskDefinition = new aws.ecs.TaskDefinition("app-task", {
        family: "app-task",
        containerDefinitions: JSON.stringify([{
            name: "app-container",
            image: "nginx:latest",
            privileged: false,  // Set to false to disable privileged mode
            user: "1000:1000",  // For host network mode: specify non-root user (UID:GID)
            linuxParameters: {
                capabilities: {
                    add: ["NET_BIND_SERVICE"],  // Avoid SYS_ADMIN, NET_ADMIN, or ALL
                },
            },
        }]),
    });
    

    efs-file-system-disallow-unencrypted-file-system

    Severity: high · Enforcement: advisory

    Checks that EFS File Systems do not have an unencrypted file system.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Encryption for EFS File System

    Set the encrypted property to true when creating an EFS file system:

    const fileSystem = new aws.efs.FileSystem("my-efs", {
        encrypted: true, // Enable encryption at rest
        kmsKeyId: kmsKey.arn, // Optional: specify a custom KMS key
    });
    

    elasticache-backup-retention

    Severity: medium · Enforcement: advisory

    ElastiCache Redis clusters must have automatic backup retention for 15 days

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure ElastiCache Backup Retention

    Set the snapshotRetentionLimit property to enable automatic backups with the required retention period:

    new aws.elasticache.ReplicationGroup("redis-cluster", {
        replicationGroupId: "my-redis-cluster",
        // Enable automatic backups with minimum 15 days retention
        snapshotRetentionLimit: 15,
        // Optional: Configure backup window during low-traffic periods
        snapshotWindow: "03:00-05:00",
        // Optional: Preserve data when cluster is deleted
        finalSnapshotIdentifier: "final-snapshot-redis-cluster",
    });
    

    elasticbeanstalk-health-reporting-enabled

    Severity: medium · Enforcement: advisory

    Elastic Beanstalk must have enhanced health reporting enabled

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Enable Enhanced Health Reporting

    Add a setting to your Elastic Beanstalk environment configuration to enable enhanced health reporting:

    const environment = new aws.elasticbeanstalk.Environment("my-env", {
        application: app.name,
        solutionStackName: "64bit Amazon Linux 2 v5.8.0 running Node.js 18",
        settings: [
            {
                namespace: "aws:elasticbeanstalk:healthreporting:system",
                name: "SystemType",
                value: "enhanced", // Enable enhanced health reporting
            },
        ],
    });
    

    elasticbeanstalk-managed-updates-enabled

    Severity: medium · Enforcement: advisory

    Elastic Beanstalk environments must have managed platform updates enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Managed Platform Updates

    Configure managed platform updates for your Elastic Beanstalk environment by adding the required settings:

    import * as aws from "@pulumi/aws";
    
    const environment = new aws.elasticbeanstalk.Environment("my-environment", {
        application: "my-app",
        solutionStackName: "64bit Amazon Linux 2023 v6.0.0 running Node.js 18",
        settings: [
            // Enable managed platform updates
            {
                namespace: "aws:elasticbeanstalk:managedactions",
                name: "ManagedActionsEnabled",
                value: "true",  // Required: Enable automated updates
            },
            {
                namespace: "aws:elasticbeanstalk:managedactions",
                name: "PreferredStartTime",
                value: "sun:02:00",  // Required: Set maintenance window
            },
            // Configure update level
            {
                namespace: "aws:elasticbeanstalk:managedactions:platformupdate",
                name: "UpdateLevel",
                value: "minor",  // Required: Set to "patch", "minor", or "all"
            },
            {
                namespace: "aws:elasticbeanstalk:managedactions:platformupdate",
                name: "InstanceRefreshEnabled",
                value: "true",  // Recommended: Enable for zero-downtime updates
            },
        ],
    });
    

    elasticsearch-cloudwatch-logging-enabled

    Severity: medium · Enforcement: advisory

    Elasticsearch domains must send logs to CloudWatch for audit tracking

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable CloudWatch Logging for Elasticsearch Domain

    Configure the logPublishingOptions property to send audit logs to CloudWatch:

    const logGroup = new aws.cloudwatch.LogGroup("es-audit-logs", {
        retentionInDays: 7
    });
    
    const domain = new aws.elasticsearch.Domain("my-domain", {
        // ... other configuration ...
        logPublishingOptions: [
            {
                logType: "AUDIT_LOGS",  // Enable audit logging
                enabled: true,
                cloudwatchLogGroupArn: logGroup.arn,
            },
        ],
    });
    

    elasticsearch-encryption-enabled

    Severity: high · Enforcement: advisory

    Elasticsearch domains must have encryption at rest enabled

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Encryption at Rest for Elasticsearch Domain

    Enable the encryptAtRest configuration on your Elasticsearch domain to encrypt data stored on disk:

    const domain = new aws.elasticsearch.Domain("my-domain", {
        domainName: "my-elasticsearch-domain",
        encryptAtRest: {
            enabled: true,  // Enable encryption at rest
        },
        // ... other configuration
    });
    

    elasticsearch-https-required

    Severity: high · Enforcement: advisory

    Elasticsearch domains must require HTTPS for client connections

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable HTTPS enforcement for Elasticsearch domain

    Configure the domainEndpointOptions property to enforce HTTPS connections:

    import * as aws from "@pulumi/aws";
    
    const domain = new aws.elasticsearch.Domain("my-domain", {
        domainName: "my-elasticsearch-domain",
        domainEndpointOptions: {
            enforceHttps: true, // Enable HTTPS enforcement
            tlsSecurityPolicy: "Policy-Min-TLS-1-2-2019-07", // Optional: Set minimum TLS version
        },
        // ... other configuration
    });
    

    elasticsearch-node-to-node-encryption-enabled

    Severity: high · Enforcement: advisory

    Elasticsearch domains must have node-to-node encryption enabled

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable node-to-node encryption for Elasticsearch domain

    Add the nodeToNodeEncryption property to your Elasticsearch domain configuration and set enabled to true:

    const esDomain = new aws.elasticsearch.Domain("my-domain", {
        domainName: "my-elasticsearch-domain",
        elasticsearchVersion: "7.10",
        clusterConfig: {
            instanceType: "r5.large.elasticsearch",
        },
        nodeToNodeEncryption: {
            enabled: true, // Enable encryption for inter-node communication
        },
        // ... other configuration
    });
    

    elasticsearch-vpc-required

    Severity: high · Enforcement: advisory

    Elasticsearch domains must be deployed in VPC for network isolation

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Deploy Elasticsearch Domain in VPC

    Add VPC configuration to your Elasticsearch domain to enable network isolation and boundary protection.

    import * as aws from "@pulumi/aws";
    
    const myElasticsearchDomain = new aws.elasticsearch.Domain("my-domain", {
        domainName: "my-domain",
        elasticsearchVersion: "7.10",
        clusterConfig: {
            instanceType: "r5.large.elasticsearch",
            instanceCount: 2,
        },
        // Add VPC configuration for network isolation
        vpcOptions: {
            subnetIds: [subnet1.id, subnet2.id], // Specify subnet IDs from your VPC
            securityGroupIds: [securityGroup.id], // Optional: specify security groups
        },
        ebsOptions: {
            ebsEnabled: true,
            volumeSize: 10,
        },
    });
    

    elb-cross-zone-load-balancing-enabled

    Severity: medium · Enforcement: advisory

    Classic Load Balancers must have cross-zone load balancing enabled

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Enable cross-zone load balancing on Classic Load Balancer

    Set the crossZoneLoadBalancing property to true to distribute traffic evenly across all availability zones.

    const loadBalancer = new aws.elb.LoadBalancer("my-load-balancer", {
        availabilityZones: ["us-west-2a", "us-west-2b"],
        listeners: [{
            instancePort: 80,
            instanceProtocol: "http",
            lbPort: 80,
            lbProtocol: "http",
        }],
        crossZoneLoadBalancing: true, // Enable cross-zone load balancing
    });
    

    elb-deletion-protection

    Severity: medium · Enforcement: advisory

    Load balancers must have deletion protection enabled

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Enable deletion protection on the load balancer

    Set the enableDeletionProtection property to true on your load balancer resource:

    const alb = new aws.lb.LoadBalancer("my-alb", {
        loadBalancerType: "application",
        enableDeletionProtection: true, // Enable deletion protection
        subnets: subnetIds,
    });
    

    elb-load-balancer-configure-access-logging

    Severity: medium · Enforcement: advisory

    Check that ELB Load Balancers uses access logging.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Access Logging for ELB Load Balancer

    Configure the accessLogs property with enabled: true and specify an S3 bucket for storing access logs:

    const lb = new aws.elb.LoadBalancer("my-lb", {
        availabilityZones: ["us-west-2a", "us-west-2b"],
        listeners: [{
            instancePort: 80,
            instanceProtocol: "http",
            lbPort: 80,
            lbProtocol: "http",
        }],
        accessLogs: {
            enabled: true, // Enable access logging
            bucket: "my-logs-bucket", // S3 bucket for logs
        },
    });
    

    elb-load-balancer-configure-multi-availability-zone

    Severity: high · Enforcement: advisory

    Check that ELB Load Balancers uses more than one availability zone.

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure Multiple Availability Zones for Load Balancer

    Specify at least two availability zones in the availabilityZones property to ensure high availability:

    const lb = new aws.elb.LoadBalancer("my-lb", {
        availabilityZones: ["us-east-1a", "us-east-1b"], // Configure multiple AZs for resilience
        listeners: [{
            instancePort: 8000,
            instanceProtocol: "http",
            lbPort: 80,
            lbProtocol: "http",
        }],
    });
    

    elb-load-balancer-disallow-unencrypted-traffic

    Severity: critical · Enforcement: advisory

    Check that ELB Load Balancers do not allow unencrypted (HTTP) traffic.

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Use HTTPS Instead of HTTP for Load Balancer Listeners

    Configure all listeners to use HTTPS (port 443) instead of HTTP (port 80) to ensure encrypted traffic:

    const lb = new aws.elb.LoadBalancer("my-lb", {
        availabilityZones: ["us-west-2a", "us-west-2b"],
        listeners: [{
            instancePort: 443,
            instanceProtocol: "https",
            lbPort: 443,
            lbProtocol: "https", // Use HTTPS instead of HTTP
            sslCertificateId: "arn:aws:iam::123456789012:server-certificate/my-cert",
        }],
    });
    

    elb-load-balancer-enable-health-check

    Severity: high · Enforcement: advisory

    Check that ELB Load Balancers have a health check enabled.

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure Health Check for Classic Load Balancer

    Add a healthCheck configuration block to your ELB Load Balancer to enable health monitoring:

    const lb = new aws.elb.LoadBalancer("my-load-balancer", {
        availabilityZones: ["us-west-2a", "us-west-2b"],
        listeners: [{
            instancePort: 80,
            instanceProtocol: "HTTP",
            lbPort: 80,
            lbProtocol: "HTTP",
        }],
        healthCheck: { // Enable health check configuration
            target: "HTTP:80/",
            interval: 30,
            timeout: 5,
            healthyThreshold: 2,
            unhealthyThreshold: 2,
        },
    });
    

    elb-waf-enabled

    Severity: critical · Enforcement: advisory

    Application Load Balancers must have WAF enabled

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Associate a WAF Web ACL with your Application Load Balancer

    Create a WAF Web ACL and associate it with your internet-facing Application Load Balancer:

    import * as aws from "@pulumi/aws";
    
    // Create or reference an existing WAF Web ACL
    const webAcl = new aws.wafv2.WebAcl("my-web-acl", {
        scope: "REGIONAL",
        defaultAction: { allow: {} },
        visibilityConfig: {
            cloudwatchMetricsEnabled: true,
            metricName: "myWebAclMetric",
            sampledRequestsEnabled: true,
        },
        rules: [/* Add your WAF rules here */],
    });
    
    // Associate the WAF Web ACL with your Application Load Balancer
    const wafAssociation = new aws.wafv2.WebAclAssociation("alb-waf-association", {
        resourceArn: loadBalancer.arn, // Reference your ALB
        webAclArn: webAcl.arn,         // Associate with the Web ACL
    });
    

    emr-no-default-subnet

    Severity: high · Enforcement: advisory

    EMR clusters must specify explicit subnet configuration to prevent default subnet usage

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Specify Explicit Subnet Configuration
    const cluster = new aws.emr.Cluster("my-cluster", {
        name: "my-emr-cluster",
        releaseLabel: "emr-6.10.0",
        ec2Attributes: {
            subnetId: privateSubnet.id,  // Explicitly specify a private subnet
            emrManagedMasterSecurityGroup: masterSg.id,
            emrManagedSlaveSecurityGroup: slaveSg.id,
            instanceProfile: instanceProfile.arn,
        },
        // ... other configuration
    });
    

    emr-no-public-ip

    Severity: high · Enforcement: advisory

    EMR clusters must not be deployed in public subnets that auto-assign public IP addresses

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Deploy EMR Cluster in Private Subnet
    const privateSubnet = new aws.ec2.Subnet("private-subnet", {
        vpcId: vpc.id,
        cidrBlock: "10.0.1.0/24",
        mapPublicIpOnLaunch: false,  // Disable auto-assign public IP
        availabilityZone: "us-east-1a",
    });
    
    const emrCluster = new aws.emr.Cluster("my-cluster", {
        releaseLabel: "emr-6.10.0",
        ec2Attributes: {
            subnetId: privateSubnet.id,  // Use private subnet without public IP auto-assignment
            emrManagedMasterSecurityGroup: masterSecurityGroup.id,
            emrManagedSlaveSecurityGroup: slaveSecurityGroup.id,
        },
        // ... other cluster configuration
    });
    

    guardduty-malware-detection-enabled

    Severity: high · Enforcement: advisory

    Ensures AWS GuardDuty is enabled with malware detection capabilities for threat protection.

    • SI-3 Malicious Code Protection — The organization implements malicious code protection mechanisms at information system entry and exit points.
    Remediation
    Fix: Enable GuardDuty with Malware Detection

    Create a GuardDuty Detector with EBS malware protection and S3 data events enabled:

    import * as aws from "@pulumi/aws";
    
    // Enable GuardDuty detector
    const detector = new aws.guardduty.Detector("guardduty-detector", {
        enable: true, // Ensure detector is enabled
    });
    
    // Enable EBS malware protection for EC2 instances
    new aws.guardduty.DetectorFeature("ebs-malware-protection", {
        detectorId: detector.id,
        name: "EBS_MALWARE_PROTECTION",
        status: "ENABLED", // Enable malware scanning for EBS volumes
    });
    
    // Enable S3 data events protection
    new aws.guardduty.DetectorFeature("s3-protection", {
        detectorId: detector.id,
        name: "S3_DATA_EVENTS",
        status: "ENABLED", // Enable S3 threat detection
    });
    

    iam-group-policy-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM group policies follow least privilege principles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Replace Wildcard Permissions with Specific Actions and Resources

    Replace wildcard actions and resources with explicit, scoped permissions:

    const groupPolicy = new aws.iam.GroupPolicy("my-group-policy", {
        group: myGroup.name,
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: [
                    "cloudwatch:PutMetricData",  // Specify exact actions needed
                ],
                Resource: "*",  // Some AWS services require "*" for resource
                Condition: {
                    StringEquals: {
                        "cloudwatch:namespace": "MyApp",  // Use conditions to scope access
                    },
                },
            }],
        }),
    });
    

    iam-group-policy-restriction

    Severity: medium · Enforcement: advisory

    IAM group policies (inline policy attachments) should not be used

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Use GroupPolicyAttachment with Managed Policy
    // Create a managed policy instead of inline policy
    const customPolicy = new aws.iam.Policy("custom-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: ["s3:ListBucket", "s3:GetBucketLocation"],
                Resource: "arn:aws:s3:::my-shared-bucket",
            }],
        }),
    });
    
    // Don't use aws.iam.GroupPolicy (inline attachment)
    // Instead, use GroupPolicyAttachment with managed policy
    new aws.iam.GroupPolicyAttachment("group-policy-attachment", {
        group: myGroup.name,
        policyArn: customPolicy.arn,  // Attach managed policy for consistent permission management
    });
    

    iam-password-complexity

    Severity: high · Enforcement: advisory

    IAM password policy must require character complexity (lowercase, uppercase, numbers, symbols)

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Enable all character complexity requirements in IAM password policy

    Update your IAM account password policy to require all character types:

    new aws.iam.AccountPasswordPolicy("account-password-policy", {
        requireLowercaseCharacters: true,  // Require lowercase letters
        requireUppercaseCharacters: true,  // Require uppercase letters
        requireNumbers: true,              // Require numbers
        requireSymbols: true,              // Require symbols
        minimumPasswordLength: 14,
    });
    

    iam-password-expiration

    Severity: high · Enforcement: advisory

    IAM password policy must expire passwords

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Configure Password Expiration in IAM Password Policy

    Set the maxPasswordAge property to enforce password expiration. Passwords should expire within 30-365 days based on your organization’s security requirements.

    import * as aws from "@pulumi/aws";
    
    const accountPasswordPolicy = new aws.iam.AccountPasswordPolicy("policy", {
        maxPasswordAge: 90,  // Passwords must be changed every 90 days
        minimumPasswordLength: 14,
        requireNumbers: true,
        requireSymbols: true,
        requireLowercaseCharacters: true,
        requireUppercaseCharacters: true,
    });
    

    iam-password-policy-minimum-password-length

    Severity: high · Enforcement: advisory

    Ensure IAM password policy requires minimum length of 14 or greater.

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Set Minimum Password Length to 14 Characters

    Set the minimumPasswordLength to 14 or greater for the IAM Account Password Policy:

    const passwordPolicy = new aws.iam.AccountPasswordPolicy("account-password-policy", {
        minimumPasswordLength: 14, // Set minimum length to at least 14 characters
    });
    

    iam-password-policy-prevent-reuse

    Severity: high · Enforcement: advisory

    Ensure IAM password policy prevents password reuse.

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Configure Password Reuse Prevention

    Set the passwordReusePrevention property to 24 to prevent users from reusing their previous 24 passwords:

    const accountPasswordPolicy = new aws.iam.AccountPasswordPolicy("password-policy", {
        minimumPasswordLength: 14,
        requireNumbers: true,
        requireSymbols: true,
        requireUppercaseCharacters: true,
        requireLowercaseCharacters: true,
        passwordReusePrevention: 24, // Prevent reuse of previous 24 passwords
    });
    

    iam-policy-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM policies follow least privilege principles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Replace Wildcard Permissions with Specific Actions and Resources

    Replace wildcard actions and resources with explicit, scoped permissions that grant only the minimum required access:

    const policy = new aws.iam.Policy("my-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: [
                    "s3:GetObject",        // Specify exact actions needed
                    "s3:PutObject",
                ],
                Resource: [
                    "arn:aws:s3:::my-bucket/*",  // Scope to specific resources
                ],
            }],
        }),
    });
    

    iam-policy-mfa-enforcement

    Severity: high · Enforcement: advisory

    IAM policies must require MFA for privileged actions

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Add MFA condition to privileged IAM policy statements

    Add a Condition block to policy statements that allow privileged actions:

    new aws.iam.Policy("admin-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: [
                    "iam:*",
                    "organizations:*",
                    "s3:DeleteBucket",
                    "rds:DeleteDBInstance"
                ],
                Resource: "*",
                Condition: {
                    Bool: {
                        // Require MFA for privileged operations
                        "aws:MultiFactorAuthPresent": "true"
                    }
                }
            }]
        })
    });
    

    iam-role-assume-role-mfa-enforcement

    Severity: high · Enforcement: advisory

    Ensures IAM roles require MFA when assumed by human users (not AWS services)

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Add MFA Condition to Role Trust Policy

    Add the aws:MultiFactorAuthPresent condition to any assume role statement that allows human principals to assume the role:

    const adminRole = new aws.iam.Role("admin-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    AWS: "arn:aws:iam::123456789012:root" // Root account (human)
                },
                Action: "sts:AssumeRole",
                Condition: {
                    Bool: {
                        "aws:MultiFactorAuthPresent": "true" // Require MFA
                    }
                }
            }],
        }),
    });
    
    const userAssumeRole = new aws.iam.Role("user-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    AWS: "arn:aws:iam::123456789012:user/john.doe" // IAM user (human)
                },
                Action: "sts:AssumeRole",
                Condition: {
                    Bool: {
                        "aws:MultiFactorAuthPresent": "true" // Require MFA
                    }
                }
            }],
        }),
    });
    
    // Service roles are automatically exempt (no MFA condition needed)
    const ecsTaskRole = new aws.iam.Role("ecs-task-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    Service: "ecs-tasks.amazonaws.com" // Service principal - no MFA needed
                },
                Action: "sts:AssumeRole"
            }],
        }),
    });
    
    // Role principals are never flagged (could be cross-account service roles)
    const crossAccountRole = new aws.iam.Role("cross-account-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    AWS: "arn:aws:iam::111111111111:role/service-role" // Role principal - not checked
                },
                Action: "sts:AssumeRole"
            }],
        }),
    });
    

    iam-role-inline-policy-restriction

    Severity: medium · Enforcement: advisory

    IAM roles must not have inline policies

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Replace Inline Policies with Managed Policies
    // Create a managed policy
    const customPolicy = new aws.iam.Policy("custom-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: ["s3:GetObject", "s3:PutObject"],
                Resource: "arn:aws:s3:::my-bucket/*",
            }],
        }),
    });
    
    // Create the role without inline policies
    const role = new aws.iam.Role("app-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { Service: "ec2.amazonaws.com" },
                Action: "sts:AssumeRole",
            }],
        }),
        // Remove inlinePolicies property entirely
    });
    
    // Attach the managed policy instead
    new aws.iam.RolePolicyAttachment("role-policy-attachment", {
        role: role.name,
        policyArn: customPolicy.arn,  // Use managed policy for better governance
    });
    

    iam-role-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM roles follow least privilege principles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Replace Wildcard Permissions with Specific Actions and Resources

    Replace wildcard actions and resources in inline policies with explicit, scoped permissions:

    const role = new aws.iam.Role("my-role", {
        assumeRolePolicy: assumePolicyDoc,
        inlinePolicies: [{
            name: "my-inline-policy",
            policy: JSON.stringify({
                Version: "2012-10-17",
                Statement: [{
                    Effect: "Allow",
                    Action: [
                        "dynamodb:GetItem",    // Specify exact actions needed
                        "dynamodb:PutItem",
                    ],
                    Resource: [
                        "arn:aws:dynamodb:us-east-1:123456789012:table/MyTable",  // Scope to specific resources
                    ],
                }],
            }),
        }],
    });
    

    iam-role-mfa-enforcement

    Severity: high · Enforcement: advisory

    IAM roles must require MFA for privileged actions

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Add MFA condition to privileged IAM role inline policies

    Add a Condition block to policy statements that allow privileged actions:

    new aws.iam.Role("admin-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { AWS: "arn:aws:iam::123456789012:root" },
                Action: "sts:AssumeRole"
            }]
        }),
        inlinePolicies: [{
            name: "admin-policy",
            policy: JSON.stringify({
                Version: "2012-10-17",
                Statement: [{
                    Effect: "Allow",
                    Action: ["iam:*", "organizations:*"],
                    Resource: "*",
                    Condition: {
                        Bool: {
                            // Require MFA for privileged operations
                            "aws:MultiFactorAuthPresent": "true"
                        }
                    }
                }]
            })
        }]
    });
    

    iam-role-policy-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM role policies follow least privilege principles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Replace Wildcard Permissions with Specific Actions and Resources

    Replace wildcard actions and resources with explicit, scoped permissions:

    const rolePolicy = new aws.iam.RolePolicy("my-role-policy", {
        role: myRole.id,
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: [
                    "ec2:DescribeInstances",   // Specify exact actions needed
                    "ec2:StartInstances",
                    "ec2:StopInstances",
                ],
                Resource: [
                    "arn:aws:ec2:us-east-1:123456789012:instance/*",  // Scope to specific resources
                ],
            }],
        }),
    });
    

    iam-role-policy-mfa-enforcement

    Severity: high · Enforcement: advisory

    IAM role policies must require MFA for privileged actions

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Add MFA condition to privileged IAM role policy statements

    Add a Condition block to policy statements that allow privileged actions:

    new aws.iam.RolePolicy("admin-role-policy", {
        role: adminRole.id,
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: ["iam:CreateUser", "iam:DeleteUser", "iam:*"],
                Resource: "*",
                Condition: {
                    Bool: {
                        // Require MFA for privileged operations
                        "aws:MultiFactorAuthPresent": "true"
                    }
                }
            }]
        })
    });
    

    iam-role-policy-restriction

    Severity: medium · Enforcement: advisory

    IAM role policies (inline policy attachments) should not be used

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Use RolePolicyAttachment with Managed Policy
    // Create a managed policy instead of inline policy
    const customPolicy = new aws.iam.Policy("custom-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: ["dynamodb:GetItem", "dynamodb:PutItem"],
                Resource: "arn:aws:dynamodb:*:*:table/MyTable",
            }],
        }),
    });
    
    // Don't use aws.iam.RolePolicy (inline attachment)
    // Instead, use RolePolicyAttachment with managed policy
    new aws.iam.RolePolicyAttachment("role-policy-attachment", {
        role: myRole.name,
        policyArn: customPolicy.arn,  // Attach managed policy for centralized governance
    });
    

    iam-user-group-membership-required

    Severity: medium · Enforcement: advisory

    IAM users must be members of groups for proper access management

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Add User to IAM Group
    const user = new aws.iam.User("developer", {
        name: "developer-user",
    });
    
    const group = new aws.iam.Group("developers", {
        name: "developers",
    });
    
    // Add user to group to satisfy group membership requirement
    new aws.iam.UserGroupMembership("developer-membership", {
        user: user.name,
        groups: [group.name],  // Assign user to appropriate groups
    });
    

    iam-user-mfa-console-access

    Severity: high · Enforcement: advisory

    Ensures IAM users with console access have MFA devices

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Enable MFA for IAM User Console Access

    Create a Virtual MFA Device for each IAM user with console access:

    const user = new aws.iam.User("example-user", {
        name: "example-user",
    });
    
    const loginProfile = new aws.iam.UserLoginProfile("example-login", {
        user: user.name,
    });
    
    // Create Virtual MFA Device for the user
    const mfaDevice = new aws.iam.VirtualMfaDevice("example-user-mfa", {
        virtualMfaDeviceName: "example-user-mfa", // Name must match pattern: <username>-mfa or <username>-mfa-device
        userName: user.name, // Associate MFA device with the user
    });
    

    iam-user-policy-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM user policies follow least privilege principles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Replace Wildcard Permissions with Specific Actions and Resources

    Replace wildcard actions and resources with explicit, scoped permissions:

    const userPolicy = new aws.iam.UserPolicy("my-user-policy", {
        user: myUser.name,
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: [
                    "s3:ListBucket",         // Specify exact actions needed
                ],
                Resource: [
                    "arn:aws:s3:::my-bucket",  // Scope to specific resources
                ],
            }],
        }),
    });
    

    iam-user-policy-restriction

    Severity: medium · Enforcement: advisory

    IAM user policies (inline policy attachments) should not be used

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Use UserPolicyAttachment with Managed Policy
    // Create a managed policy instead of inline policy
    const customPolicy = new aws.iam.Policy("custom-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: ["ec2:DescribeInstances", "ec2:StartInstances"],
                Resource: "*",
            }],
        }),
    });
    
    // Don't use aws.iam.UserPolicy (inline attachment)
    // Instead, use UserPolicyAttachment with managed policy
    new aws.iam.UserPolicyAttachment("user-policy-attachment", {
        user: myUser.name,
        policyArn: customPolicy.arn,  // Attach managed policy for reusability and audit tracking
    });
    

    kms-key-creation

    Severity: medium · Enforcement: advisory

    Validates KMS key creation with appropriate specifications and origins

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure KMS Key with Proper Specifications

    Add a description, configure an appropriate deletion window (7-30 days), and ensure key specifications match your security requirements:

    const key = new aws.kms.Key("my-key", {
        description: "Key for encrypting application data", // Add clear description
        customerMasterKeySpec: "SYMMETRIC_DEFAULT", // Use approved key spec
        keyUsage: "ENCRYPT_DECRYPT", // Specify key usage
        deletionWindowInDays: 30, // Set deletion window between 7-30 days
        enableKeyRotation: true,
    });
    

    kms-key-deletion-lifecycle

    Severity: medium · Enforcement: advisory

    Validates KMS key deletion windows and lifecycle management

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure KMS Key Deletion Window and Lifecycle Management

    Set a deletionWindowInDays between 7 and 30 days, add descriptive tags, and provide a clear description for proper lifecycle management:

    const kmsKey = new aws.kms.Key("my-key", {
        description: "Encryption key for application data",
        deletionWindowInDays: 30, // Set deletion window between 7-30 days
        tags: {
            Environment: "production",
            Owner: "security-team",
            Purpose: "data-encryption",
        },
    });
    

    kms-key-enable-key-rotation

    Severity: medium · Enforcement: advisory

    Checks that KMS Keys have key rotation enabled.

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Enable Automatic Key Rotation for KMS Keys

    Set the enableKeyRotation property to true for all KMS keys to ensure cryptographic keys are automatically rotated annually:

    const key = new kms.Key("my-key", {
        description: "KMS key with automatic rotation",
        enableKeyRotation: true, // Enable automatic annual key rotation
    });
    

    lambda-concurrent-execution-limits-required

    Severity: low · Enforcement: advisory

    Lambda functions must have concurrent execution limits configured to protect resource availability

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Configure Reserved Concurrent Executions

    Set the reservedConcurrentExecutions property on your Lambda function to limit concurrent executions and prevent resource exhaustion.

    import * as aws from "@pulumi/aws";
    
    const myFunction = new aws.lambda.Function("myFunction", {
        runtime: "nodejs18.x",
        handler: "index.handler",
        role: lambdaRole.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./function"),
        }),
        // Set reserved concurrent executions to limit resource consumption
        reservedConcurrentExecutions: 10,
    });
    

    Choose a value based on your function’s expected load and account limits. Setting this prevents the function from consuming all available concurrency and impacting other functions in your account.

    lambda-dead-letter-queue-required

    Severity: medium · Enforcement: advisory

    Lambda functions must have dead letter queues configured for error handling and incident response

    • IR-4 Incident Handling — The organization implements incident handling capability for security incidents that includes preparation, detection and analysis, containment, eradication, and recovery.
    Remediation
    Fix: Configure Dead Letter Queue for Lambda Function

    Add a deadLetterConfig property to your Lambda function with a target SQS queue or SNS topic ARN to capture failed invocations for incident analysis.

    import * as aws from "@pulumi/aws";
    
    // Create a dead letter queue
    const dlq = new aws.sqs.Queue("my-function-dlq", {
        messageRetentionSeconds: 1209600, // 14 days
    });
    
    const lambdaFunction = new aws.lambda.Function("my-function", {
        runtime: "nodejs18.x",
        handler: "index.handler",
        role: lambdaRole.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./function"),
        }),
        // Add dead letter configuration to capture failed invocations
        deadLetterConfig: {
            targetArn: dlq.arn, // ARN of SQS queue or SNS topic
        },
    });
    

    lambda-public-access-restricted

    Severity: critical · Enforcement: advisory

    Lambda functions must restrict public access through resource-based policies

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Restrict Lambda Function Access to Specific Principals
    const lambdaFunction = new aws.lambda.Function("myFunction", {
        runtime: "nodejs18.x",
        handler: "index.handler",
        role: role.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./lambda"),
        }),
    });
    
    // Grant access to specific AWS service instead of wildcard
    new aws.lambda.Permission("apiGatewayInvoke", {
        action: "lambda:InvokeFunction",
        function: lambdaFunction.name,
        principal: "apigateway.amazonaws.com",  // Specify AWS service instead of "*"
        sourceArn: apiGateway.executionArn,
    });
    
    // Or grant access to specific AWS account
    new aws.lambda.Permission("crossAccountInvoke", {
        action: "lambda:InvokeFunction",
        function: lambdaFunction.name,
        principal: "123456789012",  // Specify AWS account ID instead of "*"
    });
    

    lambda-vpc-placement-required

    Severity: medium · Enforcement: advisory

    Lambda functions must be deployed in VPC for network isolation and security

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Lambda Function VPC Placement

    Add a vpcConfig to your Lambda function with subnet and security group configurations:

    import * as aws from "@pulumi/aws";
    
    const myFunction = new aws.lambda.Function("myFunction", {
        runtime: "nodejs18.x",
        handler: "index.handler",
        role: lambdaRole.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./function"),
        }),
        // Add VPC configuration for network isolation
        vpcConfig: {
            subnetIds: [
                privateSubnet1.id,  // Use at least 2 subnets for high availability
                privateSubnet2.id,
            ],
            securityGroupIds: [lambdaSecurityGroup.id],  // Specify security groups for access control
        },
    });
    

    limit-lambda-execution-time

    Severity: low · Enforcement: advisory

    Ensures that AWS Lambda functions are configured to time out after a specified duration to prevent extended access

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Configure Lambda Function Timeout

    Set the timeout property to limit function execution time (default maximum: 300 seconds):

    const myFunction = new aws.lambda.Function("my-function", {
        runtime: "nodejs20.x",
        handler: "index.handler",
        role: lambdaRole.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./app"),
        }),
        timeout: 300, // Set timeout to prevent extended access (max 300 seconds by default)
    });
    

    load-balancer-waf-association

    Severity: critical · Enforcement: advisory

    Ensures public-facing Load Balancers have WAF associations

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Associate WAF Web ACL with Load Balancer

    Create a WAF Web ACL association to protect your public-facing Load Balancer:

    // Create a WAF Web ACL association for the Load Balancer
    const wafAssociation = new aws.wafv2.WebAclAssociation("lb-waf-association", {
        resourceArn: loadBalancer.arn, // Reference the Load Balancer ARN
        webAclArn: webAcl.arn, // Reference the WAF Web ACL ARN
    });
    

    neptune-clusterinstance-managed-service-patching

    Severity: medium · Enforcement: advisory

    Ensures Neptune cluster instances have automated minor version upgrades enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Automatic Minor Version Upgrades for Neptune Cluster Instance

    Set the autoMinorVersionUpgrade property to true to enable automated patching for managed service security updates:

    const neptuneInstance = new aws.neptune.ClusterInstance("my-neptune-instance", {
        clusterIdentifier: neptuneCluster.id,
        instanceClass: "db.r5.large",
        engine: "neptune",
        autoMinorVersionUpgrade: true, // Enable automatic minor version upgrades
    });
    

    neptune-clusterinstance-no-public-access

    Severity: critical · Enforcement: advisory

    Checks that Neptune Cluster Instances public access is not enabled.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Public Access for Neptune Cluster Instance

    Set the publiclyAccessible property to false:

    const neptuneInstance = new aws.neptune.ClusterInstance("neptune-instance", {
        clusterIdentifier: neptuneCluster.id,
        instanceClass: "db.r5.large",
        engine: "neptune",
        publiclyAccessible: false,  // Disable public access
    });
    

    no-direct-user-access-keys

    Severity: high · Enforcement: advisory

    Prevents creation of direct IAM user access keys for human users

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Use IAM Roles Instead of Access Keys

    Remove the IAM access key resource and use IAM roles with temporary credentials instead:

    // Remove this - do not create IAM access keys
    // const accessKey = new aws.iam.AccessKey("user-key", {
    //     user: user.name,
    // });
    
    // Instead, use IAM roles for workloads
    const role = new aws.iam.Role("app-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { Service: "ec2.amazonaws.com" }, // Use appropriate service
                Action: "sts:AssumeRole",
            }],
        }),
    });
    
    // Attach necessary policies to the role
    new aws.iam.RolePolicyAttachment("app-policy", {
        role: role.name,
        policyArn: "arn:aws:iam::aws:policy/ReadOnlyAccess", // Use least-privilege policy
    });
    
    // For human users, use AWS SSO or federated identity instead of access keys
    

    pubsub-least-privilege-iam

    Severity: medium · Enforcement: advisory

    Ensures IAM policies follow least privilege principles for Pub/Sub services (SNS, SQS, Kinesis)

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Specific Pub/Sub IAM Actions and Resource ARNs

    Replace wildcard permissions with specific actions and resource ARNs for Pub/Sub services:

    const queuePolicy = new aws.iam.Policy("queue-policy", {
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Action: [
                    "sqs:SendMessage",      // Use specific actions instead of sqs:*
                    "sqs:ReceiveMessage",
                    "sqs:DeleteMessage",
                ],
                Resource: "arn:aws:sqs:us-east-1:123456789012:my-queue", // Use specific ARN instead of *
            }],
        }),
    });
    

    rds-audit-logging

    Severity: medium · Enforcement: advisory

    Ensures RDS instances have audit logging enabled

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable RDS Audit Logging to CloudWatch

    Configure enabledCloudwatchLogsExports with appropriate audit log types for your database engine:

    // For MySQL/MariaDB
    const db = new aws.rds.Instance("my-db", {
        engine: "mysql",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        enabledCloudwatchLogsExports: ["audit", "error", "general", "slowquery"], // Enable audit logs
        // ... other configuration
    });
    
    // For PostgreSQL
    const pgDb = new aws.rds.Instance("my-pg-db", {
        engine: "postgres",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        enabledCloudwatchLogsExports: ["postgresql"], // Enable PostgreSQL logs
        // ... other configuration
    });
    
    // For Aurora clusters
    const cluster = new aws.rds.Cluster("my-cluster", {
        engine: "aurora-mysql",
        enabledCloudwatchLogsExports: ["audit", "error", "general", "slowquery"], // Enable audit logs
        // ... other configuration
    });
    

    rds-cluster-disallow-single-availability-zone

    Severity: high · Enforcement: advisory

    Check that RDS Cluster doesn’t use single availability zone.

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure Multiple Availability Zones for RDS Cluster

    Specify at least two availability zones in the availabilityZones property to ensure high availability and resilience:

    const cluster = new rds.Cluster("my-cluster", {
        engine: "aurora-mysql",
        engineVersion: "8.0.mysql_aurora.3.04.0",
        availabilityZones: ["us-east-1a", "us-east-1b"], // Configure at least two AZs
        databaseName: "mydb",
        masterUsername: "admin",
        masterPassword: dbPassword,
        skipFinalSnapshot: true,
    });
    

    rds-cluster-disallow-unencrypted-storage

    Severity: high · Enforcement: advisory

    Checks that RDS Clusters storage is encrypted.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable RDS Cluster Storage Encryption

    Set the storageEncrypted property to true to enable encryption at rest for the RDS cluster:

    const cluster = new aws.rds.Cluster("my-cluster", {
        engine: "aurora-mysql",
        engineVersion: "8.0.mysql_aurora.3.02.0",
        masterUsername: "admin",
        masterPassword: dbPassword,
        storageEncrypted: true, // Enable storage encryption
        databaseName: "mydb",
        skipFinalSnapshot: true,
    });
    

    rds-cluster-enable-backup-retention

    Severity: medium · Enforcement: advisory

    Checks that RDS Clusters backup retention policy is enabled.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable RDS Cluster Backup Retention

    Set the backupRetentionPeriod to a value between 1 and 35 days to enable automated backups:

    const cluster = new rds.Cluster("my-cluster", {
        engine: "aurora-mysql",
        masterUsername: "admin",
        masterPassword: dbPassword,
        backupRetentionPeriod: 7, // Enable backup retention (1-35 days)
        preferredBackupWindow: "03:00-04:00",
    });
    

    rds-cluster-instance-disallow-public-access

    Severity: critical · Enforcement: advisory

    Checks that RDS Cluster Instances public access is not enabled.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Public Access for RDS Cluster Instance

    Set the publiclyAccessible property to false to ensure the RDS Cluster Instance is not accessible from the public internet:

    const clusterInstance = new aws.rds.ClusterInstance("my-cluster-instance", {
        clusterIdentifier: cluster.id,
        instanceClass: "db.r5.large",
        engine: "aurora-postgresql",
        publiclyAccessible: false, // Disable public access
    });
    

    rds-cluster-logging-enabled

    Severity: medium · Enforcement: advisory

    Ensure RDS clusters have logging enabled for monitoring and audit compliance.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable CloudWatch logs exports

    For Aurora clusters (logging is configured at the cluster level, applies to all cluster instances):

    const cluster = new aws.rds.Cluster("myCluster", {
        engine: "aurora-postgresql",
        enabledCloudwatchLogsExports: ["postgresql"],  // This fixes the violation
    });
    

    Note: For Aurora databases, configure logging on the rds.Cluster resource. All cluster instances inherit this configuration.

    rds-clusterinstance-enhanced-monitoring

    Severity: medium · Enforcement: advisory

    RDS cluster instances must have enhanced monitoring enabled to provide detailed system-level metrics

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Enable RDS Cluster Instance Enhanced Monitoring

    Configure the RDS cluster instance with monitoringInterval and monitoringRoleArn to enable enhanced monitoring:

    import * as aws from "@pulumi/aws";
    
    // Create IAM role for RDS enhanced monitoring
    const monitoringRole = new aws.iam.Role("rds-monitoring-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Action: "sts:AssumeRole",
                Principal: { Service: "monitoring.rds.amazonaws.com" },
                Effect: "Allow",
            }],
        }),
    });
    
    new aws.iam.RolePolicyAttachment("rds-monitoring-policy", {
        role: monitoringRole.name,
        policyArn: "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole",
    });
    
    const clusterInstance = new aws.rds.ClusterInstance("my-cluster-instance", {
        clusterIdentifier: cluster.id,
        instanceClass: "db.r5.large",
        engine: cluster.engine,
        monitoringInterval: 60, // Valid values: 0, 1, 5, 10, 15, 30, 60
        monitoringRoleArn: monitoringRole.arn, // Required for enhanced monitoring
    });
    

    rds-clusterinstance-managed-service-patching

    Severity: medium · Enforcement: advisory

    Ensures RDS cluster instances have automated minor version upgrades enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Automatic Minor Version Upgrades for Aurora Cluster Instance

    Set the autoMinorVersionUpgrade property to true to enable automated patching for managed service security updates:

    const clusterInstance = new aws.rds.ClusterInstance("my-cluster-instance", {
        clusterIdentifier: cluster.id,
        instanceClass: "db.r5.large",
        engine: cluster.engine,
        autoMinorVersionUpgrade: true, // Enable automatic minor version upgrades
    });
    

    rds-clusterinstance-ssl-encryption

    Severity: high · Enforcement: advisory

    Ensures RDS cluster instances have SSL/TLS encryption enabled through parameter group configuration

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure SSL/TLS Encryption for Aurora Cluster Instance

    Configure a parameter group to enforce SSL/TLS connections for your Aurora cluster instance:

    const clusterParamGroup = new aws.rds.ParameterGroup("cluster-params", {
        family: "aurora-postgresql14",
        parameters: [
            {
                name: "rds.force_ssl",
                value: "1", // Enforce SSL/TLS for all connections
            },
        ],
    });
    
    const clusterInstance = new aws.rds.ClusterInstance("my-cluster-instance", {
        clusterIdentifier: cluster.id,
        instanceClass: "db.r5.large",
        engine: cluster.engine,
        dbParameterGroupName: clusterParamGroup.name, // Attach parameter group with SSL enforcement
    });
    

    rds-deletion-protection

    Severity: medium · Enforcement: advisory

    RDS database instances must have deletion protection enabled to prevent accidental deletion and ensure data availability

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Enable RDS Deletion Protection

    Set the deletionProtection property to true on your RDS instance:

    import * as aws from "@pulumi/aws";
    
    const db = new aws.rds.Instance("myDatabase", {
        engine: "postgres",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        deletionProtection: true,  // Enable deletion protection
        // ... other configuration
    });
    

    rds-instance-disallow-public-access

    Severity: critical · Enforcement: advisory

    Checks that RDS Instance public access is not enabled.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Public Access for RDS Instance

    Set publiclyAccessible to false to prevent the RDS instance from being accessible from the internet:

    const dbInstance = new aws.rds.Instance("my-database", {
        allocatedStorage: 20,
        engine: "mysql",
        engineVersion: "8.0",
        instanceClass: "db.t3.micro",
        dbSubnetGroupName: privateSubnetGroup.name,
        vpcSecurityGroupIds: [dbSecurityGroup.id],
        publiclyAccessible: false, // Disable public access
        username: dbUsername,
        password: dbPassword,
    });
    

    rds-instance-disallow-unencrypted-storage

    Severity: high · Enforcement: advisory

    Checks that RDS instance storage is encrypted.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable RDS Storage Encryption

    Set the storageEncrypted property to true to encrypt the RDS instance storage:

    const dbInstance = new aws.rds.Instance("my-db", {
        engine: "postgres",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        storageEncrypted: true, // Enable storage encryption
        username: "admin",
        password: adminPassword,
    });
    

    rds-instance-enable-backup-retention

    Severity: medium · Enforcement: advisory

    Checks that RDS Instances backup retention policy is enabled.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable Backup Retention for RDS Instance

    Set the backupRetentionPeriod to a value between 1 and 35 days to enable automated backups:

    const dbInstance = new aws.rds.Instance("my-db", {
        engine: "mysql",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        backupRetentionPeriod: 7, // Enable backup retention (1-35 days)
        username: "admin",
        password: dbPassword,
    });
    

    rds-instance-enhanced-monitoring

    Severity: medium · Enforcement: advisory

    RDS database instances must have enhanced monitoring enabled to provide detailed system-level metrics

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Enable RDS Instance Enhanced Monitoring

    Configure the RDS instance with monitoringInterval and monitoringRoleArn to enable enhanced monitoring:

    import * as aws from "@pulumi/aws";
    
    // Create IAM role for RDS enhanced monitoring
    const monitoringRole = new aws.iam.Role("rds-monitoring-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Action: "sts:AssumeRole",
                Principal: { Service: "monitoring.rds.amazonaws.com" },
                Effect: "Allow",
            }],
        }),
    });
    
    new aws.iam.RolePolicyAttachment("rds-monitoring-policy", {
        role: monitoringRole.name,
        policyArn: "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole",
    });
    
    const db = new aws.rds.Instance("my-database", {
        engine: "postgres",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        // Enable enhanced monitoring with 60-second interval
        monitoringInterval: 60, // Valid values: 0, 1, 5, 10, 15, 30, 60
        monitoringRoleArn: monitoringRole.arn, // Required for enhanced monitoring
    });
    

    rds-instance-high-availability

    Severity: medium · Enforcement: advisory

    Ensures RDS instances have Multi-AZ deployment enabled for high availability

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Enable Multi-AZ Deployment for RDS Instance

    Set the multiAz property to true to enable automatic failover to a standby replica in a different Availability Zone:

    const dbInstance = new aws.rds.Instance("my-database", {
        allocatedStorage: 20,
        engine: "mysql",
        engineVersion: "8.0",
        instanceClass: "db.t3.micro",
        username: "admin",
        password: dbPassword,
        multiAz: true, // Enable Multi-AZ deployment for high availability
        skipFinalSnapshot: true,
    });
    

    rds-instance-managed-service-patching

    Severity: medium · Enforcement: advisory

    Ensures RDS instances have automated minor version upgrades enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Automatic Minor Version Upgrades for RDS

    Set the autoMinorVersionUpgrade property to true to enable automated patching for managed service security updates:

    const db = new aws.rds.Instance("my-database", {
        engine: "postgres",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        dbName: "mydb",
        username: "admin",
        password: dbPassword,
        autoMinorVersionUpgrade: true, // Enable automatic minor version upgrades
        skipFinalSnapshot: true,
    });
    

    rds-instance-ssl-encryption

    Severity: high · Enforcement: advisory

    Ensures RDS instances have SSL/TLS encryption enabled through parameter group configuration

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure SSL/TLS Encryption for RDS Instance

    Configure a parameter group to enforce SSL/TLS connections for your RDS instance:

    const dbParamGroup = new aws.rds.ParameterGroup("db-params", {
        family: "mysql8.0",
        parameters: [
            {
                name: "require_secure_transport",
                value: "1", // Enforce SSL/TLS for all connections
            },
        ],
    });
    
    const db = new aws.rds.Instance("my-database", {
        engine: "mysql",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        parameterGroupName: dbParamGroup.name, // Attach parameter group with SSL enforcement
        username: "admin",
        password: dbPassword,
    });
    

    redshift-automatic-snapshots-required

    Severity: medium · Enforcement: advisory

    Ensures Redshift clusters have automatic snapshots enabled with minimum 7-day retention period.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable Automatic Snapshots with Minimum Retention Period

    Set the automatedSnapshotRetentionPeriod property to at least 7 days on your Redshift cluster:

    import * as aws from "@pulumi/aws";
    
    const cluster = new aws.redshift.Cluster("myCluster", {
        clusterIdentifier: "my-redshift-cluster",
        nodeType: "dc2.large",
        numberOfNodes: 2,
        // Enable automatic snapshots with minimum 7-day retention
        automatedSnapshotRetentionPeriod: 7,
    });
    

    redshift-enhanced-vpc-routing-enabled

    Severity: medium · Enforcement: advisory

    Ensures Redshift clusters have enhanced VPC routing enabled for network isolation.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Enable Enhanced VPC Routing

    Set the enhancedVpcRouting property to true on your Redshift cluster to ensure all COPY and UNLOAD traffic flows through your VPC infrastructure.

    const cluster = new aws.redshift.Cluster("my-cluster", {
        clusterIdentifier: "my-cluster",
        // ... other configuration ...
        enhancedVpcRouting: true, // Enable enhanced VPC routing for network isolation
    });
    

    redshift-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures Redshift clusters have encryption enabled using KMS keys.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Encryption at Rest for Redshift Cluster

    Enable encryption on your Redshift cluster by setting the ’encrypted’ property to true and providing a customer-managed KMS key.

    import * as aws from "@pulumi/aws";
    
    const cluster = new aws.redshift.Cluster("my-cluster", {
        clusterIdentifier: "my-redshift-cluster",
        encrypted: true, // Enable encryption at rest
        kmsKeyId: kmsKey.arn, // Use a customer-managed KMS key
        // ... other configuration
    });
    

    If you only need AWS managed encryption (not recommended), you can set ’encrypted’ to true without specifying ‘kmsKeyId’, but you must configure the policy to allow this by setting ‘requireCustomKMSKey’ to false in the policy configuration.

    redshift-logging-enabled

    Severity: medium · Enforcement: advisory

    Ensures Redshift clusters have logging configurations enabled for audit and monitoring purposes.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Redshift cluster logging

    Create a redshift.Logging resource to enable audit logging for your Redshift cluster. Configure either S3 or CloudWatch as the log destination to capture connection logs and user activity logs.

    import * as aws from "@pulumi/aws";
    
    const cluster = new aws.redshift.Cluster("my-cluster", {
        clusterIdentifier: "my-redshift-cluster",
        // ... other cluster configuration
    });
    
    // Add logging configuration for the cluster
    const clusterLogging = new aws.redshift.Logging("my-cluster-logging", {
        clusterIdentifier: cluster.clusterIdentifier,
        logDestinationType: "s3", // or "cloudwatch"
        bucketName: "my-audit-logs-bucket", // Required for S3 destination
        s3KeyPrefix: "redshift-logs/", // Optional: organize logs with prefix
        logExports: ["connectionlog", "useractivitylog"], // Enable audit log types
    });
    

    redshift-maintenance-required

    Severity: medium · Enforcement: advisory

    Ensures Redshift clusters have proper maintenance settings configured for automated updates.

    • CM-3 Configuration Change Control — The organization determines the types of changes to the information system that are configuration-controlled.
    Remediation
    Fix: Configure Redshift Maintenance Settings

    Add a preferred maintenance window and enable automatic version upgrades to allow automated security updates and system baseline changes.

    const cluster = new aws.redshift.Cluster("my-cluster", {
        clusterIdentifier: "my-redshift-cluster",
        // ... other configuration ...
    
        // Configure maintenance window for automated updates
        preferredMaintenanceWindow: "sun:05:00-sun:06:00", // Weekly maintenance window
    
        // Enable automatic version upgrades for security patches
        allowVersionUpgrade: true,
    });
    

    redshift-public-access-prohibited

    Severity: critical · Enforcement: advisory

    Ensures Redshift clusters prohibit public access to prevent unauthorized connections.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Public Access for Redshift Cluster
    const cluster = new aws.redshift.Cluster("data-warehouse", {
        clusterIdentifier: "my-cluster",
        nodeType: "dc2.large",
        masterUsername: "admin",
        masterPassword: password.result,
        publiclyAccessible: false,  // Disable public access to prevent internet exposure
        vpcSecurityGroupIds: [securityGroup.id],
        clusterSubnetGroupName: subnetGroup.name,
    });
    

    redshift-ssl-required

    Severity: high · Enforcement: advisory

    Ensures Redshift clusters have encryption in transit enabled through SSL parameter configuration.

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable SSL/TLS encryption for Redshift cluster connections

    Create a parameter group with require_ssl set to true and associate it with your Redshift cluster:

    import * as aws from "@pulumi/aws";
    
    // Create parameter group with SSL requirement
    const parameterGroup = new aws.redshift.ParameterGroup("secure-parameter-group", {
        family: "redshift-1.0",
        parameters: [
            {
                name: "require_ssl",
                value: "true", // Enable SSL/TLS encryption in transit
            },
        ],
    });
    
    // Associate parameter group with Redshift cluster
    const cluster = new aws.redshift.Cluster("my-cluster", {
        clusterIdentifier: "my-secure-cluster",
        clusterParameterGroupName: parameterGroup.name, // Reference the secure parameter group
        // ... other cluster configuration
    });
    

    s3-bucket-access-logging

    Severity: medium · Enforcement: advisory

    Ensures each S3 bucket has access logging enabled

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable S3 Bucket Access Logging

    Create a BucketLogging resource with a target bucket and prefix to enable access logging:

    const myBucket = new aws.s3.Bucket("my-bucket", {
        // Bucket configuration
    });
    
    const logBucket = new aws.s3.Bucket("log-bucket", {
        // Configure log bucket settings
    });
    
    const bucketLogging = new aws.s3.BucketLogging("my-bucket-logging", {
        bucket: myBucket.id,
        targetBucket: logBucket.id, // Specify target bucket for logs
        targetPrefix: "logs/my-bucket/", // Specify prefix for organization
    });
    

    s3-bucket-disallow-public-read

    Severity: critical · Enforcement: advisory

    Checks that S3 Bucket ACLs don’t allow ‘public-read’ or ‘public-read-write’ or ‘authenticated-read’.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Use Private ACL for S3 Bucket

    Set the acl to “private” or omit it entirely (defaults to private) to prevent public read access:

    const bucket = new aws.s3.Bucket("my-bucket", {
        acl: "private", // Use private ACL instead of public-read/public-read-write/authenticated-read
        // Or omit the acl property to use the default private setting
    });
    

    s3-bucket-encryption

    Severity: high · Enforcement: advisory

    S3 buckets must have server-side encryption configured using BucketServerSideEncryptionConfiguration resource

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure S3 Bucket Server-Side Encryption

    Create a separate BucketServerSideEncryptionConfigurationV2 resource for your S3 bucket with encryption rules. Use AES256 or KMS encryption:

    const bucket = new aws.s3.BucketV2("my-bucket", {
        bucket: "my-secure-bucket",
    });
    
    // Add encryption configuration resource
    const bucketEncryption = new aws.s3.BucketServerSideEncryptionConfiguration("my-bucket-encryption", {
        bucket: bucket.id,
        rules: [{
            applyServerSideEncryptionByDefault: {
                sseAlgorithm: "aws:kms", // Enable KMS encryption
                kmsMasterKeyId: kmsKey.arn, // Specify customer-managed key
            },
            bucketKeyEnabled: true, // Enable bucket key for cost optimization
        }],
    });
    

    s3-bucket-least-privilege

    Severity: critical · Enforcement: advisory

    Prevents overly permissive S3 bucket policies

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Specific Actions, Resources, and Principals

    Replace wildcard (*) values in S3 bucket policy statements with specific, scoped permissions:

    const bucketPolicy = new aws.s3.BucketPolicy("policy", {
        bucket: bucket.id,
        policy: bucket.arn.apply(arn => JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    AWS: "arn:aws:iam::123456789012:role/specific-role" // Specify exact principal ARN
                },
                Action: ["s3:GetObject", "s3:PutObject"], // Use specific S3 actions
                Resource: `${arn}/*` // Scope to specific bucket
            }]
        }))
    });
    

    s3-bucket-lifecycle

    Severity: medium · Enforcement: advisory

    Ensures each S3 bucket has lifecycle rules configured for retention/disposal

    • MP-6 Media Sanitization — The organization sanitizes information system media, both paper and digital, prior to disposal, release out of organizational control, or release for reuse.
    Remediation
    Fix: Configure Lifecycle Rules for S3 Bucket

    Create a BucketLifecycleConfiguration resource with at least one enabled rule:

    const myBucket = new aws.s3.Bucket("my-bucket", {
        // Bucket configuration
    });
    
    const lifecycleConfig = new aws.s3.BucketLifecycleConfiguration("my-bucket-lifecycle", {
        bucket: myBucket.id,
        rules: [
            {
                id: "delete-old-objects",
                status: "Enabled", // Rule must be enabled
                expiration: {
                    days: 90, // Define retention period (e.g., expire after 90 days)
                },
            },
        ],
    });
    

    s3-bucket-notifications-enabled

    Severity: medium · Enforcement: advisory

    S3 buckets must have event notifications enabled to alert personnel of important bucket activities

    • AU-5 Response to Audit Processing Failures — The information system alerts designated organizational officials in the event of an audit processing failure and takes additional actions.
    Remediation
    Fix: Enable S3 Bucket Event Notifications

    Configure event notifications for your S3 bucket to alert personnel of important activities:

    import * as aws from "@pulumi/aws";
    
    const bucket = new aws.s3.BucketV2("my-bucket", {
        bucket: "my-bucket-name"
    });
    
    // Create an SNS topic for notifications
    const topic = new aws.sns.Topic("bucket-notifications", {
        name: "s3-bucket-notifications"
    });
    
    // Enable bucket notifications with SNS, SQS, Lambda, or EventBridge
    const bucketNotification = new aws.s3.BucketNotification("bucket-notification", {
        bucket: bucket.id,
        topics: [{
            topicArn: topic.arn,
            events: [
                "s3:ObjectCreated:*",    // Alert on object creation
                "s3:ObjectRemoved:*",    // Alert on object deletion
            ],
        }],
    });
    

    s3-bucket-object-lock-enabled

    Severity: medium · Enforcement: advisory

    S3 buckets must have object lock enabled to protect audit information and prevent unauthorized deletion

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Enable S3 Bucket Object Lock with Retention Rules

    Configure object lock on your S3 bucket to enable write-once-read-many (WORM) protection for audit data:

    import * as aws from "@pulumi/aws";
    
    const auditBucket = new aws.s3.BucketV2("audit-logs", {
        bucket: "my-audit-logs",
        objectLockEnabled: true, // Enable object lock on bucket creation
    });
    
    new aws.s3.BucketObjectLockConfigurationV2("audit-logs-lock-config", {
        bucket: auditBucket.id,
        objectLockEnabled: "Enabled", // Explicitly enable object lock
        rule: {
            defaultRetention: {
                mode: "COMPLIANCE", // Use COMPLIANCE for immutable protection
                days: 90, // Retain objects for 90 days minimum
            },
        },
    });
    

    Note: Object lock can only be enabled during bucket creation. If you need to enable it on an existing bucket, you must create a new bucket with object lock enabled and migrate your data.

    s3-bucket-public-access-block

    Severity: critical · Enforcement: advisory

    Ensures each S3 bucket has a public access block with all settings enabled

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Enable All Public Access Block Settings

    Create a BucketPublicAccessBlock resource with all four settings set to true:

    const myBucket = new aws.s3.Bucket("my-bucket", {
        // Bucket configuration
    });
    
    const publicAccessBlock = new aws.s3.BucketPublicAccessBlock("my-bucket-public-access-block", {
        bucket: myBucket.id,
        blockPublicAcls: true,       // Blocks new public ACLs
        blockPublicPolicy: true,     // Blocks new public bucket policies
        ignorePublicAcls: true,      // Ignores existing public ACLs
        restrictPublicBuckets: true, // Restricts public access to buckets with public policies
    });
    

    s3-bucket-replication

    Severity: medium · Enforcement: advisory

    Ensures S3 buckets have replication configured for enhanced availability

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Replication for S3 Bucket

    Create a BucketReplicationConfig resource with an IAM role and replication rules:

    // Create destination bucket
    const destBucket = new aws.s3.Bucket("dest-bucket", {
        bucket: "my-dest-bucket",
    });
    
    // Create replication IAM role
    const replicationRole = new aws.iam.Role("replication-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { Service: "s3.amazonaws.com" },
                Action: "sts:AssumeRole",
            }],
        }),
    });
    
    // Enable versioning on source bucket (required for replication)
    const sourceBucketVersioning = new aws.s3.BucketVersioning("source-versioning", {
        bucket: sourceBucket.id,
        versioningConfiguration: { status: "Enabled" },
    });
    
    // Configure replication using BucketReplicationConfig
    const replication = new aws.s3.BucketReplicationConfig("replication", {
        bucket: sourceBucket.id,
        role: replicationRole.arn,
        rules: [{
            id: "replicate-all",
            status: "Enabled",
            destination: {
                bucket: destBucket.arn,
            },
            filter: {},
        }],
    }, { dependsOn: [sourceBucketVersioning] });
    

    s3-bucket-ssl-enforcement-required

    Severity: high · Enforcement: advisory

    S3 buckets must enforce SSL/TLS for all requests to ensure encryption in transit

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Add Bucket Policy to Enforce SSL/TLS

    Add a bucket policy that denies all requests made without SSL/TLS encryption:

    import * as aws from "@pulumi/aws";
    
    const bucket = new aws.s3.BucketV2("my-bucket", {
        bucket: "my-secure-bucket",
    });
    
    // Add bucket policy to enforce SSL/TLS
    const bucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", {
        bucket: bucket.id,
        policy: bucket.arn.apply(arn => JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Sid: "DenyInsecureTransport",
                Effect: "Deny",
                Principal: "*",
                Action: "s3:*",
                Resource: [
                    arn,
                    `${arn}/*`,
                ],
                Condition: {
                    Bool: {
                        "aws:SecureTransport": "false"  // Deny when SecureTransport is false
                    }
                }
            }]
        }))
    });
    

    s3-bucket-versioning

    Severity: medium · Enforcement: advisory

    S3 buckets must have versioning enabled using BucketVersioning resource

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable S3 Bucket Versioning

    Create a separate BucketVersioning resource with status set to “Enabled” for each S3 bucket:

    const bucket = new aws.s3.BucketV2("my-bucket", {
        bucket: "my-data-bucket",
    });
    
    const versioning = new aws.s3.BucketVersioning("my-bucket-versioning", {
        bucket: bucket.id,
        versioningConfiguration: {
            status: "Enabled", // Enable versioning for data integrity and recovery
        },
    });
    

    sagemaker-endpoint-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures SageMaker endpoint configurations have encryption enabled using KMS keys.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable KMS encryption for SageMaker endpoint configuration

    Add the kmsKeyArn property to your SageMaker endpoint configuration to enable encryption at rest:

    const endpointConfig = new aws.sagemaker.EndpointConfiguration("example", {
        productionVariants: [{
            modelName: model.name,
            initialInstanceCount: 1,
            instanceType: "ml.t2.medium",
        }],
        kmsKeyArn: kmsKey.arn, // Add KMS key ARN to enable encryption at rest
    });
    

    sagemaker-notebook-internet-access-disabled

    Severity: high · Enforcement: advisory

    Ensures SageMaker notebook instances have direct internet access disabled.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Direct Internet Access
    const notebookInstance = new aws.sagemaker.NotebookInstance("ml-notebook", {
        instanceType: "ml.t3.medium",
        roleArn: role.arn,
        directInternetAccess: "Disabled",  // Disable direct internet access
        subnetId: subnet.id,  // Must specify subnet when internet access is disabled
        securityGroups: [securityGroup.id],  // Control network access via security groups
    });
    

    sagemaker-notebook-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures SageMaker notebook instances have encryption enabled using KMS keys.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable KMS encryption for SageMaker notebook instance

    Add the kmsKeyId property to your SageMaker notebook instance configuration to enable encryption at rest:

    import * as aws from "@pulumi/aws";
    
    const notebookInstance = new aws.sagemaker.NotebookInstance("example", {
        name: "my-notebook",
        instanceType: "ml.t2.medium",
        roleArn: role.arn,
        kmsKeyId: kmsKey.id, // Add KMS key ID to enable encryption at rest
    });
    

    secrets-manager-rotation-required

    Severity: medium · Enforcement: advisory

    Ensures Secrets Manager secrets have automatic rotation enabled with proper scheduling and frequency limits.

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Enable Automatic Rotation for Secrets Manager Secret

    Configure a SecretRotation resource with rotation rules to automatically rotate your secret credentials at regular intervals.

    import * as aws from "@pulumi/aws";
    
    const mySecret = new aws.secretsmanager.Secret("mySecret", {
        name: "my-database-credentials",
    });
    
    // Create rotation configuration with Lambda function
    const rotationLambda = new aws.lambda.Function("rotationLambda", {
        // Lambda function configuration for rotation
    });
    
    // Add automatic rotation to the secret
    const secretRotation = new aws.secretsmanager.SecretRotation("mySecretRotation", {
        secretId: mySecret.id,
        rotationLambdaArn: rotationLambda.arn,
        rotationRules: {
            automaticallyAfterDays: 30, // Rotate every 30 days (must be <= configured maximum)
            // Or use scheduleExpression: "cron(0 0 1 * ? *)" for cron-based rotation
        },
    });
    

    secrets-manager-secret-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Check that Secrets Manager Secrets use a customer-manager KMS key.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Customer-Managed KMS Key for Secrets Manager Secret

    Set the kmsKeyId property to reference a customer-managed KMS key for encrypting the secret:

    const secret = new aws.secretsmanager.Secret("my-secret", {
        name: "my-application-secret",
        kmsKeyId: kmsKey.arn, // Use customer-managed KMS key
        description: "Sensitive application credentials",
    });
    

    security-group-default-deny

    Severity: high · Enforcement: advisory

    Ensures Security Groups follow default deny with explicit allow principle

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Replace Unrestricted CIDR Blocks with Specific IP Ranges

    Replace 0.0.0.0/0 in ingress and egress rules with specific CIDR blocks or security group references to follow the default deny with explicit allow principle:

    const webSecurityGroup = new aws.ec2.SecurityGroup("web-sg", {
        vpcId: vpc.id,
        ingress: [{
            protocol: "tcp",
            fromPort: 443,
            toPort: 443,
            cidrBlocks: ["10.0.0.0/16"], // Use specific CIDR block instead of 0.0.0.0/0
        }],
        egress: [{
            protocol: "tcp",
            fromPort: 443,
            toPort: 443,
            cidrBlocks: ["10.0.0.0/16"], // Use specific CIDR block instead of 0.0.0.0/0
        }],
    });
    

    security-group-ssh-rdp

    Severity: critical · Enforcement: advisory

    Ensures security groups do not allow SSH/RDP from the internet

    • AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.
    Remediation
    Fix: Remove Public SSH and RDP Access

    Remove or restrict ingress rules that allow SSH (port 22) or RDP (port 3389) from 0.0.0.0/0. Use specific CIDR blocks for trusted networks or implement alternative secure access methods:

    const securityGroup = new aws.ec2.SecurityGroup("my-sg", {
        vpcId: vpc.id,
        ingress: [
            {
                fromPort: 22,
                toPort: 22,
                protocol: "tcp",
                cidrBlocks: ["10.0.0.0/16"], // Restrict to specific network, not 0.0.0.0/0
            },
            {
                fromPort: 3389,
                toPort: 3389,
                protocol: "tcp",
                cidrBlocks: ["10.0.0.0/16"], // Restrict to specific network, not 0.0.0.0/0
            },
        ],
    });
    

    security-group-strict

    Severity: high · Enforcement: advisory

    Ensures security groups follow strict firewall rules with default deny

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Strict Security Group Rules

    Restrict ingress rules to specific CIDR blocks instead of allowing access from the entire internet (0.0.0.0/0). Use specific protocols and narrow port ranges:

    const securityGroup = new aws.ec2.SecurityGroup("my-sg", {
        vpcId: vpc.id,
        ingress: [
            {
                protocol: "tcp", // Use specific protocol, not "-1" (all)
                fromPort: 443,
                toPort: 443,
                cidrBlocks: ["10.0.0.0/8"], // Restrict to internal network, not "0.0.0.0/0"
            },
        ],
        egress: [
            {
                protocol: "-1",
                fromPort: 0,
                toPort: 0,
                cidrBlocks: ["0.0.0.0/0"],
            },
        ],
    });
    

    security-hub-enabled

    Severity: high · Enforcement: advisory

    Ensures AWS Security Hub is enabled for continuous monitoring and security assessment.

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Enable AWS Security Hub

    Add an AWS Security Hub Account resource to your Pulumi program to enable continuous monitoring:

    import * as aws from "@pulumi/aws";
    
    // Enable Security Hub for continuous monitoring
    const securityHub = new aws.securityhub.Account("security-hub", {
        // Security Hub will be enabled in the current region
    });
    

    shield-advanced-enabled

    Severity: high · Enforcement: advisory

    Ensures AWS Shield Advanced is enabled for DDoS protection.

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Enable AWS Shield Advanced Subscription

    Add an AWS Shield Advanced subscription to your Pulumi stack:

    import * as aws from "@pulumi/aws";
    
    // Enable Shield Advanced for DDoS protection
    const shieldSubscription = new aws.shield.Subscription("shield-advanced", {
        autoRenew: "ENABLED", // Automatically renew the subscription
    });
    

    sns-kms-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensures SNS topics have encryption enabled using KMS keys.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable KMS encryption for SNS topic

    Add the kmsMasterKeyId property to your SNS topic to enable encryption at rest using a KMS key.

    const myTopic = new aws.sns.Topic("myTopic", {
        name: "my-topic",
        kmsMasterKeyId: "alias/aws/sns", // Add KMS key ID or ARN for encryption
    });
    

    sqs-dead-letter-queue

    Severity: medium · Enforcement: advisory

    Ensures SQS queues have dead letter queue configuration

    • AU-5 Response to Audit Processing Failures — The information system alerts designated organizational officials in the event of an audit processing failure and takes additional actions.
    Remediation
    Fix: Configure Dead Letter Queue for SQS Queue

    Set the redrivePolicy with a deadLetterTargetArn pointing to a DLQ and specify maxReceiveCount to capture failed messages:

    // Create a dead letter queue first
    const dlq = new aws.sqs.Queue("my-dlq", {
        messageRetentionSeconds: 1209600, // 14 days
    });
    
    // Configure the main queue with redrive policy
    const queue = new aws.sqs.Queue("my-queue", {
        redrivePolicy: pulumi.interpolate`{
            "deadLetterTargetArn": "${dlq.arn}",
            "maxReceiveCount": 3
        }`, // Configure DLQ to capture messages that fail processing
        messageRetentionSeconds: 345600,
    });
    

    sqs-encryption

    Severity: high · Enforcement: advisory

    Ensures SQS queues have server-side encryption enabled

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Server-Side Encryption for SQS Queue

    Set the kmsMasterKeyId property to enable server-side encryption with AWS KMS:

    const queue = new aws.sqs.Queue("my-queue", {
        name: "my-secure-queue",
        kmsMasterKeyId: "alias/aws/sqs", // Enable encryption with AWS-managed KMS key
        // Or use a customer-managed key:
        // kmsMasterKeyId: customerKey.arn,
    });
    

    vpc-flow-logs

    Severity: medium · Enforcement: advisory

    Ensures VPC flow logs use approved destinations for centralized monitoring

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Configure VPC Flow Logs with Approved Destination

    Configure VPC Flow Logs to use one of the approved log destinations specified in the policy configuration:

    const flowLog = new aws.ec2.FlowLog("vpc-flow-log", {
        vpcId: vpc.id,
        trafficType: "ALL",
        logDestination: "arn:aws:s3:::approved-logging-bucket", // Use approved destination
        logDestinationType: "s3",
    });
    

    vpc-peering-dns-resolution-enabled

    Severity: low · Enforcement: advisory

    Ensures VPC peering connections have DNS resolution enabled for proper name resolution.

    • SC-20 Secure Name / Address Resolution Service (Authoritative Source) — The information system provides additional data origin and integrity artifacts along with the authoritative name resolution data the system returns in response to external name/address resolution queries.
    Remediation
    Fix: Enable DNS Resolution for VPC Peering Connection

    Set the allowRemoteVpcDnsResolution property to true for both the accepter and requester configurations in your VPC peering connection.

    new aws.ec2.VpcPeeringConnection("my-peering", {
        vpcId: vpc1.id,
        peerVpcId: vpc2.id,
        accepter: {
            allowRemoteVpcDnsResolution: true,  // Enable DNS resolution for accepter VPC
        },
        requester: {
            allowRemoteVpcDnsResolution: true,  // Enable DNS resolution for requester VPC
        },
    });
    

    vpc-route-table-internet-gateway-restricted

    Severity: medium · Enforcement: advisory

    Ensures VPC route tables restrict public access to internet gateways appropriately.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Restrict Route Table Internet Gateway Access

    Remove or restrict overly broad routes to internet gateways in your VPC route table.

    import * as aws from "@pulumi/aws";
    
    // Create route table without unrestricted internet access
    const routeTable = new aws.ec2.RouteTable("example", {
        vpcId: vpc.id,
        routes: [
            // ❌ INCORRECT: Avoid routes with 0.0.0.0/0 to internet gateway
            // {
            //     cidrBlock: "0.0.0.0/0",
            //     gatewayId: igw.id,
            // },
    
            // ✅ CORRECT: Use specific CIDR blocks or route through NAT gateway instead
            {
                cidrBlock: "10.0.0.0/8", // Private network range
                gatewayId: igw.id,
            },
            // Or use NAT gateway for controlled outbound access
            {
                cidrBlock: "0.0.0.0/0",
                natGatewayId: natGateway.id, // NAT gateway provides controlled egress
            },
        ],
    });
    

    Alternatively, exempt specific route tables from this check by configuring the policy.

    vpc-subnet-auto-assign-public-ip-disabled

    Severity: high · Enforcement: advisory

    Ensures VPC subnets have auto-assign public IP disabled to prevent unintended internet exposure.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Disable Auto-Assign Public IP for VPC Subnets
    const subnet = new aws.ec2.Subnet("private-subnet", {
        vpcId: vpc.id,
        cidrBlock: "10.0.1.0/24",
        mapPublicIpOnLaunch: false,  // Disable auto-assign public IP to prevent unintended internet exposure
    });
    

    wafv2-logging-enabled

    Severity: medium · Enforcement: advisory

    Ensures WAFv2 Web ACLs have logging configurations enabled for audit and monitoring purposes.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable WAFv2 Web ACL Logging

    Create a WebAclLoggingConfiguration resource to enable logging for your WAFv2 Web ACL:

    import * as aws from "@pulumi/aws";
    
    // Create a Kinesis Data Firehose delivery stream for WAF logs
    const wafLogStream = new aws.kinesis.FirehoseDeliveryStream("waf-logs", {
        destination: "extended_s3",
        extendedS3Configuration: {
            roleArn: logRole.arn,
            bucketArn: logBucket.arn,
            prefix: "waf-logs/",
        },
    });
    
    // Enable logging for the Web ACL
    const webAclLogging = new aws.wafv2.WebAclLoggingConfiguration("web-acl-logging", {
        resourceArn: myWebAcl.arn, // Reference to your Web ACL
        logDestinationConfigs: [
            wafLogStream.arn, // Link to Kinesis Firehose stream
        ],
    });
    

    Alternatively, you can log directly to CloudWatch Logs or S3.

      The infrastructure as code platform for any cloud.