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

HITRUST CSF 11.5 - AWS

    This page lists all 130 policies in the HITRUST CSF 11.5 pack for AWS, as published in hitrust-aws version 2.6.4.

    Policies by control

    01.a Access Control Policy — All users shall have a unique identifier for their personal and sole use so that users can be linked to and made responsible for their actions.

    01.b User Registration — User registration shall be used for authorizing and enabling access to information systems and services and for revoking access rights.

    01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.

    01.d User Password Management — The allocation and management of passwords shall be controlled through a formal process, including requirements for password encryption, storage separate from application system data, and prevention of hardcoded credentials in scripts and configuration.

    01.p Secure Log-on Procedures — Log-on procedures shall be designed to minimize the opportunity for unauthorized access. Log-on procedures shall reveal the minimum of information necessary to allow authorized users to recognize that they have accessed the appropriate system.

    01.u Limitation of Connection Time — Inactive sessions shall shut down after a defined period of inactivity.

    01.v Information Access Restriction — Access to systems and applications shall be restricted in accordance with the access control policy.

    06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.

    09.aa Audit Logging — The organization shall ensure that audit logs are enabled and monitored for sensitive systems.

    09.b Change Management — Changes to systems, applications and supporting infrastructure shall be controlled.

    09.d Separation of Development, Test, and Operational Environments — Development, testing, and operational environments shall be separated to reduce the risks of unauthorized access or changes to the operational environment.

    09.e Service Delivery — Policy ensures compliance with HITRUST security requirements.

    09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.

    09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.

    10.c Control of Internal Processing — Input data validation and output controls shall be applied to safeguard against errors, loss, unauthorized modification or misuse of information in applications.

    10.d Message Integrity — Integrity shall be applied to messages using cryptography or digital signatures, where deemed appropriate.

    10.e Output Data Validation — Output data from applications shall be validated to ensure that the processing of stored information is correct and appropriate to the circumstances.

    10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization

    10.h Control of Operational Software — The installation of software on operational systems shall be controlled.

    10.k Change Control Procedures — Changes to systems within the development lifecycle shall be controlled by the use of formal change control procedures.

    10.m Control of Technical Vulnerabilities — Information about technical vulnerabilities of information systems being used shall be obtained in a timely fashion, the organization

    12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization

    Policy details

    anti-malware-edr

    Severity: high · Enforcement: advisory

    Ensures EC2 instances have anti-malware/EDR agents deployed

    • 10.m Control of Technical Vulnerabilities — Information about technical vulnerabilities of information systems being used shall be obtained in a timely fashion, the organization
    Remediation
    Fix: Deploy Anti-Malware/EDR Agent via User Data

    Include anti-malware or EDR agent installation commands in the instance’s userData:

    const instance = new aws.ec2.Instance("protected-instance", {
        instanceType: "t3.medium",
        ami: "ami-0c55b159cbfafe1f0",
        userData: "#!/bin/bash\nyum install -y amazon-ssm-agent\nsystemctl enable amazon-ssm-agent\nsystemctl start amazon-ssm-agent", // Install SSM agent
        subnetId: subnet.id,
    });
    

    api-gateway-access-logging

    Severity: medium · Enforcement: advisory

    Ensures API Gateway stages have access logging enabled

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    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-authorization

    Severity: high · Enforcement: advisory

    Ensures API Gateway methods use strong authorization instead of NONE

    • 01.a Access Control Policy — All users shall have a unique identifier for their personal and sole use so that users can be linked to and made responsible for their actions.
    Remediation
    Fix: Enable Strong Authorization for API Gateway Method

    Set the authorization property to a strong authorization type (AWS_IAM, COGNITO_USER_POOLS, CUSTOM, or JWT) instead of “NONE”:

    const method = new aws.apigateway.Method("my-method", {
        restApi: api.id,
        resourceId: resource.id,
        httpMethod: "GET",
        authorization: "AWS_IAM", // Use strong authorization instead of "NONE"
        // For CUSTOM authorization, also specify the authorizer:
        // authorizerId: authorizer.id,
    });
    

    api-gateway-domain-name-configure-security-policy

    Severity: high · Enforcement: advisory

    Checks that ApiGateway Domain Name Security Policy uses secure/modern TLS encryption.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure TLS 1.2 Security Policy

    Set the securityPolicy to “TLS_1_2” to ensure the API Gateway domain name uses secure TLS encryption:

    const domainName = new apigateway.DomainName("my-domain", {
        domainName: "api.example.com",
        certificateArn: cert.arn,
        securityPolicy: "TLS_1_2", // Use TLS 1.2 for secure encryption
    });
    

    api-gateway-v2-access-logging

    Severity: medium · Enforcement: advisory

    Ensures API Gateway V2 stages have access logging enabled

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    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-v2-domain-name-configure-domain-name-security-policy

    Severity: high · Enforcement: advisory

    Checks that any ApiGatewayV2 Domain Name Security Policy uses secure/modern TLS encryption.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Set TLS 1.2 Security Policy for API Gateway V2 Domain Name

    Configure the securityPolicy to “TLS_1_2” in the domain name configuration to enforce modern TLS encryption:

    const domainName = new aws.apigatewayv2.DomainName("my-domain", {
        domainName: "api.example.com",
        domainNameConfiguration: {
            certificateArn: certificate.arn,
            endpointType: "REGIONAL",
            securityPolicy: "TLS_1_2", // Use TLS 1.2 for secure encryption
        },
    });
    

    api-gateway-v2-domain-name-enable-domain-name-configuration

    Severity: high · Enforcement: advisory

    Checks that any ApiGatewayV2 Domain Name Configuration is enabled.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Domain Name Configuration for API Gateway V2

    Add the domainNameConfiguration property with the required TLS settings to enable secure custom domain name configuration:

    const domainName = new apigatewayv2.DomainName("my-domain", {
        domainName: "api.example.com",
        domainNameConfiguration: { // Enable domain name configuration
            certificateArn: certificate.arn,
            endpointType: "REGIONAL",
            securityPolicy: "TLS_1_2",
        },
    });
    

    api-gateway-v2-stage-configure-access-logging

    Severity: medium · Enforcement: advisory

    Checks that any ApiGatewayV2 Stages have access logging configured.

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    Remediation
    Fix: Configure Access Logging for API Gateway V2 Stage

    Set the accessLogSettings property with both destinationArn (pointing to a CloudWatch Log Group) and format (defining the log format):

    const logGroup = new aws.cloudwatch.LogGroup("api-logs", {
        retentionInDays: 30,
    });
    
    const stage = new aws.apigatewayv2.Stage("api-stage", {
        apiId: api.id,
        name: "prod",
        accessLogSettings: { // Configure access logging
            destinationArn: logGroup.arn, // CloudWatch Log Group ARN
            format: JSON.stringify({ // Log format specification
                requestId: "$context.requestId",
                ip: "$context.identity.sourceIp",
                requestTime: "$context.requestTime",
                httpMethod: "$context.httpMethod",
                routeKey: "$context.routeKey",
                status: "$context.status",
            }),
        },
    });
    

    api-gateway-v2-stage-enable-access-logging

    Severity: medium · Enforcement: advisory

    Checks that any ApiGatewayV2 Stages have access logging enabled.

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    Remediation
    Fix: Enable Access Logging for API Gateway V2 Stage

    Configure the accessLogSettings property to enable access logging by specifying a CloudWatch Logs destination ARN:

    const stage = new aws.apigatewayv2.Stage("my-stage", {
        apiId: api.id,
        name: "prod",
        accessLogSettings: { // Enable access logging
            destinationArn: logGroup.arn,
            format: "$context.requestId",
        },
    });
    

    api-gateway-waf-association

    Severity: critical · Enforcement: advisory

    Ensures public-facing API Gateways have WAF associations

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Associate WAF Web ACL with API Gateway Stage

    Create a WAF Web ACL association for your API Gateway stage:

    // Create a WAF Web ACL association for the API Gateway stage
    const wafAssociation = new aws.wafv2.WebAclAssociation("api-waf-association", {
        resourceArn: pulumi.interpolate`arn:aws:apigateway:${region}::/restapis/${restApi.id}/stages/${stage.stageName}`, // Stage ARN
        webAclArn: webAcl.arn, // Reference the WAF Web ACL ARN
    });
    

    appflow-connector-profile-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Check that AppFlow ConnectorProfile uses a customer-managed KMS key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed KMS Key for AppFlow Connector Profile

    Set the kmsArn property to reference a customer-managed KMS key:

    const connectorProfile = new aws.appflow.ConnectorProfile("my-connector-profile", {
        connectorProfileName: "salesforce-connector",
        connectorType: "Salesforce",
        connectionMode: "Public",
        kmsArn: kmsKey.arn, // Specify customer-managed KMS key ARN
        connectorProfileConfig: {
            connectorProfileCredentials: {
                salesforce: {
                    accessToken: salesforceAccessToken,
                    refreshToken: salesforceRefreshToken,
                    oauthRequest: {
                        authCode: authCode,
                        redirectUri: redirectUri,
                    },
                },
            },
        },
    });
    

    appflow-flow-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Check that AppFlow Flow uses a customer-managed KMS key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed KMS Key for AppFlow Flow

    Set the kmsArn property to specify a customer-managed KMS key for encrypting the AppFlow Flow:

    const flow = new aws.appflow.Flow("my-flow", {
        name: "my-appflow",
        kmsArn: kmsKey.arn, // Configure customer-managed KMS key
        sourceFlowConfig: {
            connectorType: "S3",
            sourceConnectorProperties: {
                s3: {
                    bucketName: sourceBucket.bucket,
                    bucketPrefix: "data/",
                },
            },
        },
        destinationFlowConfigs: [{
            connectorType: "S3",
            destinationConnectorProperties: {
                s3: {
                    bucketName: destBucket.bucket,
                },
            },
        }],
        tasks: [{
            taskType: "Map_all",
            sourceFields: [],
            connectorOperator: {
                s3: "NO_OP",
            },
        }],
        triggerConfig: {
            triggerType: "OnDemand",
        },
    });
    

    appsync-waf-association

    Severity: critical · Enforcement: advisory

    Ensures public-facing AppSync GraphQL APIs have WAF associations

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Associate WAF Web ACL with AppSync GraphQL API

    Create a WAF Web ACL association to protect your AppSync GraphQL API:

    // Create a WAF Web ACL association for the AppSync GraphQL API
    const wafAssociation = new aws.wafv2.WebAclAssociation("appsync-waf-association", {
        resourceArn: graphqlApi.arn, // Reference the GraphQL API ARN
        webAclArn: webAcl.arn, // Reference the WAF Web ACL ARN
    });
    

    athena-database-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Checks that Athena Databases storage uses a customer-managed-key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed Key Encryption for Athena Database

    Set the encryptionOption to “SSE_KMS” and specify a KMS key ARN in the encryptionConfiguration:

    const athenaDatabase = new aws.athena.Database("my-database", {
        name: "my_database",
        bucket: myBucket.id,
        encryptionConfiguration: {
            encryptionOption: "SSE_KMS", // Use customer-managed KMS key
            kmsKey: myKmsKey.arn, // Specify the KMS key ARN
        },
    });
    

    athena-database-disallow-unencrypted-database

    Severity: high · Enforcement: advisory

    Checks that Athena Databases storage is encrypted.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable Encryption for Athena Database

    Configure the encryptionConfiguration property to encrypt query results and data catalog:

    const athenaDatabase = new aws.athena.Database("my-database", {
        name: "my_database",
        bucket: dataBucket.id,
        encryptionConfiguration: { // Enable encryption
            encryptionOption: "SSE_S3", // Use SSE-S3, SSE-KMS, or CSE-KMS
        },
    });
    

    athena-workgroup-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Checks that Athena Workgroups use a customer-managed-key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed Key Encryption for Athena Workgroup

    Set the encryptionOption to “SSE_KMS” in the workgroup’s result configuration to enable customer-managed key encryption:

    const workgroup = new athena.Workgroup("my-workgroup", {
        name: "my-workgroup",
        configuration: {
            resultConfiguration: {
                outputLocation: "s3://my-bucket/query-results/",
                encryptionConfiguration: {
                    encryptionOption: "SSE_KMS", // Enable customer-managed key encryption
                    kmsKey: kmsKey.arn, // Optional: specify a specific KMS key
                },
            },
        },
    });
    

    athena-workgroup-disallow-unencrypted-workgroup

    Severity: high · Enforcement: advisory

    Checks that Athena Workgroups are encrypted.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable Encryption for Athena Workgroup Query Results

    Configure encryption for query results by adding an encryptionConfiguration within the workgroup’s resultConfiguration:

    const workgroup = new athena.Workgroup("my-workgroup", {
        name: "example-workgroup",
        configuration: {
            resultConfiguration: {
                outputLocation: "s3://my-query-results-bucket/",
                encryptionConfiguration: { // Add encryption configuration
                    encryptionOption: "SSE_KMS", // or "SSE_S3" or "CSE_KMS"
                    kmsKey: kmsKey.arn, // Required when using SSE_KMS or CSE_KMS
                },
            },
        },
    });
    

    athena-workgroup-enforce-configuration

    Severity: high · Enforcement: advisory

    Checks that Athena Workgroups enforce their configuration to their clients.

    • 10.h Control of Operational Software — The installation of software on operational systems shall be controlled.
    Remediation
    Fix: Enable Workgroup Configuration Enforcement

    Set enforceWorkgroupConfiguration to true in the Athena Workgroup configuration to ensure clients use the workgroup’s settings:

    const workgroup = new athena.Workgroup("my-workgroup", {
        name: "my-workgroup",
        configuration: {
            enforceWorkgroupConfiguration: true, // Enforce workgroup configuration on clients
            resultConfiguration: {
                outputLocation: "s3://my-query-results/",
            },
        },
    });
    

    centralized-os-app-logging

    Severity: medium · Enforcement: advisory

    Ensures EC2 instances have logging agents configured to forward OS/application logs to central system

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    Remediation
    Fix: Configure Logging Agent in EC2 Instance User Data

    Add a logging agent installation and configuration script to the instance’s userData to forward OS and application logs to a central logging system:

    const instance = new aws.ec2.Instance("web-server", {
        ami: "ami-0c55b159cbfafe1f0",
        instanceType: "t3.micro",
        userData: `#!/bin/bash
    ##### Install and configure CloudWatch Agent for centralized logging
    wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
    rpm -U ./amazon-cloudwatch-agent.rpm
    ##### Configure agent to forward logs
    /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
        -a fetch-config -m ec2 -s -c ssm:AmazonCloudWatch-Config
    `, // Add logging agent to userData
        iamInstanceProfile: instanceProfile.name,
        subnetId: subnet.id,
    });
    

    cloudfront-distribution-configure-access-logging

    Severity: medium · Enforcement: advisory

    Checks that any CloudFront distributions have access logging configured.

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    Remediation
    Fix: Configure CloudFront Access Logging

    Configure the loggingConfig property with an S3 bucket to store CloudFront access logs:

    const distribution = new cloudfront.Distribution("my-distribution", {
        enabled: true,
        loggingConfig: {
            bucket: logBucket.bucketDomainName, // S3 bucket for access logs
            includeCookies: false,
            prefix: "cloudfront-logs/",
        },
        // ... other distribution configuration
    });
    

    cloudfront-distribution-configure-secure-tls

    Severity: high · Enforcement: advisory

    Checks that CloudFront distributions uses secure/modern TLS encryption.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Secure TLS Protocol Version for CloudFront

    Set the minimumProtocolVersion to “TLSv1.2_2021” in the viewer certificate configuration:

    const distribution = new cloudfront.Distribution("my-distribution", {
        enabled: true,
        origins: [/* ... */],
        defaultCacheBehavior: {/* ... */},
        viewerCertificate: {
            cloudfrontDefaultCertificate: true,
            minimumProtocolVersion: "TLSv1.2_2021", // Use secure TLS 1.2 with modern cipher suites
        },
    });
    

    cloudfront-distribution-configure-secure-tls-to-origin

    Severity: high · Enforcement: advisory

    Checks that CloudFront distributions communicate with custom origins using TLS 1.2 encryption only.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure TLS 1.2 for CloudFront Custom Origins

    Set the originSslProtocols in your custom origin configuration to only allow TLS 1.2:

    const distribution = new cloudfront.Distribution("my-distribution", {
        enabled: true,
        origins: [{
            domainName: "my-origin.example.com",
            originId: "myCustomOrigin",
            customOriginConfig: {
                httpPort: 80,
                httpsPort: 443,
                originProtocolPolicy: "https-only",
                originSslProtocols: ["TLSv1.2"], // Only allow TLS 1.2
            },
        }],
        defaultCacheBehavior: {
            targetOriginId: "myCustomOrigin",
            viewerProtocolPolicy: "redirect-to-https",
            allowedMethods: ["GET", "HEAD"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: false,
                cookies: { forward: "none" },
            },
        },
    });
    

    cloudfront-distribution-configure-waf

    Severity: high · Enforcement: advisory

    Checks that any CloudFront distribution has a WAF ACL associated.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Associate WAF Web ACL with CloudFront Distribution

    Set the webAclId property to attach a WAF Web ACL to your CloudFront distribution:

    const distribution = new aws.cloudfront.Distribution("my-distribution", {
        enabled: true,
        webAclId: webAcl.arn, // Associate WAF Web ACL for protection
        origins: [{
            domainName: bucket.bucketRegionalDomainName,
            originId: "myS3Origin",
        }],
        defaultCacheBehavior: {
            targetOriginId: "myS3Origin",
            viewerProtocolPolicy: "redirect-to-https",
            allowedMethods: ["GET", "HEAD"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: false,
                cookies: { forward: "none" },
            },
        },
    });
    

    cloudfront-distribution-disallow-unencrypted-traffic

    Severity: critical · Enforcement: advisory

    Checks that CloudFront distributions only allow encypted ingress traffic.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Enforce HTTPS for CloudFront Distribution

    Set the viewerProtocolPolicy to “redirect-to-https” or “https-only” for both default and ordered cache behaviors to ensure all traffic is encrypted:

    const distribution = new cloudfront.Distribution("my-distribution", {
        enabled: true,
        defaultCacheBehavior: {
            targetOriginId: origin.originId,
            viewerProtocolPolicy: "redirect-to-https", // Enforce HTTPS for all traffic
            allowedMethods: ["GET", "HEAD"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: false,
                cookies: { forward: "none" },
            },
        },
        orderedCacheBehaviors: [{
            pathPattern: "/api/*",
            targetOriginId: origin.originId,
            viewerProtocolPolicy: "https-only", // Enforce HTTPS-only for API paths
            allowedMethods: ["GET", "HEAD", "OPTIONS"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: true,
                cookies: { forward: "none" },
            },
        }],
        origins: [origin],
        viewerCertificate: {
            cloudfrontDefaultCertificate: true,
        },
    });
    

    cloudfront-distribution-enable-access-logging

    Severity: medium · Enforcement: advisory

    Checks that any CloudFront distributions have access logging enabled.

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    Remediation
    Fix: Enable Access Logging for CloudFront Distribution

    Configure the loggingConfig property to enable access logging and specify an S3 bucket to store the logs:

    const distribution = new aws.cloudfront.Distribution("my-distribution", {
        enabled: true,
        origins: [{
            domainName: bucket.bucketRegionalDomainName,
            originId: "myS3Origin",
        }],
        defaultCacheBehavior: {
            targetOriginId: "myS3Origin",
            viewerProtocolPolicy: "redirect-to-https",
            allowedMethods: ["GET", "HEAD"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: false,
                cookies: { forward: "none" },
            },
        },
        loggingConfig: {  // Enable access logging
            bucket: logBucket.bucketDomainName,  // S3 bucket for logs
            includeCookies: false,
            prefix: "cloudfront-logs/",
        },
        restrictions: {
            geoRestriction: {
                restrictionType: "none",
            },
        },
        viewerCertificate: {
            cloudfrontDefaultCertificate: true,
        },
    });
    

    cloudfront-distribution-enable-tls-to-origin

    Severity: critical · Enforcement: advisory

    Checks that CloudFront distributions communicate with custom origins using TLS encryption.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Enable HTTPS-Only Protocol for CloudFront Custom Origins

    Set the originProtocolPolicy to “https-only” in the customOriginConfig for all custom origins to ensure encrypted communication:

    const distribution = new cloudfront.Distribution("my-distribution", {
        enabled: true,
        origins: [{
            domainName: "my-custom-origin.example.com",
            originId: "my-custom-origin",
            customOriginConfig: {
                httpPort: 80,
                httpsPort: 443,
                originProtocolPolicy: "https-only", // Enforce TLS encryption to origin
                originSslProtocols: ["TLSv1.2"],
            },
        }],
        defaultCacheBehavior: {
            targetOriginId: "my-custom-origin",
            viewerProtocolPolicy: "redirect-to-https",
            allowedMethods: ["GET", "HEAD"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: false,
                cookies: { forward: "none" },
            },
        },
    });
    

    cloudfront-waf-association

    Severity: critical · Enforcement: advisory

    Ensures CloudFront distributions have WAF associations

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Associate WAF Web ACL with CloudFront Distribution

    Set the webAclId property to associate your CloudFront distribution with a WAF Web ACL:

    const distribution = new aws.cloudfront.Distribution("my-distribution", {
        enabled: true,
        webAclId: webAcl.arn, // Associate the WAF Web ACL with the distribution
        origins: [{
            domainName: bucket.bucketRegionalDomainName,
            originId: "S3Origin",
        }],
        defaultCacheBehavior: {
            targetOriginId: "S3Origin",
            viewerProtocolPolicy: "redirect-to-https",
            allowedMethods: ["GET", "HEAD"],
            cachedMethods: ["GET", "HEAD"],
            forwardedValues: {
                queryString: false,
                cookies: { forward: "none" },
            },
        },
    });
    

    database-strict-network-access

    Severity: critical · Enforcement: advisory

    Ensures RDS instances have strict network access controls

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Configure Strict Network Access for Database Resources

    Restrict database access to specific internal sources only. Never allow public access (0.0.0.0/0) to database ports.

    // Create a security group with restricted ingress
    const dbSecurityGroup = new aws.ec2.SecurityGroup("db-sg", {
        vpcId: vpc.id,
        ingress: [{
            protocol: "tcp",
            fromPort: 3306,
            toPort: 3306,
            cidrBlocks: ["10.0.0.0/16"], // Restrict to internal VPC CIDR only
        }],
    });
    
    // Associate security group with RDS instance
    const db = new aws.rds.Instance("my-db", {
        engine: "mysql",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        vpcSecurityGroupIds: [dbSecurityGroup.id], // Attach security group
        dbSubnetGroupName: dbSubnetGroup.name,
    });
    
    // Ensure subnet group has at least 2 subnets
    const dbSubnetGroup = new aws.rds.SubnetGroup("db-subnet-group", {
        subnetIds: [privateSubnet1.id, privateSubnet2.id], // Minimum 2 subnets
    });
    

    docdb-clusterinstance-managed-service-patching

    Severity: medium · Enforcement: advisory

    Ensures DocumentDB cluster instances have automated minor version upgrades enabled

    • 10.k Change Control Procedures — Changes to systems within the development lifecycle shall be controlled by the use of formal change control procedures.
    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-streams-enabled

    Severity: medium · Enforcement: advisory

    Enforces that all DynamoDB tables have Stream settings enabled to capture all changes

    • 10.c Control of Internal Processing — Input data validation and output controls shall be applied to safeguard against errors, loss, unauthorized modification or misuse of information in applications.
    Remediation
    Fix: Enable DynamoDB Streams

    Set the streamEnabled property to true on your DynamoDB table:

    const table = new aws.dynamodb.Table("my-table", {
        name: "my-table",
        attributes: [
            { name: "id", type: "S" },
        ],
        hashKey: "id",
        streamEnabled: true, // Enable DynamoDB Streams
        billingMode: "PAY_PER_REQUEST",
    });
    

    ebs-volume-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Check that encrypted EBS volumes use a customer-managed KMS key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed KMS Key for EBS Volume

    Specify a customer-managed KMS key using the kmsKeyId property when creating an encrypted EBS volume:

    const volume = new aws.ebs.Volume("my-volume", {
        availabilityZone: "us-west-2a",
        size: 100,
        encrypted: true,
        kmsKeyId: customerKey.arn, // Use customer-managed KMS key instead of default AWS-managed key
    });
    

    ebs-volume-disallow-unencrypted-volume

    Severity: high · Enforcement: advisory

    Checks that EBS volumes are encrypted.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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-instance-disallow-public-ip

    Severity: high · Enforcement: advisory

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

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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-launch-configuration-disallow-public-ip

    Severity: high · Enforcement: advisory

    Checks that EC2 Launch Configurations do not have a public IP address.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Disable Public IP Assignment for Launch Configuration

    Set the associatePublicIpAddress property to false to prevent instances from receiving public IP addresses:

    const launchConfig = new aws.ec2.LaunchConfiguration("my-launch-config", {
        imageId: "ami-12345678",
        instanceType: "t3.micro",
        associatePublicIpAddress: false, // Disable public IP assignment
        securityGroups: [securityGroup.id],
    });
    

    ec2-launch-configuration-disallow-unencrypted-block-device

    Severity: high · Enforcement: advisory

    Checks that EC2 Launch Configurations do not have unencrypted block devices.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable EBS Block Device Encryption

    Set the encrypted property to true for all EBS block devices in the Launch Configuration:

    const launchConfig = new aws.ec2.LaunchConfiguration("my-launch-config", {
        imageId: "ami-12345678",
        instanceType: "t3.medium",
        ebsBlockDevices: [{
            deviceName: "/dev/sdf",
            volumeSize: 100,
            encrypted: true, // Enable encryption for all EBS block devices
        }],
    });
    

    ec2-launch-configuration-disallow-unencrypted-root-block-device

    Severity: high · Enforcement: advisory

    Checks that EC2 launch configuration do not have unencrypted root block device.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable Encryption for Root Block Device

    Set the encrypted property to true in the rootBlockDevice configuration:

    const launchConfig = new ec2.LaunchConfiguration("my-launch-config", {
        imageId: "ami-0c55b159cbfafe1f0",
        instanceType: "t2.micro",
        rootBlockDevice: {
            encrypted: true, // Enable encryption for root block device
        },
    });
    

    ec2-launch-template-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Check that encrypted EBS volume uses a customer-managed KMS key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Specify Customer-Managed KMS Key for Encrypted EBS Volumes

    Add the kmsKeyId property to encrypted EBS block device mappings in your Launch Template:

    const launchTemplate = new aws.ec2.LaunchTemplate("my-template", {
        blockDeviceMappings: [{
            ebs: {
                encrypted: "true",
                kmsKeyId: customerManagedKey.id, // Specify customer-managed KMS key
                volumeSize: 20,
            },
        }],
    });
    

    ec2-launch-template-disallow-public-ip

    Severity: high · Enforcement: advisory

    Checks that EC2 Launch Templates do not have public IP addresses.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Disable Public IP Assignment in Launch Template

    Set associatePublicIpAddress to false (or omit it) in the network interface configuration to prevent instances from receiving public IP addresses:

    const launchTemplate = new aws.ec2.LaunchTemplate("my-template", {
        imageId: "ami-12345678",
        instanceType: "t3.micro",
        networkInterfaces: [{
            associatePublicIpAddress: "false", // Disable public IP assignment
            securityGroups: [securityGroup.id],
            subnetId: privateSubnet.id,
        }],
    });
    

    ec2-launch-template-disallow-unencrypted-block-device

    Severity: high · Enforcement: advisory

    Checks that EC2 Launch Templates do not have unencrypted block device.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable EBS Volume Encryption in Launch Template

    Set the encrypted property to “true” for all block device mappings in the Launch Template:

    const launchTemplate = new aws.ec2.LaunchTemplate("my-template", {
        imageId: "ami-12345678",
        instanceType: "t3.micro",
        blockDeviceMappings: [{
            deviceName: "/dev/sda1",
            ebs: {
                encrypted: "true", // Enable encryption for the EBS volume
                volumeSize: 20,
                volumeType: "gp3",
            },
        }],
    });
    

    ec2-security-group-disallow-inbound-http-traffic

    Severity: critical · Enforcement: advisory

    Check that EC2 Security Groups do not allow inbound HTTP traffic.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Remove HTTP Inbound Traffic Rules

    Remove any ingress rules that allow HTTP traffic on port 80, or use HTTPS (port 443) instead:

    const securityGroup = new ec2.SecurityGroup("my-sg", {
        vpcId: vpc.id,
        ingress: [
            {
                protocol: "tcp",
                fromPort: 443, // Use HTTPS instead of HTTP (port 80)
                toPort: 443,
                cidrBlocks: ["0.0.0.0/0"],
            },
            // Remove any rules with fromPort: 80 or toPort: 80
        ],
    });
    

    ecr-image-scanning

    Severity: medium · Enforcement: advisory

    Ensures ECR repositories have image scanning enabled for vulnerability management

    • 10.m Control of Technical Vulnerabilities — Information about technical vulnerabilities of information systems being used shall be obtained in a timely fashion, the organization
    Remediation
    Fix: Enable Image Scanning for ECR Repository

    Set the imageScanningConfiguration with scanOnPush: true to automatically scan container images for vulnerabilities when they are pushed:

    const repository = new aws.ecr.Repository("my-repo", {
        name: "my-application",
        imageScanningConfiguration: {
            scanOnPush: true, // Enable automatic vulnerability scanning
        },
    });
    

    ecr-repository-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Checks that ECR repositories use a customer-managed KMS key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed KMS Key for ECR Repository

    Set the encryptionConfiguration with encryptionType to “KMS” and provide a kmsKey ARN to use customer-managed encryption:

    const kmsKey = new aws.kms.Key("ecr-key", {
        description: "KMS key for ECR repository encryption",
    });
    
    const repo = new ecr.Repository("my-repo", {
        encryptionConfigurations: [{
            encryptionType: "KMS", // Use KMS encryption instead of AES256
            kmsKey: kmsKey.arn, // Specify customer-managed KMS key
        }],
    });
    

    ecr-repository-configure-image-scan

    Severity: high · Enforcement: advisory

    Checks that ECR repositories have ‘scan-on-push’ configured.

    • 10.m Control of Technical Vulnerabilities — Information about technical vulnerabilities of information systems being used shall be obtained in a timely fashion, the organization
    Remediation
    Fix: Enable Image Scanning for ECR Repository

    Set the imageScanningConfiguration with scanOnPush enabled to automatically scan container images for vulnerabilities when pushed:

    const repository = new aws.ecr.Repository("my-repo", {
        imageScanningConfiguration: {
            scanOnPush: true, // Enable automatic vulnerability scanning on image push
        },
    });
    

    ecr-repository-disallow-mutable-image

    Severity: high · Enforcement: advisory

    Checks that ECR Repositories have immutable images enabled.

    • 10.h Control of Operational Software — The installation of software on operational systems shall be controlled.
    Remediation
    Fix: Enable Immutable Image Tags

    Set the imageTagMutability property to “IMMUTABLE” to prevent image tags from being overwritten:

    const repository = new ecr.Repository("my-repository", {
        imageTagMutability: "IMMUTABLE", // Prevent image tags from being overwritten
    });
    

    ecr-repository-disallow-unencrypted-repository

    Severity: high · Enforcement: advisory

    Checks that ECR Repositories are encrypted.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable Encryption for ECR Repository

    Configure the encryptionConfigurations property to enable encryption at rest for your ECR repository:

    const repo = new ecr.Repository("my-repo", {
        name: "my-application-repo",
        encryptionConfigurations: [{ // Enable encryption
            encryptionType: "AES256", // Use AWS managed encryption (or "KMS" for customer-managed keys)
        }],
    });
    

    ecr-repository-enable-image-scan

    Severity: high · Enforcement: advisory

    Checks that ECR repositories have ‘scan-on-push’ enabled.

    • 10.m Control of Technical Vulnerabilities — Information about technical vulnerabilities of information systems being used shall be obtained in a timely fashion, the organization
    Remediation
    Fix: Enable Scan-on-Push for ECR Repository

    Set scanOnPush to true in the imageScanningConfiguration to automatically scan container images for vulnerabilities when pushed:

    const repository = new aws.ecr.Repository("my-repository", {
        imageScanningConfiguration: {
            scanOnPush: true, // Enable automatic vulnerability scanning
        },
    });
    

    ecs-task-definition-image-scanning

    Severity: medium · Enforcement: advisory

    Ensures ECS task definitions use images from repositories with vulnerability scanning

    • 10.m Control of Technical Vulnerabilities — Information about technical vulnerabilities of information systems being used shall be obtained in a timely fashion, the organization
    Remediation
    Fix: Use ECR Images with Scanning Enabled

    Update your ECS task definition to use container images from ECR repositories that have vulnerability scanning enabled:

    const taskDefinition = new aws.ecs.TaskDefinition("my-task", {
        family: "my-app",
        containerDefinitions: JSON.stringify([{
            name: "app",
            image: "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest", // Use ECR image with scanning
            memory: 512,
            cpu: 256,
        }]),
        requiresCompatibilities: ["FARGATE"],
        networkMode: "awsvpc",
        cpu: "256",
        memory: "512",
    });
    

    efs-file-system-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Check that encrypted EFS File system uses a customer-managed KMS key.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    Remediation
    Fix: Configure Customer-Managed KMS Key for EFS Encryption

    Set the kmsKeyId property to specify a customer-managed KMS key for EFS file system encryption:

    const fileSystem = new aws.efs.FileSystem("my-efs", {
        encrypted: true,
        kmsKeyId: kmsKey.arn, // Use customer-managed KMS key instead of AWS-managed key
        lifecyclePolicy: {
            transitionToIa: "AFTER_30_DAYS",
        },
    });
    

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

    Severity: high · Enforcement: advisory

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

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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
    });
    

    eks-cluster-disallow-api-endpoint-public-access

    Severity: critical · Enforcement: advisory

    Check that EKS Clusters API Endpoint are not publicly accessible.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Disable Public Access to EKS Cluster API Endpoint

    Set endpointPublicAccess to false and endpointPrivateAccess to true in the VPC configuration:

    const cluster = new eks.Cluster("my-cluster", {
        vpcConfig: {
            subnetIds: privateSubnetIds,
            endpointPublicAccess: false, // Disable public access to API endpoint
            endpointPrivateAccess: true, // Enable private access for internal communication
        },
        // ... other configuration
    });
    

    eks-cluster-enable-cluster-encryption-config

    Severity: high · Enforcement: advisory

    Check that EKS Cluster Encryption Config is enabled.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Enable EKS Cluster Encryption Configuration

    Configure the encryptionConfig property to encrypt Kubernetes secrets using AWS KMS:

    const cluster = new aws.eks.Cluster("my-cluster", {
        roleArn: clusterRole.arn,
        vpcConfig: {
            subnetIds: subnetIds,
        },
        encryptionConfig: { // Enable encryption for Kubernetes secrets
            provider: {
                keyArn: kmsKey.arn, // KMS key for encrypting secrets
            },
            resources: ["secrets"], // Encrypt Kubernetes secrets at rest
        },
    });
    

    elb-load-balancer-configure-access-logging

    Severity: medium · Enforcement: advisory

    Check that ELB Load Balancers uses access logging.

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    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.

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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.

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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,
        },
    });
    

    environment-separation-tagging

    Severity: low · Enforcement: advisory

    Ensures that resources are tagged to distinguish between production and non-production environments

    • 09.d Separation of Development, Test, and Operational Environments — Development, testing, and operational environments shall be separated to reduce the risks of unauthorized access or changes to the operational environment.
    Remediation
    Fix: Add Environment Tag to Resource

    Add an “Environment” tag to the resource with a valid environment value (e.g., production, development, staging, testing):

    const instance = new aws.ec2.Instance("web-server", {
        instanceType: "t3.micro",
        ami: "ami-12345678",
        tags: {
            "Environment": "production", // Add environment tag for proper separation
            "Name": "web-server",
        },
    });
    

    iam-group-policy-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM group policies follow least privilege principles

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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-password-policy-minimum-password-length

    Severity: high · Enforcement: advisory

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

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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.

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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-role-assume-role-mfa-enforcement

    Severity: high · Enforcement: advisory

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

    • 01.p Secure Log-on Procedures — Log-on procedures shall be designed to minimize the opportunity for unauthorized access. Log-on procedures shall reveal the minimum of information necessary to allow authorized users to recognize that they have accessed the appropriate system.
    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-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM roles follow least privilege principles

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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-policy-least-privilege

    Severity: high · Enforcement: advisory

    Ensures IAM role policies follow least privilege principles

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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-session-duration

    Severity: medium · Enforcement: advisory

    Enforces maximum session duration for IAM roles

    • 01.a Access Control Policy — All users shall have a unique identifier for their personal and sole use so that users can be linked to and made responsible for their actions.
    Remediation
    Fix: Set Appropriate Maximum Session Duration for IAM Role

    Configure the maxSessionDuration property based on the role type to limit credential exposure window:

    const appRole = new aws.iam.Role("app-role", {
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { Service: "ec2.amazonaws.com" },
                Action: "sts:AssumeRole",
            }],
        }),
        maxSessionDuration: 3600, // 1 hour for general roles (default)
    });
    
    const adminRole = new aws.iam.Role("admin-role", {
        name: "AdminRole",
        assumeRolePolicy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: { AWS: "arn:aws:iam::123456789012:root" },
                Action: "sts:AssumeRole",
            }],
        }),
        maxSessionDuration: 7200, // 2 hours for administrative roles
    });
    

    iam-user-mfa-console-access

    Severity: high · Enforcement: advisory

    Ensures IAM users with console access have MFA devices

    • 01.p Secure Log-on Procedures — Log-on procedures shall be designed to minimize the opportunity for unauthorized access. Log-on procedures shall reveal the minimum of information necessary to allow authorized users to recognize that they have accessed the appropriate system.
    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

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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
                ],
            }],
        }),
    });
    

    kinesis-event-source-mapping-dlq

    Severity: medium · Enforcement: advisory

    Ensures Kinesis Lambda event source mappings have DLQ configuration

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    Remediation
    Fix: Configure Dead Letter Queue for Kinesis Event Source Mapping

    Add the destinationConfig property with an onFailure destination to capture failed records:

    const eventSourceMapping = new aws.lambda.EventSourceMapping("kinesis-mapping", {
        eventSourceArn: kinesisStream.arn,
        functionName: lambdaFunction.arn,
        startingPosition: "LATEST",
        destinationConfig: { // Add destination configuration for error handling
            onFailure: {
                destination: dlqArn, // ARN of SQS queue or SNS topic for failed records
            },
        },
    });
    

    kinesis-stream-retention

    Severity: medium · Enforcement: advisory

    Ensures Kinesis streams have retention periods configured

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Configure Kinesis Stream Retention Period

    Set the retentionPeriod property to define how long data records remain accessible in the stream (minimum 24 hours, maximum 8760 hours):

    const stream = new aws.kinesis.Stream("my-stream", {
        shardCount: 1,
        retentionPeriod: 24, // Set retention period in hours (24 hours minimum)
        encryptionType: "KMS",
        kmsKeyId: kmsKey.id,
    });
    

    kms-grant-access-control

    Severity: high · Enforcement: advisory

    Validates KMS grants for least privilege access control

    • 01.a Access Control Policy — All users shall have a unique identifier for their personal and sole use so that users can be linked to and made responsible for their actions.
    Remediation
    Fix: Configure KMS Grant with Least Privilege Access Control

    Specify explicit operations for the grant, add constraints for sensitive operations, and define a specific grantee principal:

    const grant = new aws.kms.Grant("my-kms-grant", {
        keyId: kmsKey.id,
        granteePrincipal: roleArn, // Specify a specific grantee principal
        operations: ["Encrypt", "Decrypt"], // Define specific operations
        constraints: {
            encryptionContextSubset: {
                "Department": "Finance", // Add constraints for sensitive operations
            },
        },
    });
    

    kms-key-creation

    Severity: medium · Enforcement: advisory

    Validates KMS key creation with appropriate specifications and origins

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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.

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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
    });
    

    kms-key-policy-access-control

    Severity: high · Enforcement: advisory

    Validates KMS key policies for least privilege and separation of duties

    • 01.a Access Control Policy — All users shall have a unique identifier for their personal and sole use so that users can be linked to and made responsible for their actions.
    Remediation
    Fix: Configure KMS Key Policy with Least Privilege Access Control

    Define an explicit key policy with specific principals and actions, avoiding wildcards:

    const keyPolicy = {
        Version: "2012-10-17",
        Statement: [
            {
                Sid: "Enable IAM User Permissions",
                Effect: "Allow",
                Principal: {
                    AWS: `arn:aws:iam::${accountId}:root`, // Specific account root
                },
                Action: "kms:*",
                Resource: "*",
            },
            {
                Sid: "Allow Key Administrators",
                Effect: "Allow",
                Principal: {
                    AWS: `arn:aws:iam::${accountId}:role/KeyAdminRole`, // Specific role ARN
                },
                Action: [
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion", // Specific administrative actions only
                ],
                Resource: "*",
            },
            {
                Sid: "Allow Key Usage",
                Effect: "Allow",
                Principal: {
                    AWS: `arn:aws:iam::${accountId}:role/KeyUserRole`, // Specific user role ARN
                },
                Action: [
                    "kms:Decrypt",
                    "kms:EncryptionContext*",
                    "kms:GenerateDataKey", // Specific usage actions only
                ],
                Resource: "*",
            },
        ],
    };
    
    const key = new aws.kms.Key("my-key", {
        description: "My KMS key with least privilege policy",
        policy: JSON.stringify(keyPolicy), // Apply the policy with specific principals and actions
    });
    

    lambda-environment-variables-encryption

    Severity: high · Enforcement: advisory

    Ensures that all Lambda functions have their environment variables encrypted using AWS KMS

    • 10.d Message Integrity — Integrity shall be applied to messages using cryptography or digital signatures, where deemed appropriate.
    Remediation
    Fix: Encrypt Lambda Environment Variables with KMS

    Configure a KMS key for Lambda function environment variable encryption by setting the kmsKeyArn property:

    const kmsKey = new aws.kms.Key("lambda-env-key", {
        description: "KMS key for Lambda environment variable encryption",
    });
    
    const lambdaFunction = new aws.lambda.Function("my-function", {
        runtime: "nodejs18.x",
        handler: "index.handler",
        role: role.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./function"),
        }),
        environment: {
            variables: {
                DATABASE_URL: "postgres://example.com/db",
            },
        },
        kmsKeyArn: kmsKey.arn, // Encrypt environment variables with KMS
    });
    

    lambda-function-documentation

    Severity: low · Enforcement: advisory

    Ensures all AWS Lambda functions have a documented description attribute

    • 09.b Change Management — Changes to systems, applications and supporting infrastructure shall be controlled.
    Remediation
    Fix: Add Description to Lambda Function

    Add a meaningful description attribute to your Lambda function that is at least 10 characters long:

    const myFunction = new aws.lambda.Function("my-function", {
        code: new pulumi.asset.FileArchive("./function"),
        role: lambdaRole.arn,
        handler: "index.handler",
        runtime: "nodejs20.x",
        description: "Processes user authentication requests and validates credentials", // Add descriptive documentation
    });
    

    lambda-function-logging

    Severity: medium · Enforcement: advisory

    Ensures that all AWS Lambda functions have logging enabled to track output data processing

    • 10.e Output Data Validation — Output data from applications shall be validated to ensure that the processing of stored information is correct and appropriate to the circumstances.
    Remediation
    Fix: Enable Lambda Function Logging Configuration

    Add the loggingConfig property to your Lambda function with an appropriate applicationLogLevel (DEBUG, INFO, or WARN):

    const myFunction = new aws.lambda.Function("my-function", {
        runtime: "nodejs18.x",
        handler: "index.handler",
        role: lambdaRole.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./app"),
        }),
        loggingConfig: {
            logFormat: "JSON",
            applicationLogLevel: "INFO", // Set log level to INFO or DEBUG for adequate logging
        },
    });
    

    lambda-permission-configure-source-arn

    Severity: critical · Enforcement: advisory

    Checks that lambda function permissions have a source arn specified.

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    Remediation
    Fix: Configure Source ARN for Lambda Permission

    Add the sourceArn property to restrict which AWS service or resource can invoke the Lambda function:

    const lambdaPermission = new aws.lambda.Permission("my-permission", {
        action: "lambda:InvokeFunction",
        function: myFunction.name,
        principal: "apigateway.amazonaws.com",
        sourceArn: apiGateway.executionArn, // Specify the source ARN to restrict invocation
    });
    

    lambda-runtime-restrictions

    Severity: low · Enforcement: advisory

    Ensures that AWS Lambda functions are created only with approved runtime versions

    • 10.h Control of Operational Software — The installation of software on operational systems shall be controlled.
    Remediation
    Fix: Use Approved Lambda Runtime

    Set the runtime property to an approved runtime version from the organization’s approved list:

    const myFunction = new aws.lambda.Function("my-function", {
        runtime: "nodejs20.x", // Use an approved runtime version
        handler: "index.handler",
        role: role.arn,
        code: new pulumi.asset.AssetArchive({
            ".": new pulumi.asset.FileArchive("./function"),
        }),
    });
    

    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

    • 01.u Limitation of Connection Time — Inactive sessions shall shut down after a defined period of inactivity.
    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

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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

    • 10.k Change Control Procedures — Changes to systems within the development lifecycle shall be controlled by the use of formal change control procedures.
    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.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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

    • 01.p Secure Log-on Procedures — Log-on procedures shall be designed to minimize the opportunity for unauthorized access. Log-on procedures shall reveal the minimum of information necessary to allow authorized users to recognize that they have accessed the appropriate system.
    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
    

    no-hardcoded-secrets

    Severity: critical · Enforcement: advisory

    Ensures EC2 instance userData does not contain hardcoded secrets

    • 01.d User Password Management — The allocation and management of passwords shall be controlled through a formal process, including requirements for password encryption, storage separate from application system data, and prevention of hardcoded credentials in scripts and configuration.
    Remediation
    Fix: Remove Hardcoded Secrets

    Remove hardcoded secrets from userData scripts.

    Example Violation
    const instance = new aws.ec2.Instance("web-server", {
        instanceType: "t3.micro",
        ami: "ami-12345678",
        userData: `#!/bin/bash
    export DATABASE_PASSWORD="mySecretPassword123"
    export API_KEY="sk_live_abc123def456789"
    mysql -u admin -p"hardcodedPassword" -h db.example.com
    `,
    });
    

    pubsub-least-privilege-iam

    Severity: medium · Enforcement: advisory

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

    • 01.c Privilege Management — The allocation and use of privileges shall be restricted and controlled. The use of privileged utility programs shall be restricted and tightly controlled.
    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

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    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-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Checks that RDS Clusters storage uses a customer-managed KMS key.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Configure Customer-Managed KMS Key for RDS Cluster

    Specify a customer-managed KMS key for RDS Cluster storage encryption using the kmsKeyId property:

    const cluster = new rds.Cluster("my-cluster", {
        engine: "aurora-postgresql",
        storageEncrypted: true,
        kmsKeyId: kmsKey.arn, // Use customer-managed KMS key
        masterUsername: "admin",
        masterPassword: dbPassword,
    });
    

    rds-cluster-disallow-single-availability-zone

    Severity: high · Enforcement: advisory

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

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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.

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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-secure-master-credentials

    Severity: high · Enforcement: advisory

    Ensures RDS clusters use secure credential management instead of hardcoded passwords

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Use AWS Secrets Manager for RDS Cluster Master Credentials

    Enable AWS-managed master password using Secrets Manager instead of hardcoded credentials:

    const dbCluster = new aws.rds.Cluster("my-cluster", {
        engine: "aurora-mysql",
        engineVersion: "8.0.mysql_aurora.3.02.0",
        manageMasterUserPassword: true, // Enable AWS Secrets Manager for master password
        masterUsername: "admin",
        // Do NOT set the masterPassword property - AWS Secrets Manager handles it
        vpcSecurityGroupIds: [securityGroup.id],
        dbSubnetGroupName: subnetGroup.name,
    });
    

    rds-clusterinstance-managed-service-patching

    Severity: medium · Enforcement: advisory

    Ensures RDS cluster instances have automated minor version upgrades enabled

    • 10.k Change Control Procedures — Changes to systems within the development lifecycle shall be controlled by the use of formal change control procedures.
    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

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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-iam-authentication

    Severity: medium · Enforcement: advisory

    Ensures RDS instances have IAM database authentication enabled

    • 01.a Access Control Policy — All users shall have a unique identifier for their personal and sole use so that users can be linked to and made responsible for their actions.
    Remediation
    Fix: Enable IAM Database Authentication for RDS Instance

    Set the iamDatabaseAuthenticationEnabled property to true to enable IAM-based authentication for your RDS instance:

    const rdsInstance = new aws.rds.Instance("my-database", {
        engine: "mysql",
        instanceClass: "db.t3.micro",
        allocatedStorage: 20,
        username: "admin",
        iamDatabaseAuthenticationEnabled: true, // Enable IAM database authentication
        skipFinalSnapshot: true,
    });
    

    rds-instance-configure-customer-managed-key

    Severity: low · Enforcement: advisory

    Checks that RDS Instance storage uses a customer-managed KMS key.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Configure Customer-Managed KMS Key for RDS Instance

    Specify a customer-managed KMS key when enabling storage encryption on your RDS instance:

    const rdsInstance = new aws.rds.Instance("my-db", {
        allocatedStorage: 20,
        engine: "postgres",
        instanceClass: "db.t3.micro",
        storageEncrypted: true,
        kmsKeyId: kmsKey.arn, // Specify customer-managed KMS key ARN
        // ... other configuration
    });
    

    rds-instance-disallow-public-access

    Severity: critical · Enforcement: advisory

    Checks that RDS Instance public access is not enabled.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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.

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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.

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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-high-availability

    Severity: medium · Enforcement: advisory

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

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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

    • 10.k Change Control Procedures — Changes to systems within the development lifecycle shall be controlled by the use of formal change control procedures.
    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

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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,
    });
    

    rds-private-subnet-validation

    Severity: critical · Enforcement: advisory

    Validates that RDS DB subnet groups contain only private subnets

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Deploy RDS DB Subnet Group in Private Subnets

    Ensure the DB subnet group only contains subnets that do not have routes to an Internet Gateway. Private subnets should route internet-bound traffic through a NAT Gateway instead:

    const privateSubnetGroup = new aws.rds.SubnetGroup("db-subnet-group", {
        subnetIds: [
            privateSubnet1.id,  // Private subnet without Internet Gateway route
            privateSubnet2.id,  // Private subnet without Internet Gateway route
        ],
        tags: {
            Name: "Private DB Subnet Group",
        },
    });
    
    const db = new aws.rds.Instance("database", {
        dbSubnetGroupName: privateSubnetGroup.name,
        publiclyAccessible: false,
        // ... other configuration
    });
    

    rds-secure-master-credentials

    Severity: high · Enforcement: advisory

    Ensures RDS instances use secure credential management instead of hardcoded passwords

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Use AWS Secrets Manager for RDS Master Credentials

    Enable AWS-managed master password using Secrets Manager instead of hardcoded credentials:

    const dbInstance = new aws.rds.Instance("my-db", {
        allocatedStorage: 20,
        engine: "mysql",
        instanceClass: "db.t3.micro",
        manageMasterUserPassword: true, // Enable AWS Secrets Manager for master password
        username: "admin",
        // Do NOT set the password property - AWS Secrets Manager handles it
        vpcSecurityGroupIds: [securityGroup.id],
        dbSubnetGroupName: subnetGroup.name,
    });
    

    resource-tagging

    Severity: low · Enforcement: advisory

    Ensures all AWS resources must include tags for proper change tracking

    • 09.b Change Management — Changes to systems, applications and supporting infrastructure shall be controlled.
    Remediation
    Fix: Add Required Tags to AWS Resources

    Add a tags property with meaningful values to enable proper change tracking and documentation:

    const instance = new aws.ec2.Instance("my-instance", {
        ami: "ami-0c55b159cbfafe1f0",
        instanceType: "t3.micro",
        tags: {
            Environment: "production", // Add meaningful tags for change tracking
            Owner: "team-name",
            Application: "web-app",
        },
    });
    

    restrict-default-iam-user-creation

    Severity: medium · Enforcement: advisory

    Ensures that default IAM user accounts are not allowed to be created

    • 01.b User Registration — User registration shall be used for authorizing and enabling access to information systems and services and for revoking access rights.
    Remediation
    Fix: Use Descriptive User Names

    Use specific, descriptive user names that follow your organization’s naming conventions instead of generic default names:

    const iamUser = new aws.iam.User("my-iam-user", {
        name: "john.doe", // Use descriptive, organization-specific user names
        // Avoid generic names like: root, admin, administrator, default, user, guest, test, demo
    });
    

    s3-bucket-access-logging

    Severity: medium · Enforcement: advisory

    Ensures each S3 bucket has access logging enabled

    • 09.e Service Delivery — Policy ensures compliance with HITRUST security requirements.
    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’.

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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

    • 01.v Information Access Restriction — Access to systems and applications shall be restricted in accordance with the access control policy.
    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

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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-macie-access

    Severity: low · Enforcement: advisory

    Ensures S3 buckets allow AWS Macie access for data classification and discovery

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Allow AWS Macie Service Access in S3 Bucket Policy

    Add an Allow statement for the AWS Macie service principal in your S3 bucket policy, or ensure Deny statements exclude the Macie service-linked role:

    const bucketPolicy = new aws.s3.BucketPolicy("my-bucket-policy", {
        bucket: bucket.id,
        policy: bucket.arn.apply(arn => JSON.stringify({
            Version: "2012-10-17",
            Statement: [
                {
                    Effect: "Allow",
                    Principal: {
                        Service: "macie.amazonaws.com" // Allow Macie service access
                    },
                    Action: [
                        "s3:GetObject",
                        "s3:GetBucketLocation",
                        "s3:ListBucket"
                    ],
                    Resource: [
                        arn,
                        `${arn}/*`
                    ]
                }
            ]
        }))
    });
    

    s3-bucket-public-access-block

    Severity: critical · Enforcement: advisory

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

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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-versioning

    Severity: medium · Enforcement: advisory

    S3 buckets must have versioning enabled using BucketVersioning resource

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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
        },
    });
    

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

    Severity: low · Enforcement: advisory

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

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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

    • 10.f Policy on the Use of Cryptographic Controls — Cryptographic controls shall be used in compliance with all relevant agreements, legislation and regulations, and risk assessments shall consider the organization
    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

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    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"],
            },
        ],
    });
    

    sns-subscription-dead-letter-queue

    Severity: medium · Enforcement: advisory

    Ensures SNS subscriptions have dead letter queue configuration

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    Remediation
    Fix: Configure Dead Letter Queue for SNS Subscription

    Set the redrivePolicy with a deadLetterTargetArn pointing to an SQS queue to capture failed message deliveries:

    const dlq = new aws.sqs.Queue("my-dlq", {
        messageRetentionSeconds: 1209600, // 14 days
    });
    
    const subscription = new aws.sns.TopicSubscription("my-subscription", {
        topic: topic.arn,
        protocol: "sqs",
        endpoint: targetQueue.arn,
        redrivePolicy: JSON.stringify({ // Configure dead letter queue
            deadLetterTargetArn: dlq.arn,
        }),
    });
    

    sqs-dead-letter-queue

    Severity: medium · Enforcement: advisory

    Ensures SQS queues have dead letter queue configuration

    • 12.a Including Information Security in the Business Continuity Management — Information security shall be a central part of the organization
    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

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    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,
    });
    

    sqs-message-retention

    Severity: medium · Enforcement: advisory

    Ensures SQS queues have message retention periods configured

    • 06.d Data Protection and Privacy of Covered Information — Covered information shall be protected against unauthorized disclosure, modification and destruction. For the purpose of this control, covered information includes protected health information, cardholder data, and other sensitive information.
    Remediation
    Fix: Configure SQS Message Retention Period

    Set the messageRetentionSeconds property to define how long messages are retained in the queue (60 seconds to 1,209,600 seconds/14 days):

    const queue = new aws.sqs.Queue("my-queue", {
        messageRetentionSeconds: 345600, // Set retention period (e.g., 4 days)
    });
    

    subnet-multi-az

    Severity: medium · Enforcement: advisory

    Ensures subnets are distributed across multiple availability zones

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Distribute Subnets Across Multiple Availability Zones

    Create subnets in at least 2 different availability zones to ensure high availability and fault tolerance:

    const subnet1 = new aws.ec2.Subnet("subnet-az1", {
        vpcId: vpc.id,
        cidrBlock: "10.0.1.0/24",
        availabilityZone: "us-east-1a", // Specify explicit AZ
    });
    
    const subnet2 = new aws.ec2.Subnet("subnet-az2", {
        vpcId: vpc.id,
        cidrBlock: "10.0.2.0/24",
        availabilityZone: "us-east-1b", // Use different AZ for redundancy
    });
    

    vpc-endpoint-security-policy

    Severity: medium · Enforcement: advisory

    Ensures that VPC endpoints are associated with security policies that limit access to specified resources

    • 01.v Information Access Restriction — Access to systems and applications shall be restricted in accordance with the access control policy.
    Remediation
    Fix: Configure Restrictive VPC Endpoint Policy

    Add a policy to your VPC endpoint that specifies explicit principals and resources instead of wildcards:

    const vpcEndpoint = new aws.ec2.VpcEndpoint("my-endpoint", {
        vpcId: vpc.id,
        serviceName: "com.amazonaws.us-west-2.s3",
        policy: JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    AWS: "arn:aws:iam::123456789012:role/MyRole" // Specify explicit principal ARN
                },
                Action: "s3:GetObject",
                Resource: "arn:aws:s3:::my-bucket/*" // Specify explicit resource ARN
            }]
        }),
    });
    

    vpc-flow-logs

    Severity: medium · Enforcement: advisory

    Ensures VPC flow logs use approved destinations for centralized monitoring

    • 09.aa Audit Logging — The organization shall ensure that audit logs are enabled and monitored for sensitive systems.
    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-subnet-flow-logs

    Severity: medium · Enforcement: advisory

    Ensures all VPCs and subnets have flow logs enabled

    • 09.z Publicly Available Information — Publicly available information shall be protected against unauthorized modification or deletion.
    Remediation
    Fix: Enable VPC Flow Logs for Network Monitoring

    Create a VPC Flow Log resource and associate it with your VPC or subnet to capture network traffic information:

    const vpc = new aws.ec2.Vpc("my-vpc", {
        cidrBlock: "10.0.0.0/16",
    });
    
    // Enable flow logs for the VPC
    const flowLog = new aws.ec2.FlowLog("vpc-flow-log", {
        vpcId: vpc.id, // Associate flow log with VPC
        trafficType: "ALL", // Capture all traffic (ACCEPT, REJECT, ALL)
        logDestinationType: "cloud-watch-logs",
        logDestination: logGroup.arn,
        iamRoleArn: flowLogRole.arn,
    });
    

    waf-association-validation

    Severity: critical · Enforcement: advisory

    Validates WAF Web ACL associations are properly configured

    • 09.m Network Controls — Networks shall be managed and controlled in order to protect the organization from threats and to maintain security for the systems and applications using the network, including information in transit.
    Remediation
    Fix: Configure WAF Web ACL Association Properties

    Ensure both resourceArn and webAclArn are specified in the WAF association:

    const wafAssociation = new aws.wafv2.WebAclAssociation("my-waf-association", {
        resourceArn: resource.arn, // Specify the resource ARN to protect
        webAclArn: webAcl.arn, // Specify the WAF Web ACL ARN
    });
    

      The infrastructure as code platform for any cloud.