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

NIST SP 800-53 - Google Cloud

    This page lists all 140 policies in the NIST SP 800-53 pack for Google Cloud, as published in nist-google-cloud version 1.0.1.

    Policies by control

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

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

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

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

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

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

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

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

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

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

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

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

    CM-5 Access Restrictions for Change — The organization defines, documents, approves, and enforces logical access restrictions associated with changes to the information system.

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

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

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

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

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

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

    RA-5 Vulnerability Monitoring and Scanning — The organization monitors and scans for vulnerabilities in the information system and hosted applications and remediates legitimate vulnerabilities.

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

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

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

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

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

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

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

    Policy details

    ai-platform-endpoint-configuration-kms-key-configured

    Severity: medium · Enforcement: advisory

    Ensure AI Platform endpoint configuration uses Cloud KMS

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

    Configure the encryptionSpec property with a kmsKeyName when creating AI Platform endpoints. Ensure the KMS key is in the same region as the endpoint and grant the Vertex AI service account access to the key.

    Pulumi TypeScript example:

    import * as gcp from "@pulumi/gcp";
    
    // Create a KMS key for endpoint encryption
    const keyRing = new gcp.kms.KeyRing("ai-keyring", {
        location: "us-central1",
    });
    
    const cryptoKey = new gcp.kms.CryptoKey("ai-endpoint-key", {
        keyRing: keyRing.id,
        rotationPeriod: "7776000s", // 90 days
    });
    
    // Create an AI Platform endpoint with CMEK
    const endpoint = new gcp.vertex.AiEndpoint("my-endpoint", {
        location: "us-central1",
        displayName: "My Secure Endpoint",
        // Configure customer-managed encryption key
        encryptionSpec: {
            kmsKeyName: cryptoKey.id,
        },
    });
    

    ai-platform-notebook-instance-kms-key-configured

    Severity: medium · Enforcement: advisory

    Ensure AI Platform notebook instance uses Cloud KMS

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

    Configure the kmsKey property for notebook instances or virtualMachine.virtualMachineConfig.encryptionConfig.kmsKey for runtimes. Grant the Notebooks service account encrypt/decrypt permissions on the KMS key.

    Pulumi TypeScript example:

    import * as gcp from "@pulumi/gcp";
    
    // Create a KMS key for notebook encryption
    const keyRing = new gcp.kms.KeyRing("notebook-keyring", {
        location: "us-central1",
    });
    
    const cryptoKey = new gcp.kms.CryptoKey("notebook-key", {
        keyRing: keyRing.id,
        rotationPeriod: "7776000s", // 90 days
    });
    
    // Option 1: Notebook Instance with CMEK
    const notebookInstance = new gcp.notebooks.Instance("my-notebook", {
        location: "us-central1-a",
        machineType: "n1-standard-4",
        // Configure customer-managed encryption key
        kmsKey: cryptoKey.id,
        vmImage: {
            project: "deeplearning-platform-release",
            imageFamily: "tf-latest-cpu",
        },
    });
    
    // Option 2: Notebook Runtime with CMEK
    const notebookRuntime = new gcp.notebooks.Runtime("my-runtime", {
        location: "us-central1",
        virtualMachine: {
            virtualMachineConfig: {
                machineType: "n1-standard-4",
                dataDisk: {
                    initializeParams: {
                        diskSizeGb: 100,
                        diskType: "PD_STANDARD",
                    },
                },
                // Configure customer-managed encryption key
                encryptionConfig: {
                    kmsKey: cryptoKey.id,
                },
            },
        },
    });
    

    ai-platform-notebook-no-direct-internet-access

    Severity: high · Enforcement: advisory

    Ensure AI Platform notebook has no direct internet access

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

    Configure AI Platform notebook instances with noPublicIp: true and deploy within a VPC subnet. Use VPC Service Controls and Private Google Access for controlled connectivity to Google services without public IP addresses.

    Pulumi TypeScript example:

    import * as gcp from "@pulumi/gcp";
    
    const notebook = new gcp.notebooks.Instance("my-notebook", {
        location: "us-central1-a",
        machineType: "n1-standard-4",
        // Disable public IP to prevent direct internet access
        noPublicIp: true,
        // Deploy in a VPC subnet for network isolation
        network: "projects/my-project/global/networks/my-vpc",
        subnet: "projects/my-project/regions/us-central1/subnetworks/my-subnet",
        // Configure boot disk
        vmImage: {
            project: "deeplearning-platform-release",
            imageFamily: "tf-latest-cpu",
        },
    });
    

    api-gateway-logging-configuration

    Severity: high · Enforcement: advisory

    Ensure API Gateway has proper logging configuration with service accounts and audit logs

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

    Configure API Gateway with proper logging setup:

    1. Create a dedicated service account for API Gateway backend authentication
    2. Configure ApiConfig with gatewayConfig.backendConfig.googleServiceAccount
    3. Grant the service account appropriate IAM roles for backend access (e.g., roles/run.invoker for Cloud Run)
    4. Enable audit logging for apigateway.googleapis.com service

    Pulumi TypeScript example:

    import * as gcp from "@pulumi/gcp";
    
    // Step 1: Create service account
    const apiGatewaySA = new gcp.serviceaccount.Account("api-gateway-sa", {
        accountId: "api-gateway-sa",
        displayName: "API Gateway Service Account",
    });
    
    // Step 2: Grant backend access permissions
    const invokerBinding = new gcp.iam.Member("api-gateway-invoker", {
        project: "my-project",
        role: "roles/run.invoker",  // Or roles/cloudfunctions.invoker for Cloud Functions
        member: apiGatewaySA.member,
    });
    
    // Step 3: Configure API Gateway with service account
    const apiConfig = new gcp.apigateway.ApiConfig("my-api-config", {
        api: api.id,
        apiConfigId: "my-config",
        gatewayConfig: {
            backendConfig: {
                googleServiceAccount: apiGatewaySA.email,  // Critical for logging
            },
        },
        openapiDocuments: [{
            document: {
                path: "openapi.yaml",
                contents: pulumi.asset.StringAsset(openapiSpec),
            },
        }],
    });
    
    // Step 4: Enable audit logging
    const auditConfig = new gcp.projects.IAMAuditConfig("api-gateway-audit", {
        project: "my-project",
        service: "apigateway.googleapis.com",
        auditLogConfigs: [
            { logType: "ADMIN_READ" },
            { logType: "DATA_READ" },
            { logType: "DATA_WRITE" },
        ],
    });
    

    app-engine-managed-updates-enabled

    Severity: high · Enforcement: advisory

    Ensure App Engine managed updates are enabled

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

    Configure App Engine versions with automaticScaling instead of manualScaling or basicScaling to enable managed updates:

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Standard App Version with automatic scaling
    const app = new gcp.appengine.StandardAppVersion("app-auto-scaled", {
      service: "myapp",
      runtime: "nodejs20",
      versionId: "v1",
      entrypoint: { shell: "node ./app.js" },
      deployment: {
        zip: { sourceUrl: "https://storage.googleapis.com/bucket/app.zip" },
      },
      automaticScaling: {
        maxConcurrentRequests: 10,
        minIdleInstances: 1,
        maxIdleInstances: 3,
      },
    });
    
    // NON-COMPLIANT: Manual scaling prevents managed updates
    // manualScaling: { instances: 3 }  // Don't use this
    
    // NON-COMPLIANT: Basic scaling limits managed updates
    // basicScaling: { maxInstances: 5 }  // Don't use this
    

    artifactregistry-customer-kms

    Severity: high · Enforcement: advisory

    Require Artifact Registry repositories to use customer-managed Cloud KMS keys for encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Customer-Managed KMS Key
    const repository = new gcp.artifactregistry.Repository("my-repository", {
        repositoryId: "my-repo",
        format: "DOCKER",
        kmsKeyName: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Specify customer-managed KMS key
        // ... other config
    });
    

    artifactregistry-immutable-images

    Severity: medium · Enforcement: advisory

    Require Artifact Registry repositories to disallow mutable images for security and compliance

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Enable Immutable Tags for Docker Repositories
    const repository = new gcp.artifactregistry.Repository("my-repository", {
        repositoryId: "my-repo",
        format: "DOCKER",
        dockerConfig: {
            immutableTags: true,  // Prevent tag overwrites to ensure image integrity
        },
        // ... other config
    });
    

    audit-logs-sink-enabled

    Severity: medium · Enforcement: advisory

    Enable Cloud Audit Logs Cloud Logging integration for monitoring

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

    Create log sinks to route audit logs to Cloud Logging destinations. Configure gcp.logging.ProjectSink, gcp.logging.OrganizationSink, or gcp.logging.FolderSink resources with filters to capture audit logs (e.g., filter including ‘cloudaudit.googleapis.com’). Route logs to Cloud Logging buckets, BigQuery, or Pub/Sub for centralized analysis and retention.

    bigquery-audit-logging-enabled

    Severity: high · Enforcement: advisory

    Enable BigQuery audit logging for monitoring

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

    Configure projects.IAMAuditConfig resource with service: "bigquery.googleapis.com" and enable DATA_READ and DATA_WRITE log types in auditLogConfigs. Create a log sink (ProjectSink or OrganizationSink) with filter protoPayload.serviceName="bigquery.googleapis.com" to export audit logs for long-term retention.

    Example TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const bigQueryAuditConfig = new gcp.projects.IAMAuditConfig("bigquery-audit", {
        project: "your-project-id",
        service: "bigquery.googleapis.com",
        auditLogConfigs: [
            { logType: "DATA_READ" },
            { logType: "DATA_WRITE" },
            { logType: "ADMIN_READ" }
        ]
    });
    
    const bigQueryLogSink = new gcp.logging.ProjectSink("bigquery-logs", {
        destination: "storage.googleapis.com/my-audit-logs-bucket",
        filter: 'protoPayload.serviceName="bigquery.googleapis.com"',
        uniqueWriterIdentity: true
    });
    

    bigquery-dataset-cmek

    Severity: high · Enforcement: advisory

    Ensures BigQuery datasets are encrypted with customer-managed keys (CMEK)

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

    Configure defaultEncryptionConfiguration with kmsKeyName to use a Cloud KMS key for dataset encryption.

    bigquery-dataset-public-access-check

    Severity: high · Enforcement: advisory

    Ensure BigQuery datasets are not publicly accessible

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

    Remove public access from BigQuery datasets by ensuring IAM policies do not grant allUsers or allAuthenticatedUsers permissions. Review dataset accesses configuration and IAM bindings/members. Grant access only to specific service accounts, users, or groups based on least privilege principles.

    Example TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const dataset = new gcp.bigquery.Dataset("secure-dataset", {
        datasetId: "my_dataset",
        location: "US",
        accesses: [
            {
                role: "READER",
                userByEmail: "analyst@example.com"
            },
            {
                role: "roles/bigquery.dataEditor",
                userByEmail: serviceAccount.email
            }
            // Do NOT include allUsers or allAuthenticatedUsers
        ]
    });
    
    // Using IAM binding for specific members only
    const datasetViewer = new gcp.bigquery.DatasetIamBinding("dataset-viewer", {
        datasetId: dataset.datasetId,
        role: "roles/bigquery.dataViewer",
        members: [
            "user:jane@example.com",
            "serviceAccount:myapp@project.iam.gserviceaccount.com"
            // Do NOT use allUsers or allAuthenticatedUsers
        ]
    });
    

    bigquery-maintenance-settings-check

    Severity: medium · Enforcement: advisory

    Ensure BigQuery maintenance settings are configured

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

    Configure BigQuery datasets with appropriate maintenance settings:

    import * as gcp from "@pulumi/gcp";
    
    const dataset = new gcp.bigquery.Dataset("my-dataset", {
      datasetId: "my_dataset",
      description: "Dataset purpose and maintenance requirements",
      defaultTableExpirationMs: 7776000000, // 90 days
      defaultPartitionExpirationMs: 7776000000,
      labels: {
        environment: "production",
        dataRetention: "90days",
      },
    });
    

    bigquery-table-cmek

    Severity: high · Enforcement: advisory

    Ensures BigQuery tables are encrypted with customer-managed keys (CMEK)

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

    Configure encryptionConfiguration with kmsKeyName to use a Cloud KMS key for table encryption.

    bigtable-change-streams

    Severity: medium · Enforcement: advisory

    Require Bigtable tables to have change streams enabled for change tracking

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Change Stream Retention
    const bigtableTable = new gcp.bigtable.Table("my-table", {
        instanceName: "my-bigtable-instance",
        changeStreamRetention: "72h0m0s",  // Enable change streams with 3-day retention
        // ... other config
    });
    

    bucket-access-logging

    Severity: medium · Enforcement: advisory

    Ensures Cloud Storage buckets have access logging enabled with logBucket and logObjectPrefix configured

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

    bucket-cmek

    Severity: high · Enforcement: advisory

    Ensures Cloud Storage buckets use customer-managed KMS keys for encryption

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

    Configure bucket.encryption.defaultKmsKeyName with a valid customer-managed KMS key in the format: projects/PROJECT/locations/LOCATION/keyRings/RING/cryptoKeys/KEY

    bucket-dlp-access

    Severity: medium · Enforcement: advisory

    Require Cloud Storage buckets to have appropriate access for data classification services like Cloud DLP

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Grant DLP Service Account Access
    const bucketIamPolicy = new gcp.storage.BucketIAMPolicy("bucket-iam", {
        bucket: bucket.name,
        policyData: JSON.stringify({
            bindings: [
                {
                    role: "roles/storage.objectViewer",
                    members: [
                        "serviceAccount:service-{project-number}@dlp-api.iam.gserviceaccount.com",  // Grant DLP service account access
                    ],
                },
                // ... other bindings
            ],
        }),
    });
    

    bucket-iam-least-privilege

    Severity: high · Enforcement: advisory

    Enforce least privilege access for Cloud Storage bucket IAM policies

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Specific Least Privilege Roles
    // Instead of overly broad roles like storage.admin or storage.objectAdmin
    // Use specific roles based on actual needs:
    
    // For read-only access
    const viewerBinding = new gcp.storage.BucketIAMBinding("viewer-binding", {
        bucket: bucket.name,
        role: "roles/storage.objectViewer",  // Read-only access to objects
        members: ["user:viewer@example.com"],
    });
    
    // For write-only access
    const creatorBinding = new gcp.storage.BucketIAMBinding("creator-binding", {
        bucket: bucket.name,
        role: "roles/storage.objectCreator",  // Write-only access (no read)
        members: ["serviceAccount:app@project.iam.gserviceaccount.com"],
    });
    
    // Avoid these overly broad roles:
    // - roles/storage.admin
    // - roles/storage.objectAdmin
    // - roles/owner
    // - roles/editor
    

    bucket-lifecycle

    Severity: medium · Enforcement: advisory

    Require Cloud Storage buckets to have lifecycle management policies configured

    • MP-6 Media Sanitization — The organization sanitizes information system media, both paper and digital, prior to disposal, release out of organizational control, or release for reuse.
    Remediation
    Fix: Configure Lifecycle Rules
    const bucket = new gcp.storage.Bucket("my-bucket", {
        location: "US",
        lifecycleRules: [
            {
                action: {
                    type: "Delete",  // Delete old objects
                },
                condition: {
                    age: 365,  // After 365 days
                },
            },
            {
                action: {
                    type: "SetStorageClass",
                    storageClass: "NEARLINE",  // Archive to cheaper storage
                },
                condition: {
                    age: 90,  // After 90 days
                },
            },
        ],
        // ... other config
    });
    

    bucket-multi-region

    Severity: medium · Enforcement: advisory

    Require Cloud Storage buckets to have multi-region replication for business continuity

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Multi-Region Replication
    // Option 1: Use multi-region location
    const bucket = new gcp.storage.Bucket("my-bucket", {
        location: "US",  // Multi-region location (US, EU, or ASIA)
        // ... other config
    });
    
    // Option 2: Use dual-region location
    const bucket = new gcp.storage.Bucket("my-bucket", {
        location: "NAM4",  // Dual-region location
        // ... other config
    });
    
    // Option 3: Use custom placement with multiple data locations
    const bucket = new gcp.storage.Bucket("my-bucket", {
        location: "US",
        customPlacementConfig: {
            dataLocations: ["US-EAST1", "US-WEST1"],  // Specify at least 2 regions
        },
        // ... other config
    });
    

    bucket-public-access-prevention

    Severity: high · Enforcement: advisory

    Ensures Cloud Storage buckets have public access prevention enforced

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

    Set publicAccessPrevention: "enforced" on the bucket.

    bucket-public-read-prohibited

    Severity: high · Enforcement: advisory

    Ensure Cloud Storage bucket public read is prohibited

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

    Remove public read access from Cloud Storage buckets by ensuring IAM policies and ACLs do not grant allUsers or allAuthenticatedUsers read permissions. Set ‘publicAccessPrevention’ to ’enforced’ to prevent public access.

    bucket-soft-delete-retention

    Severity: medium · Enforcement: advisory

    Ensures Cloud Storage buckets have soft delete retention configured for at least 7 days

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

    Set softDeletePolicy.retentionDurationSeconds to at least 604800 (7 days).

    bucket-uniform-bucket-level-access

    Severity: high · Enforcement: advisory

    Ensures Cloud Storage buckets enable uniform bucket-level access

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

    Set uniformBucketLevelAccess: true on the bucket.

    certificate-manager-certificate-lifecycle-management

    Severity: medium · Enforcement: advisory

    Ensure proper certificate lifecycle management to prevent expiration

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

    Use managed certificates for automatic renewal to prevent expiration-related outages. Managed certificates handle renewal automatically through DNS or Load Balancer authorization.

    import * as gcp from "@pulumi/gcp";
    
    // RECOMMENDED: Managed certificate with automatic renewal via DNS
    const managedDnsCert = new gcp.certificatemanager.Certificate("managed-dns-cert", {
        name: "managed-dns-cert",
        description: "Auto-renewed certificate via DNS authorization",
        managed: {
            domains: ["example.com", "www.example.com"],
            dnsAuthorizations: [dnsAuthResource.id]
        }
    });
    
    // RECOMMENDED: Managed certificate with automatic renewal via Load Balancer
    const managedLbCert = new gcp.certificatemanager.Certificate("managed-lb-cert", {
        name: "managed-lb-cert",
        description: "Auto-renewed certificate via Load Balancer",
        managed: {
            domains: ["api.example.com"]
            // No dnsAuthorizations needed for Load Balancer authorization
        }
    });
    
    // NOT RECOMMENDED: Self-managed certificate requires manual renewal
    const selfManagedCert = new gcp.certificatemanager.Certificate("self-managed-cert", {
        name: "custom-cert",
        selfManaged: {
            pemCertificate: certPem,
            pemPrivateKey: keyPem
        }
    });
    

    cloud-armor-logging

    Severity: medium · Enforcement: advisory

    Ensure Cloud Armor security policies are attached to backend services with logging enabled

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

    Enable logging on backend services that use Cloud Armor security policies. Cloud Armor events are logged through the backend service’s access logs, not the security policy itself.

    import * as gcp from "@pulumi/gcp";
    
    // Step 1: Create Cloud Armor security policy
    const securityPolicy = new gcp.compute.SecurityPolicy("security-policy", {
        name: "my-security-policy",
        rules: [{
            action: "deny(403)",
            priority: 1000,
            match: {
                versionedExpr: "SRC_IPS_V1",
                config: {
                    srcIpRanges: ["192.168.1.0/24"]
                }
            }
        }]
    });
    
    // Step 2: CRITICAL - Attach to backend service with logging enabled
    const backend = new gcp.compute.BackendService("backend", {
        name: "backend-service",
        securityPolicy: securityPolicy.selfLink,
        logConfig: {
            enable: true,        // REQUIRED for Cloud Armor logging
            sampleRate: 1.0      // 1.0 = 100% logging, 0.5 = 50% sampling
        }
    });
    

    cloud-audit-logs-data-access-events-enabled

    Severity: high · Enforcement: advisory

    Enable Cloud Audit Logs data access events for monitoring

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

    Configure projects.IAMAuditConfig resources with auditLogConfigs including DATA_READ and DATA_WRITE log types for services handling sensitive data to monitor unauthorized access.

    Example - Enable Data Access Audit Logging:

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Enable data access logging for all services
    const auditConfigAll = new gcp.projects.IAMAuditConfig("audit-all-services", {
        project: "my-project-id",
        service: "allServices",  // Apply to all GCP services
        auditLogConfigs: [
            {
                logType: "ADMIN_READ"  // Administrative read operations
            },
            {
                logType: "DATA_READ",  // Compliant: Data read logging enabled
                exemptedMembers: []  // No exemptions
            },
            {
                logType: "DATA_WRITE"  // Compliant: Data write logging enabled
            }
        ]
    });
    
    // COMPLIANT: Enable data access logging for specific services
    const auditConfigStorage = new gcp.projects.IAMAuditConfig("audit-storage", {
        project: "my-project-id",
        service: "storage.googleapis.com",
        auditLogConfigs: [
            {
                logType: "DATA_READ",  // Compliant: Monitor bucket/object reads
                exemptedMembers: ["user:admin@example.com"]  // Optional exemptions
            },
            {
                logType: "DATA_WRITE"  // Compliant: Monitor bucket/object writes
            }
        ]
    });
    
    const auditConfigBigQuery = new gcp.projects.IAMAuditConfig("audit-bigquery", {
        project: "my-project-id",
        service: "bigquery.googleapis.com",
        auditLogConfigs: [
            {
                logType: "DATA_READ"   // Compliant: Monitor query operations
            },
            {
                logType: "DATA_WRITE"  // Compliant: Monitor data modifications
            }
        ]
    });
    
    // NON-COMPLIANT: Only ADMIN_READ enabled, missing data access logging
    const auditConfigIncomplete = new gcp.projects.IAMAuditConfig("audit-incomplete", {
        project: "my-project-id",
        service: "allServices",
        auditLogConfigs: [
            {
                logType: "ADMIN_READ"  // Only admin operations logged
                // Missing DATA_READ and DATA_WRITE
            }
        ]
    });
    
    // NON-COMPLIANT: No audit configuration at all
    // (missing IAMAuditConfig resource)
    

    cloud-audit-logs-integrity-monitoring-enabled

    Severity: high · Enforcement: advisory

    Ensure Cloud Audit Logs integrity monitoring is enabled

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

    Configure log buckets with locked retention policies to ensure audit log integrity. Set retentionDays to at least 90 days and enable locked: true on gcp.logging.LogBucket resources. Locked retention policies prevent modification or deletion, ensuring audit logs remain trustworthy. Route audit logs to BigQuery or Cloud Storage for tamper-evident long-term storage.

    cloud-audit-logs-multi-region-trail-enabled

    Severity: high · Enforcement: advisory

    Ensure Cloud Audit Logs multi-region trail is enabled

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

    Configure Cloud Audit Logs to export to a multi-region or dual-region Cloud Storage bucket. Update the logging sink destination to use a bucket with location set to ‘US’, ‘EU’, ‘ASIA’, or a dual-region location for high availability.

    cloud-build-logging

    Severity: medium · Enforcement: advisory

    Require Cloud Build triggers to have secure logging configurations

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Configure Secure Logging
    const trigger = new cloudbuild.Trigger("my-trigger", {
        build: {
            logsBucket: "gs://my-logs-bucket/build-logs",  // Configure centralized logs bucket
            options: {
                logging: "CLOUD_LOGGING_ONLY",  // Use Cloud Logging for audit trails
            },
            // ... other config
        },
        // ... other config
    });
    

    cloud-build-trigger-envvar-gcpcred-check

    Severity: high · Enforcement: advisory

    Ensure Cloud Build trigger environment variables do not contain GCP credentials

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

    Remove GCP credentials from Cloud Build trigger substitutions, build.options.envs, and step environment variables. Store credentials in Secret Manager and reference them using availableSecrets configuration. Grant Cloud Build service account access to the secrets.

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Using Secret Manager references
    const compliantTrigger = new gcp.cloudbuild.Trigger("compliant-trigger", {
        location: "us-central1",
        triggerTemplate: {
            branchName: "main",
            repoName: "my-repo",
        },
        substitutions: {
            _ENV: "production",
            _REGION: "us-central1",
        },
        filename: "cloudbuild.yaml",
    });
    
    // NON-COMPLIANT: Storing credentials in substitutions
    const badTrigger = new gcp.cloudbuild.Trigger("bad-trigger", {
        location: "us-central1",
        triggerTemplate: {
            branchName: "main",
            repoName: "my-repo",
        },
        substitutions: {
            _GCP_API_KEY: "AIzaSyD...", // Violates policy
            _SERVICE_ACCOUNT_KEY: '{"type":"service_account",...}', // Violates policy
        },
        filename: "cloudbuild.yaml",
    });
    
    // NON-COMPLIANT: Storing credentials in build options
    const badTriggerWithEnvs = new gcp.cloudbuild.Trigger("bad-trigger-envs", {
        name: "my-trigger",
        build: {
            options: {
                envs: [
                    "ENV = production",
                    "GCP_CREDENTIALS = {...}", // Violates policy
                ],
            },
            steps: [{
                name: "gcr.io/cloud-builders/gcloud",
                args: ["version"],
            }],
        },
    });
    

    cloud-build-trigger-source-repo-url-check

    Severity: medium · Enforcement: advisory

    Ensure Cloud Build trigger source repository URLs use secure protocols

    • CM-5 Access Restrictions for Change — The organization defines, documents, approves, and enforces logical access restrictions associated with changes to the information system.
    Remediation

    Update source repository URLs in sourceToBuild.uri, gitFileSource.uri, and other URL fields to use HTTPS protocol. Replace http://, git://, or ftp:// protocols with https:// or ssh:// (git@). Configure proper authentication for the repository connections.

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Using HTTPS protocol
    const compliantTrigger = new gcp.cloudbuild.Trigger("compliant-trigger", {
        name: "my-trigger",
        location: "us-central1",
        sourceToBuild: {
            uri: "https://github.com/my-org/my-repo", // Secure HTTPS
            ref: "refs/heads/main",
            repoType: "GITHUB",
        },
        filename: "cloudbuild.yaml",
    });
    
    // COMPLIANT: Using SSH protocol
    const compliantSshTrigger = new gcp.cloudbuild.Trigger("compliant-ssh-trigger", {
        name: "my-ssh-trigger",
        location: "us-central1",
        sourceToBuild: {
            uri: "git@github.com:my-org/my-repo.git", // Secure SSH
            ref: "refs/heads/main",
            repoType: "GITHUB",
        },
        filename: "cloudbuild.yaml",
    });
    
    // NON-COMPLIANT: Using insecure HTTP protocol
    const badTrigger = new gcp.cloudbuild.Trigger("bad-trigger", {
        name: "bad-trigger",
        location: "us-central1",
        sourceToBuild: {
            uri: "http://github.com/my-org/my-repo", // Violates policy - insecure HTTP
            ref: "refs/heads/main",
            repoType: "GITHUB",
        },
        filename: "cloudbuild.yaml",
    });
    
    // NON-COMPLIANT: Using insecure git:// protocol
    const badGitTrigger = new gcp.cloudbuild.Trigger("bad-git-trigger", {
        name: "bad-git-trigger",
        location: "us-central1",
        sourceToBuild: {
            uri: "git://github.com/my-org/my-repo.git", // Violates policy - insecure git://
            ref: "refs/heads/main",
            repoType: "GITHUB",
        },
        filename: "cloudbuild.yaml",
    });
    

    cloud-cdn-armor

    Severity: medium · Enforcement: advisory

    Require Cloud CDN to have Cloud Armor configuration for DDoS protection

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Attach Cloud Armor Security Policy to CDN
    // Create a Cloud Armor security policy
    const securityPolicy = new gcp.compute.SecurityPolicy("cdn-security-policy", {
        rules: [{
            action: "deny(403)",
            priority: 1000,
            match: {
                versionedExpr: "SRC_IPS_V1",
                config: {
                    srcIpRanges: ["9.9.9.0/24"],
                },
            },
            description: "Deny access to example IP range",
        }],
    });
    
    // For BackendService: attach security policy
    const backendService = new gcp.compute.BackendService("cdn-backend", {
        enableCdn: true,
        securityPolicy: securityPolicy.id,  // Attach Cloud Armor policy for DDoS protection
        // ... other config
    });
    
    // For BackendBucket: attach edge security policy
    const backendBucket = new gcp.compute.BackendBucket("cdn-bucket-backend", {
        enableCdn: true,
        edgeSecurityPolicy: securityPolicy.id,  // Attach Cloud Armor policy for DDoS protection
        // ... other config
    });
    

    cloud-cdn-logging-enabled

    Severity: high · Enforcement: advisory

    Ensure Cloud CDN has logging enabled for audit and monitoring

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

    Configure Backend Services with logConfig.enable: true when enableCdn: true. Set an appropriate sampleRate (0.0 to 1.0) to balance log volume with coverage. Logs are automatically sent to Cloud Logging for centralized management.

    Pulumi TypeScript example:

    import * as gcp from "@pulumi/gcp";
    
    // Create a backend service with Cloud CDN enabled and logging configured
    const backendService = new gcp.compute.BackendService("my-backend", {
        name: "my-backend-service",
        protocol: "HTTP",
        timeoutSec: 30,
        // Enable Cloud CDN
        enableCdn: true,
        // Configure CDN policy
        cdnPolicy: {
            cacheMode: "CACHE_ALL_STATIC",
            defaultTtl: 3600,
            clientTtl: 7200,
            maxTtl: 86400,
            negativeCaching: true,
        },
        // Enable logging for Cloud CDN
        logConfig: {
            enable: true,
            sampleRate: 1.0, // Log 100% of requests (adjust based on traffic volume)
        },
        backends: [{
            group: instanceGroup.id,
            balancingMode: "UTILIZATION",
            capacityScaler: 1.0,
        }],
        healthChecks: [healthCheck.id],
    });
    

    cloud-cdn-origin-tls

    Severity: high · Enforcement: advisory

    Require Cloud CDN to use secure TLS to origin

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable HTTPS Protocol for CDN Backend Service
    const backendService = new gcp.compute.BackendService("cdn-backend", {
        enableCdn: true,
        protocol: "HTTPS",  // Use HTTPS for secure communication to origin
        // ... other config
    });
    

    cloud-firestore-autoscaling-enabled

    Severity: medium · Enforcement: advisory

    Ensure Cloud Firestore autoscaling is enabled

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

    Configure Cloud Firestore in Native mode (type: FIRESTORE_NATIVE) for automatic scaling. Use OPTIMISTIC concurrency mode for better scalability and performance.

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Firestore Native mode with OPTIMISTIC concurrency (automatic scaling)
    const databaseCompliant = new gcp.firestore.Database("native-optimistic", {
        name: "production-db",
        locationId: "nam5",  // Multi-region for better availability
        type: "FIRESTORE_NATIVE",  // Compliant: has automatic scaling
        concurrencyMode: "OPTIMISTIC",  // Compliant: best for scalability
        appEngineIntegrationMode: "DISABLED",
        deleteProtectionState: "DELETE_PROTECTION_ENABLED",
        pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_ENABLED"
    });
    
    // NON-COMPLIANT: Firestore Native with PESSIMISTIC concurrency
    const databasePessimistic = new gcp.firestore.Database("native-pessimistic", {
        name: "db-pessimistic",
        locationId: "us-central1",
        type: "FIRESTORE_NATIVE",
        concurrencyMode: "PESSIMISTIC",  // Non-compliant: can limit throughput
        appEngineIntegrationMode: "DISABLED"
    });
    
    // NON-COMPLIANT: Datastore mode instead of Native mode
    const databaseDatastore = new gcp.firestore.Database("datastore-mode", {
        name: "datastore-db",
        locationId: "us-central1",
        type: "DATASTORE_MODE"  // Non-compliant: Native mode recommended for enhanced scaling
    });
    
    // NON-COMPLIANT: Single-region without multi-region availability
    const databaseSingleRegion = new gcp.firestore.Database("single-region", {
        name: "single-region-db",
        locationId: "us-west1",  // Non-compliant: not multi-region
        type: "FIRESTORE_NATIVE"
    });
    

    cloud-firestore-in-backup-plan

    Severity: high · Enforcement: advisory

    Perform automated backups for Cloud Firestore databases and maintain isolated recovery data

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

    Create backup schedules with appropriate retention periods. Enable point-in-time recovery by setting pointInTimeRecoveryEnablement to ‘POINT_IN_TIME_RECOVERY_ENABLED’.

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Firestore database with PITR and backup schedule
    const database = new gcp.firestore.Database("production-db", {
        name: "production-db",
        locationId: "nam5",
        type: "FIRESTORE_NATIVE",
        pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_ENABLED",  // Compliant
        deleteProtectionState: "DELETE_PROTECTION_ENABLED"
    });
    
    const backupSchedule = new gcp.firestore.BackupSchedule("daily-backup", {
        database: database.name,
        retention: "30d",  // Compliant: adequate retention period
        dailyRecurrence: {}  // Compliant: daily backups configured
    });
    
    // NON-COMPLIANT: Database without backup schedule
    const databaseNoBackup = new gcp.firestore.Database("no-backup-db", {
        name: "test-db",
        locationId: "us-central1",
        type: "FIRESTORE_NATIVE",
        pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_DISABLED"  // Non-compliant
        // Missing backup schedule
    });
    
    // NON-COMPLIANT: Backup schedule with insufficient retention
    const shortRetentionBackup = new gcp.firestore.BackupSchedule("short-backup", {
        database: database.name,
        retention: "3d",  // Non-compliant: less than 7 days
        dailyRecurrence: {}
    });
    
    // NON-COMPLIANT: Backup schedule without recurrence
    const noRecurrenceBackup = new gcp.firestore.BackupSchedule("no-recurrence", {
        database: database.name,
        retention: "30d"
        // Missing dailyRecurrence or weeklyRecurrence
    });
    

    cloud-functions-concurrency-check

    Severity: medium · Enforcement: advisory

    Configure Cloud Functions concurrency for monitoring

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

    For v1 functions, set maxInstances to limit concurrent executions. For v2 functions, configure serviceConfig.maxInstanceRequestConcurrency (1 for CPU-bound, 80+ for I/O-bound) and serviceConfig.maxInstanceCount. Base values on expected load and resource requirements for proper capacity monitoring.

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: 1st gen function with maxInstances configured
    const functionV1 = new gcp.cloudfunctions.Function("my-function-v1", {
        name: "example-function",
        runtime: "nodejs20",
        sourceArchiveBucket: bucket.name,
        sourceArchiveObject: archive.name,
        entryPoint: "helloWorld",
        triggerHttp: true,
        maxInstances: 10, // Limits concurrent instances
    });
    
    // COMPLIANT: 2nd gen function with concurrency settings
    const functionV2 = new gcp.cloudfunctionsv2.Function("my-function-v2", {
        name: "example-function-v2",
        location: "us-central1",
        buildConfig: {
            runtime: "nodejs20",
            entryPoint: "helloWorld",
            source: {
                storageSource: {
                    bucket: bucket.name,
                    object: archive.name,
                },
            },
        },
        serviceConfig: {
            maxInstanceCount: 10,
            maxInstanceRequestConcurrency: 80, // For I/O-bound functions
        },
    });
    
    // NON-COMPLIANT: Missing maxInstances
    const badFunction = new gcp.cloudfunctions.Function("bad-function", {
        name: "bad-example",
        runtime: "nodejs20",
        triggerHttp: true,
        // maxInstances not configured - violates policy
    });
    

    cloud-functions-inside-vpc

    Severity: high · Enforcement: advisory

    Ensure Cloud Functions are inside VPC

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

    Configure VPC connector for Cloud Functions:

    // Cloud Functions v1
    new gcp.cloudfunctions.Function("my-function", {
      vpcConnector: "projects/my-project/locations/us-central1/connectors/my-connector",
      vpcConnectorEgressSettings: "ALL_TRAFFIC", // or "PRIVATE_RANGES_ONLY"
    });
    
    // Cloud Functions v2
    new gcp.cloudfunctionsv2.Function("my-function-v2", {
      serviceConfig: {
        vpcConnector: "projects/my-project/locations/us-central1/connectors/my-connector",
        vpcConnectorEgressSettings: "ALL_TRAFFIC",
      },
    });
    

    cloud-logging-encrypted

    Severity: high · Enforcement: advisory

    Ensure Cloud Logging is encrypted

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

    Configure Cloud Logging buckets with customer-managed encryption keys (CMEK) for enhanced security. On gcp.logging.LogBucket or gcp.logging.ProjectBucketConfig resources, set cmekSettings with a kmsKeyName pointing to a Cloud KMS key. While GCP encrypts all log data by default with Google-managed keys, CMEK provides additional control and compliance capabilities.

    cloud-logging-retention-period-365

    Severity: high · Enforcement: advisory

    Ensure Cloud Logging log retention is 365 days or more

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

    Configure Cloud Logging buckets with retentionDays set to at least 365 days. Update gcp.logging.ProjectBucketConfig, gcp.logging.OrganizationBucketConfig, gcp.logging.FolderBucketConfig, or gcp.logging.BillingAccountBucketConfig resources to specify ‘retentionDays: 365’ or higher to maintain adequate audit trails for security investigations and compliance.

    cloud-run-service-configuration-check

    Severity: high · Enforcement: advisory

    Ensure Cloud Run service configuration check

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

    Remove IAM bindings that grant allUsers the roles/run.invoker role. Set service ingress annotation run.googleapis.com/ingress to internal or internal-and-cloud-load-balancing in metadata.annotations. Grant invocation permissions only to specific service accounts or users.

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Service with restricted ingress
    const compliantService = new gcp.cloudrun.Service("compliant-service", {
        name: "secure-service",
        location: "us-central1",
        metadata: {
            annotations: {
                "run.googleapis.com/ingress": "internal-and-cloud-load-balancing",
            },
        },
        template: {
            spec: {
                containers: [{
                    image: "gcr.io/my-project/my-image:latest",
                }],
            },
        },
    });
    
    // COMPLIANT: Grant access to specific user
    const specificAccess = new gcp.cloudrun.IamMember("specific-access", {
        service: compliantService.name,
        location: compliantService.location,
        role: "roles/run.invoker",
        member: "user:jane@example.com",
    });
    
    // NON-COMPLIANT: Public access via IAM
    const publicAccess = new gcp.cloudrun.IamMember("public-access", {
        service: compliantService.name,
        location: compliantService.location,
        role: "roles/run.invoker",
        member: "allUsers", // Violates policy
    });
    
    // NON-COMPLIANT: Service without ingress restrictions
    const badService = new gcp.cloudrun.Service("bad-service", {
        name: "public-service",
        location: "us-central1",
        metadata: {
            annotations: {
                "run.googleapis.com/ingress": "all", // Violates policy
            },
        },
        template: {
            spec: {
                containers: [{
                    image: "gcr.io/my-project/my-image:latest",
                }],
            },
        },
    });
    

    cloud-security-scanner-enabled

    Severity: high · Enforcement: advisory

    Ensure Cloud Security Scanner is enabled for vulnerability management

    • RA-5 Vulnerability Monitoring and Scanning — The organization monitors and scans for vulnerabilities in the information system and hosted applications and remediates legitimate vulnerabilities.
    Remediation

    Enable the Web Security Scanner API service (websecurityscanner.googleapis.com) in your project. Configure scan configurations for your web applications using gcp.securityscanner.ScanConfig resources. Specify starting URLs, authentication details, and scan schedules to ensure comprehensive vulnerability coverage.

    Example - Enable Web Security Scanner:

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Enable Web Security Scanner API and configure scan
    const scannerService = new gcp.projects.Service("scanner-api", {
        service: "websecurityscanner.googleapis.com"  // Compliant: API enabled
    });
    
    const scanConfig = new gcp.securityscanner.ScanConfig("web-scan", {
        displayName: "Production Web App Scan",
        startingUrls: ["https://myapp.example.com"],  // Compliant: URLs configured
        schedule: {
            scheduleTime: "0 2 * * *",  // Compliant: daily at 2 AM
            intervalDurationDays: 1
        },
        maxQps: 5,
        targetPlatforms: ["APP_ENGINE", "COMPUTE"]
    }, { dependsOn: [scannerService] });
    
    // NON-COMPLIANT: Web Security Scanner API not enabled
    // (no gcp.projects.Service resource for websecurityscanner.googleapis.com)
    
    // NON-COMPLIANT: Scanner API enabled but no scan configurations
    const scannerServiceOnly = new gcp.projects.Service("scanner-only", {
        service: "websecurityscanner.googleapis.com"
        // Missing ScanConfig resources
    });
    
    // NON-COMPLIANT: Scan config without schedule
    const scanConfigNoSchedule = new gcp.securityscanner.ScanConfig("no-schedule-scan", {
        displayName: "Manual Scan Only",
        startingUrls: ["https://app.example.com"]
        // Missing schedule - won't run automatically
    });
    
    // NON-COMPLIANT: Scan config without starting URLs
    const scanConfigNoUrls = new gcp.securityscanner.ScanConfig("no-urls-scan", {
        displayName: "Incomplete Scan",
        schedule: {
            scheduleTime: "0 2 * * *"
        }
        // Missing startingUrls - scanner can't run
    });
    

    cloud-sql-high-availability

    Severity: high · Enforcement: advisory

    Ensure Cloud SQL instances have regional high availability enabled

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

    Enable regional high availability for Cloud SQL instances by setting availabilityType to ‘REGIONAL’. This provides automatic failover and data replication across zones within a region.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.sql.DatabaseInstance("my-db-instance", {
        databaseVersion: "POSTGRES_15",
        region: "us-central1",
        settings: {
            tier: "db-f1-micro",
            availabilityType: "REGIONAL",
        },
    });
    

    cloud-sql-instance-deletion-protection-enabled

    Severity: high · Enforcement: advisory

    Ensure Cloud SQL instance deletion protection is enabled

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

    Enable deletion protection by setting deletionProtection to true. Also enable automated backups and point-in-time recovery for comprehensive data protection.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.sql.DatabaseInstance("my-db-instance", {
        databaseVersion: "POSTGRES_15",
        region: "us-central1",
        deletionProtection: true,
        settings: {
            tier: "db-f1-micro",
            backupConfiguration: {
                enabled: true,
                pointInTimeRecoveryEnabled: true,
            },
        },
    });
    

    cloud-sql-instance-not-publicly-accessible

    Severity: high · Enforcement: advisory

    Restrict public access for Cloud SQL instances

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

    Disable public IP by setting ipv4Enabled to false and configure privateNetwork in ipConfiguration. Remove authorized networks that allow 0.0.0.0/0 access.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.sql.DatabaseInstance("my-db-instance", {
        databaseVersion: "POSTGRES_15",
        region: "us-central1",
        settings: {
            tier: "db-f1-micro",
            ipConfiguration: {
                ipv4Enabled: false,
                privateNetwork: "projects/my-project/global/networks/my-vpc",
            },
        },
    });
    

    cloud-sql-logging-enabled

    Severity: high · Enforcement: advisory

    Enable Cloud SQL logging for monitoring

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

    Enable database logging flags via databaseFlags. For PostgreSQL: set log_connections, log_disconnections, log_checkpoints to ‘on’. For MySQL: enable general_log or slow_query_log.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.sql.DatabaseInstance("db-with-logging", {
        databaseVersion: "POSTGRES_15",
        region: "us-central1",
        settings: {
            tier: "db-f1-micro",
            databaseFlags: [
                { name: "log_connections", value: "on" },
                { name: "log_disconnections", value: "on" },
                { name: "log_checkpoints", value: "on" },
            ],
        },
    });
    

    cloud-sql-storage-encrypted

    Severity: high · Enforcement: advisory

    Ensure Cloud SQL storage is encrypted

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

    Configure customer-managed encryption keys (CMEK) by setting encryptionKeyName to a Cloud KMS key for enhanced security and key management control.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.sql.DatabaseInstance("my-db-instance", {
        databaseVersion: "POSTGRES_15",
        region: "us-central1",
        encryptionKeyName: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",
        settings: {
            tier: "db-f1-micro",
        },
    });
    

    cloud-storage-bucket-iam-policy-grantee-check

    Severity: high · Enforcement: advisory

    Ensure Cloud Storage bucket IAM policy grantee check

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

    Remove IAM policy bindings that grant access to allUsers or allAuthenticatedUsers. Use Cloud IAM to grant access only to specific service accounts, users, or groups.

    cloud-storage-bucket-public-write-prohibited

    Severity: critical · Enforcement: advisory

    Ensure Cloud Storage bucket public write is prohibited

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

    Remove IAM policy bindings that grant write permissions to allUsers or allAuthenticatedUsers. Ensure bucket ACLs do not grant WRITE or FULL_CONTROL to public principals.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const bucket = new gcp.storage.Bucket("secure-bucket", {
        location: "US",
        uniformBucketLevelAccess: true,
        publicAccessPrevention: "enforced",
    });
    
    // Do NOT add IAM bindings like this:
    // new gcp.storage.BucketIAMMember("bad-binding", {
    //     bucket: bucket.name,
    //     role: "roles/storage.objectCreator",
    //     member: "allUsers",  // NEVER use allUsers/allAuthenticatedUsers
    // });
    

    cloud-storage-bucket-versioning-enabled

    Severity: high · Enforcement: advisory

    Ensure Cloud Storage bucket versioning is enabled

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

    Enable versioning on Cloud Storage buckets by setting versioning.enabled to true to protect against accidental deletion or modification.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const bucket = new gcp.storage.Bucket("versioned-bucket", {
        location: "US",
        versioning: {
            enabled: true,
        },
    });
    

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const bucket = new gcp.storage.Bucket("my-bucket", {
        location: "US",
        versioning: {
            enabled: true,
        },
    });
    

    cloud-tasks-retry-configuration

    Severity: medium · Enforcement: advisory

    Require Cloud Tasks queues to have proper retry configuration for business continuity

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Configure Retry Policy with Max Attempts
    const queue = new gcp.cloudtasks.Queue("my-queue", {
        retryConfig: {
            maxAttempts: 10,  // Set reasonable max retry attempts
            maxRetryDuration: "3600s",  // Set max retry duration (1 hour)
            minBackoff: "0.1s",
            maxBackoff: "3600s",
        },
        // ... other config
    });
    

    cloudfunctions-documentation

    Severity: low · Enforcement: advisory

    Require Cloud Functions to have adequate documentation

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Add Function Documentation
    const func = new gcp.cloudfunctions.Function("my-function", {
        description: "Processes customer orders from Pub/Sub and stores results in BigQuery",  // Add descriptive documentation
        labels: {
            purpose: "order-processing",  // Document function purpose
            team: "backend-team",  // Document ownership
            // ... other labels
        },
        // ... other config
    });
    

    cloudfunctions-execution-time

    Severity: low · Enforcement: advisory

    Limit Cloud Functions execution time to prevent extended access

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Limit Execution Timeout
    const func = new gcp.cloudfunctions.Function("my-function", {
        timeout: 60,  // Set reasonable timeout in seconds (max 540)
        // ... other config
    });
    
    // For Cloud Functions v2
    const funcV2 = new gcp.cloudfunctionsv2.Function("my-function-v2", {
        serviceConfig: {
            timeoutSeconds: 60,  // Set reasonable timeout in seconds (max 540)
        },
        // ... other config
    });
    

    cloudfunctions-iam-no-public

    Severity: high · Enforcement: advisory

    Require Cloud Functions IAM bindings to not grant public access

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Use Specific IAM Members
    const iamMember = new gcp.cloudfunctions.FunctionIamMember("my-function-invoker", {
        cloudFunction: myFunction.name,
        role: "roles/cloudfunctions.invoker",
        member: "serviceAccount:my-service@project.iam.gserviceaccount.com",
        // ... other config
    });
    

    cloudfunctions-kms-env-vars

    Severity: medium · Enforcement: advisory

    Require Cloud Functions environment variables to be encrypted with Cloud KMS

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Encrypt Environment Variables with KMS
    const func = new gcp.cloudfunctions.Function("my-function", {
        environmentVariables: {
            API_KEY: "sensitive-value",
            DATABASE_URL: "postgres://...",
        },
        kmsKeyName: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Add KMS key for encryption
        // ... other config
    });
    

    cloudfunctions-logging

    Severity: low · Enforcement: advisory

    Require Cloud Functions to have logging configuration enabled

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Logging Configuration
    const func = new gcp.cloudfunctions.Function("my-function", {
        environmentVariables: {
            LOG_FORMAT: "json",  // Enable structured logging
            LOG_LEVEL: "INFO",  // Set appropriate log level
        },
        labels: {
            "log-sink": "cloud-logging",  // Configure log sink
        },
        // ... other config
    });
    

    cloudfunctions-runtime-versions

    Severity: medium · Enforcement: advisory

    Restrict Cloud Functions to approved runtime versions only

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Use Approved Runtime Version
    const func = new gcp.cloudfunctions.Function("my-function", {
        runtime: "nodejs20",  // Use current supported runtime (e.g., nodejs20, python311, go121)
        // ... other config
    });
    

    cloudsql-authorized-networks-restricted

    Severity: high · Enforcement: advisory

    Ensures Cloud SQL instances do not allow overly broad authorized networks

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

    Remove or replace overly broad authorized networks with specific IP ranges. Avoid 0.0.0.0/0, /8, and /16 CIDR blocks.

    cloudsql-backup

    Severity: high · Enforcement: advisory

    Perform automated backups for Cloud SQL instances

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

    Enable automated backups by setting backupConfiguration.enabled to true. Configure startTime, pointInTimeRecoveryEnabled, and backupRetentionSettings with at least 7 days retention.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.sql.DatabaseInstance("my-db-instance", {
        databaseVersion: "POSTGRES_15",
        region: "us-central1",
        settings: {
            tier: "db-f1-micro",
            backupConfiguration: {
                enabled: true,
                startTime: "03:00",
                pointInTimeRecoveryEnabled: true,
                backupRetentionSettings: {
                    retainedBackups: 7,
                    retentionUnit: "COUNT",
                },
            },
        },
    });
    

    cloudsql-patching

    Severity: medium · Enforcement: advisory

    Require Cloud SQL instances to use managed service patching

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Configure Maintenance Window for Automatic Patching
    const sqlInstance = new gcp.sql.DatabaseInstance("my-sql-instance", {
        databaseVersion: "POSTGRES_15",
        settings: {
            maintenanceWindow: {
                updateTrack: "stable",  // Use stable update track for patching
                day: 7,  // Saturday (1=Sunday, 7=Saturday)
                hour: 3,  // 3 AM
            },
            // ... other config
        },
    });
    

    cloudsql-secure-credentials

    Severity: high · Enforcement: advisory

    Require Cloud SQL instances to use secure master credentials management

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Use IAM Authentication and Secure Password Management
    // For Cloud SQL instance: Enable IAM authentication
    const sqlInstance = new gcp.sql.DatabaseInstance("my-sql-instance", {
        databaseVersion: "POSTGRES_15",
        settings: {
            databaseFlags: [
                {
                    name: "cloudsql_iam_authentication",
                    value: "on",  // Enable IAM authentication
                },
            ],
            passwordValidationPolicy: {
                enablePasswordPolicy: true,  // Enable password validation
            },
            // ... other config
        },
        // Do not set rootPassword - use auto-generated or Secret Manager
    });
    
    // For Cloud SQL users: Use IAM-based authentication
    const sqlUser = new gcp.sql.User("my-sql-user", {
        instance: sqlInstance.name,
        name: "user@example.com",
        type: "CLOUD_IAM_USER",  // Use IAM user type instead of built-in
        // Do not set password field for IAM users
    });
    

    cloudsql-ssl

    Severity: high · Enforcement: advisory

    Require Cloud SQL connections to use SSL/TLS encryption

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Require SSL/TLS for All Connections
    const sqlInstance = new gcp.sql.DatabaseInstance("my-sql-instance", {
        databaseVersion: "POSTGRES_15",
        settings: {
            ipConfiguration: {
                sslMode: "ENCRYPTED_ONLY",  // Require SSL/TLS for all connections
                // ... other config
            },
        },
    });
    

    compute-engine-instance-detailed-monitoring-enabled

    Severity: medium · Enforcement: advisory

    Enable Compute Engine instance detailed monitoring

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

    Enable shieldedInstanceConfig with enableIntegrityMonitoring set to true. Add metadata keys ’enable-guest-attributes: TRUE’ and ’enable-oslogin: TRUE’. Install the Ops Agent for comprehensive monitoring.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.compute.Instance("monitored-instance", {
        machineType: "e2-medium",
        zone: "us-central1-a",
        shieldedInstanceConfig: {
            enableIntegrityMonitoring: true,
            enableVtpm: true,
        },
        metadata: {
            "enable-guest-attributes": "TRUE",
            "enable-oslogin": "TRUE",
        },
        bootDisk: { /* ... */ },
        networkInterfaces: [{ /* ... */ }],
    });
    

    compute-engine-instance-in-vpc

    Severity: high · Enforcement: advisory

    Ensure Compute Engine instances are deployed in VPC networks

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

    Deploy instances in custom VPC with explicit subnetwork:

    new gcp.compute.Instance("my-instance", {
      networkInterfaces: [{
        network: customVpc.id,
        subnetwork: customSubnet.id,
        // Specify explicit VPC and subnet
      }],
      // ... other config
    });
    

    Avoid using legacy default networks.

    compute-engine-instance-not-publicly-accessible

    Severity: high · Enforcement: advisory

    Ensure Compute Engine instances are not publicly accessible

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation

    Remove accessConfigs from networkInterfaces to disable external IP assignment:

    new gcp.compute.Instance("my-instance", {
      networkInterfaces: [{
        network: "my-vpc",
        subnetwork: "my-subnet",
        // accessConfigs: [], // Remove or set to empty array
      }],
      canIpForward: false,
    });
    

    Use Cloud NAT or load balancers for controlled external access.

    compute-engine-instance-os-config-managed

    Severity: high · Enforcement: advisory

    Ensure Compute Engine instances are managed with OS Config

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

    Enable OS Config management by adding metadata key ’enable-osconfig: TRUE’ to enable centralized patch management, security updates, and configuration compliance.

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.compute.Instance("managed-instance", {
        machineType: "e2-medium",
        zone: "us-central1-a",
        metadata: {
            "enable-osconfig": "TRUE",  // REQUIRED: Enable OS Config management
        },
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
            },
        },
        networkInterfaces: [{
            network: "default",
            accessConfigs: [{}],
        }],
    });
    

    Benefits of OS Config:

    • Automated security patching
    • Vulnerability detection and reporting
    • Configuration drift detection
    • Centralized compliance monitoring

    compute-engine-instance-proper-configuration

    Severity: medium · Enforcement: advisory

    Ensure Compute Engine instances have proper configuration for lifecycle management

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

    Configure instances with appropriate settings based on their type:

    For production instances:

    import * as gcp from "@pulumi/gcp";
    
    const productionInstance = new gcp.compute.Instance("prod-instance", {
        machineType: "e2-medium",
        zone: "us-central1-a",
        scheduling: {
            automaticRestart: true,         // Ensure high availability
            onHostMaintenance: "MIGRATE",   // Migrate during maintenance
            preemptible: false,             // Use standard instances for production
        },
        deletionProtection: true,           // Protect production resources
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
                size: 100,
                type: "pd-ssd",             // Use SSD for production
            },
            autoDelete: false,              // Preserve data on instance deletion
        },
        networkInterfaces: [{
            network: "default",
            accessConfigs: [{}],
        }],
    });
    

    For temporary/development instances:

    const tempInstance = new gcp.compute.Instance("temp-instance", {
        machineType: "e2-medium",
        zone: "us-central1-a",
        scheduling: {
            preemptible: true,              // Use preemptible for cost savings
            automaticRestart: false,        // Don't restart when preempted
            onHostMaintenance: "TERMINATE", // Terminate on maintenance
        },
        deletionProtection: false,         // Allow easy cleanup
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
                size: 20,
                type: "pd-standard",        // Use standard disk for dev
            },
            autoDelete: true,               // Clean up disk with instance
        },
        networkInterfaces: [{
            network: "default",
            accessConfigs: [{}],
        }],
    });
    

    compute-engine-instance-service-account-attached

    Severity: high · Enforcement: advisory

    Ensure Compute Engine instances have service accounts attached

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

    Attach a custom service account with explicit scopes:

    new gcp.compute.Instance("my-instance", {
      serviceAccount: {
        email: customServiceAccount.email,
        scopes: [
          "https://www.googleapis.com/auth/cloud-platform",
        ],
      },
      // ... other config
    });
    

    Avoid using the default compute service account.

    compute-engine-instance-uses-os-login

    Severity: high · Enforcement: advisory

    Ensure Compute Engine instances enforce OS Login

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

    Add metadata keys to enable OS Login:

    new gcp.compute.Instance("my-instance", {
      metadata: {
        "enable-oslogin": "TRUE",
        "block-project-ssh-keys": "TRUE",
        "enable-oslogin-2fa": "TRUE", // For production instances
      },
      // ... other config
    });
    

    This enables centralized SSH authentication via IAM.

    compute-engine-optimized-instance

    Severity: medium · Enforcement: advisory

    Ensure Compute Engine instances are optimized for backup and maintain isolated recovery data

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

    Enable deletion protection and configure boot disk:

    new gcp.compute.Instance("my-instance", {
      deletionProtection: true,
      bootDisk: {
        autoDelete: false,
        initializeParams: {
          type: "pd-ssd", // Use persistent disk type
        },
      },
      labels: {
        "backup": "enabled",
        "critical": "true",
      },
    });
    

    Avoid scratch disks for data requiring backup.

    compute-engine-os-config-compliance-association-compliant

    Severity: high · Enforcement: advisory

    Ensure OS Config managed instances have compliance association

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

    Add compliance labels such as ‘patch-group’ or ‘compliance-policy’ to instances with OS Config enabled. Enable OS Config by setting metadata ’enable-osconfig’ to ‘TRUE’ for proper vulnerability scanning and patch management tracking.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const instance = new gcp.compute.Instance("compliant-instance", {
        machineType: "e2-medium",
        zone: "us-central1-a",
        metadata: {
            "enable-osconfig": "TRUE",
        },
        labels: {
            "patch-group": "production",
            "compliance-policy": "cis-benchmark",
        },
        bootDisk: { /* ... */ },
        networkInterfaces: [{ /* ... */ }],
    });
    

    compute-engine-os-config-compliance-patch-compliant

    Severity: high · Enforcement: advisory

    Ensure OS Config managed instances have patch compliance

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

    Enable OS Config on instances by setting metadata ’enable-osconfig: TRUE’. Create patch deployment policies with schedules and instance filters. Configure patchConfig with reboot settings and update classifications.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const patchDeployment = new gcp.osconfig.PatchDeployment("weekly-patch", {
        patchDeploymentId: "weekly-patches",
        instanceFilter: {
            all: true,
        },
        recurringSchedule: {
            timeZone: { id: "UTC" },
            weekly: { dayOfWeek: "SUNDAY" },
        },
        patchConfig: {
            rebootConfig: "DEFAULT",
        },
    });
    

    compute-instance-encrypted-attached-disk

    Severity: medium · Enforcement: advisory

    Require Compute Engine instances to have encrypted attached disks

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Encrypt Attached Disks with CMEK
    const instance = new compute.Instance("my-instance", {
        attachedDisks: [{
            source: myDisk.selfLink,
            kmsKeySelfLink: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Use CMEK for attached disk encryption
        }],
        // ... other config
    });
    

    compute-instance-encrypted-boot-disk

    Severity: medium · Enforcement: advisory

    Require Compute Engine instances to have encrypted boot disks

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Boot Disk Encryption with CMEK
    const instance = new compute.Instance("my-instance", {
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
            },
            kmsKeySelfLink: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Use customer-managed encryption key
        },
        // ... other config
    });
    

    compute-osconfig-vulnerability

    Severity: medium · Enforcement: advisory

    Require OS Config agent for vulnerability management on compute instances

    • RA-5 Vulnerability Monitoring and Scanning — The organization monitors and scans for vulnerabilities in the information system and hosted applications and remediates legitimate vulnerabilities.
    Remediation
    Fix: Enable OS Config Agent
    const instance = new compute.Instance("my-instance", {
        metadata: {
            "enable-osconfig": "TRUE",  // Enable OS Config for vulnerability scanning
            "enable-guest-attributes": "TRUE",  // Enable guest attributes for older agent versions
        },
        // ... other config
    });
    

    database-migration-service-not-publicly-accessible

    Severity: high · Enforcement: advisory

    Prevent public accessibility of Database Migration Service instances

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

    Configure connection profiles to use private connectivity (VPC peering or Private Service Connect) instead of public IP addresses. Ensure SSL is configured with CA certificates.

    Example - Secure Database Migration Service Connection Profiles:

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: MySQL connection profile with SSL and private IP
    const mysqlCompliant = new gcp.databasemigrationservice.ConnectionProfile("mysql-private", {
        location: "us-central1",
        connectionProfileId: "mysql-private-profile",
        displayName: "MySQL Private Connection",
        mysql: {
            host: "10.0.0.5",  // Compliant: private IP address
            port: 3306,
            username: "migration-user",
            password: sqldbUser.password,
            ssl: {  // Compliant: SSL configured
                clientKey: sqlClientCert.privateKey,
                clientCertificate: sqlClientCert.cert,
                caCertificate: sqlClientCert.serverCaCert,
                type: "SERVER_CLIENT"
            }
        }
    });
    
    // COMPLIANT: PostgreSQL with internal hostname and SSL
    const postgresCompliant = new gcp.databasemigrationservice.ConnectionProfile("postgres-private", {
        location: "us-central1",
        connectionProfileId: "postgres-private-profile",
        displayName: "PostgreSQL Private Connection",
        postgresql: {
            host: "db.internal.example.com",  // Compliant: internal hostname
            port: 5432,
            username: "migration-user",
            password: pgUser.password,
            ssl: {  // Compliant: SSL configured
                clientCertificate: pgClientCert.cert,
                caCertificate: pgClientCert.serverCaCert
            }
        }
    });
    
    // NON-COMPLIANT: MySQL connection without SSL
    const mysqlNoSsl = new gcp.databasemigrationservice.ConnectionProfile("mysql-no-ssl", {
        location: "us-central1",
        connectionProfileId: "mysql-insecure",
        mysql: {
            host: "203.0.113.10",  // Public IP
            port: 3306,
            username: "user",
            password: "password"
            // Missing ssl configuration
        }
    });
    
    // NON-COMPLIANT: PostgreSQL with public IP and no SSL
    const postgresPublic = new gcp.databasemigrationservice.ConnectionProfile("postgres-public", {
        location: "us-central1",
        connectionProfileId: "postgres-public",
        postgresql: {
            host: "198.51.100.20",  // Non-compliant: public IP
            port: 5432,
            username: "user",
            password: "password"
            // Missing ssl configuration
        }
    });
    

    dataflow-kms

    Severity: high · Enforcement: advisory

    Require Dataflow jobs and pipelines to use customer-managed Cloud KMS keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure KMS Encryption for Dataflow
    const job = new dataflow.Job("my-job", {
        kmsKeyName: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Use CMEK for data encryption
        // ... other config
    });
    
    // For Dataflow Pipeline
    const pipeline = new dataflow.Pipeline("my-pipeline", {
        workload: {
            dataflowFlexTemplateRequest: {
                launchParameter: {
                    environment: {
                        kmsKeyName: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Use CMEK for data encryption
                    },
                },
            },
        },
        // ... other config
    });
    

    dataproc-cluster-master-nodes-no-public-ip

    Severity: high · Enforcement: advisory

    Restrict public access for Dataproc clusters by ensuring master nodes use internal IP addresses only

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

    Set clusterConfig.gceClusterConfig.internalIpOnly: true for the Dataproc cluster. Enable Private Google Access on the VPC subnet. Use Cloud NAT or VPN/Interconnect for required external connectivity. Configure firewall rules for internal communication.

    import * as gcp from "@pulumi/gcp";
    
    const privateDataprocCluster = new gcp.dataproc.Cluster("private-dataproc", {
        name: "private-dataproc-cluster",
        region: "us-central1",
        clusterConfig: {
            gceClusterConfig: {
                // Disable external IPs for all nodes including master
                internalIpOnly: true,
                network: "projects/my-project/global/networks/my-vpc",
                subnetwork: "projects/my-project/regions/us-central1/subnetworks/my-subnet",
                zone: "us-central1-a",
                // Optional: Configure service account with necessary permissions
                serviceAccount: "dataproc-sa@my-project.iam.gserviceaccount.com",
                serviceAccountScopes: [
                    "https://www.googleapis.com/auth/cloud-platform",
                ],
            },
            masterConfig: {
                numInstances: 1,
                machineType: "n2-standard-4",
                diskConfig: {
                    bootDiskSizeGb: 100,
                    bootDiskType: "pd-standard",
                },
            },
            workerConfig: {
                numInstances: 2,
                machineType: "n2-standard-4",
            },
        },
    });
    

    dataproc-kerberos-enabled

    Severity: medium · Enforcement: advisory

    Ensure Dataproc Kerberos is enabled

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

    Configure clusterConfig.securityConfig.kerberosConfig with enableKerberos: true. Store Kerberos credentials in Secret Manager and provide URIs for rootPrincipalPasswordUri, keyPasswordUri, keystorePasswordUri, and truststorePasswordUri. Configure realm and KDC settings as needed.

    import * as gcp from "@pulumi/gcp";
    
    // First, create secrets in Secret Manager for Kerberos passwords
    const rootPassword = new gcp.secretmanager.Secret("kerberos-root-pwd", {
        secretId: "dataproc-kerberos-root-password",
        replication: { auto: {} },
    });
    
    const keystorePassword = new gcp.secretmanager.Secret("kerberos-keystore-pwd", {
        secretId: "dataproc-kerberos-keystore-password",
        replication: { auto: {} },
    });
    
    const truststorePassword = new gcp.secretmanager.Secret("kerberos-truststore-pwd", {
        secretId: "dataproc-kerberos-truststore-password",
        replication: { auto: {} },
    });
    
    const keyPassword = new gcp.secretmanager.Secret("kerberos-key-pwd", {
        secretId: "dataproc-kerberos-key-password",
        replication: { auto: {} },
    });
    
    // Create Dataproc cluster with Kerberos enabled
    const kerberosCluster = new gcp.dataproc.Cluster("kerberos-dataproc", {
        name: "secure-dataproc-cluster",
        region: "us-central1",
        clusterConfig: {
            securityConfig: {
                kerberosConfig: {
                    // Enable Kerberos authentication
                    enableKerberos: true,
                    // Reference secrets stored in Secret Manager
                    rootPrincipalPasswordUri: rootPassword.name.apply(name =>
                        `projects/my-project/secrets/${name}/versions/latest`
                    ),
                    keyPasswordUri: keyPassword.name.apply(name =>
                        `projects/my-project/secrets/${name}/versions/latest`
                    ),
                    keystorePasswordUri: keystorePassword.name.apply(name =>
                        `projects/my-project/secrets/${name}/versions/latest`
                    ),
                    truststorePasswordUri: truststorePassword.name.apply(name =>
                        `projects/my-project/secrets/${name}/versions/latest`
                    ),
                    // Optional: Configure realm and KDC
                    realm: "DATAPROC.EXAMPLE.COM",
                    // Optional: Cross-realm trust configuration
                    // crossRealmTrustRealm: "EXTERNAL.EXAMPLE.COM",
                    // crossRealmTrustKdc: "kdc.external.example.com",
                },
            },
            gceClusterConfig: {
                network: "projects/my-project/global/networks/my-vpc",
                subnetwork: "projects/my-project/regions/us-central1/subnetworks/my-subnet",
            },
        },
    });
    

    elasticsearch-encrypted-at-rest

    Severity: high · Enforcement: advisory

    Ensure Elasticsearch is encrypted at rest

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

    Configure bootDisk.kmsKeySelfLink for boot disks and diskEncryptionKeyRaw or kmsKeySelfLink for attached disks. Create Cloud KMS keys in the same region as the instance and grant the Compute Engine service account encrypt/decrypt permissions. All disks are encrypted by default with Google-managed keys; use CMEK for enhanced control.

    import * as gcp from "@pulumi/gcp";
    
    // Create KMS key ring and key for disk encryption
    const keyRing = new gcp.kms.KeyRing("elasticsearch-keyring", {
        name: "elasticsearch-disk-encryption",
        location: "us-central1",
    });
    
    const cryptoKey = new gcp.kms.CryptoKey("elasticsearch-key", {
        name: "elasticsearch-disk-key",
        keyRing: keyRing.id,
        rotationPeriod: "7776000s", // 90 days
    });
    
    // Grant Compute Engine service account permission to use the key
    const computeSA = gcp.compute.getDefaultServiceAccount({});
    const keyIAM = new gcp.kms.CryptoKeyIAMMember("compute-encrypter-decrypter", {
        cryptoKeyId: cryptoKey.id,
        role: "roles/cloudkms.cryptoKeyEncrypterDecrypter",
        member: computeSA.then(sa => `serviceAccount:${sa.email}`),
    });
    
    // Elasticsearch instance with CMEK-encrypted disks
    const encryptedElasticsearch = new gcp.compute.Instance("encrypted-elasticsearch", {
        name: "elasticsearch-encrypted",
        machineType: "n2-standard-8",
        zone: "us-central1-a",
        labels: {
            app: "elasticsearch",
        },
        // Boot disk with customer-managed encryption key
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
                size: 100,
            },
            kmsKeySelfLink: cryptoKey.id,
        },
        // Attached data disk with encryption
        attachedDisks: [{
            source: new gcp.compute.Disk("elasticsearch-data-disk", {
                name: "elasticsearch-data",
                zone: "us-central1-a",
                size: 500,
                type: "pd-ssd",
                diskEncryptionKey: {
                    kmsKeySelfLink: cryptoKey.id,
                },
            }).selfLink,
            kmsKeySelfLink: cryptoKey.id,
        }],
        networkInterfaces: [{
            network: "default",
        }],
    });
    
    // Alternative: Create separate persistent disk with encryption
    const elasticsearchDataDisk = new gcp.compute.Disk("elasticsearch-persistent-disk", {
        name: "elasticsearch-data-disk",
        zone: "us-central1-a",
        size: 1000, // 1TB for Elasticsearch data
        type: "pd-ssd",
        diskEncryptionKey: {
            kmsKeySelfLink: cryptoKey.id,
        },
    });
    

    elasticsearch-in-vpc-only

    Severity: high · Enforcement: advisory

    Ensure Elasticsearch is in VPC only

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

    Remove accessConfigs from networkInterfaces to disable external IP assignment for instances running Elasticsearch. Ensure instances are deployed within a VPC subnet. Access Elasticsearch through private networking or VPN/Interconnect only.

    import * as gcp from "@pulumi/gcp";
    
    // Elasticsearch instance with no external IP (VPC-only access)
    const elasticsearchInstance = new gcp.compute.Instance("elasticsearch-node", {
        name: "elasticsearch-node-1",
        machineType: "n2-standard-8",
        zone: "us-central1-a",
        labels: {
            environment: "production",
        },
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
                size: 100,
            },
        },
        networkInterfaces: [{
            network: "projects/my-project/global/networks/my-vpc",
            subnetwork: "projects/my-project/regions/us-central1/subnetworks/private-subnet",
            // IMPORTANT: No accessConfigs means no external IP
            // Instance is only accessible within VPC or via VPN/Interconnect
        }],
        // Optional: Add startup script to install Elasticsearch
        metadataStartupScript: `#!/bin/bash
            # Install and configure Elasticsearch
            wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
            echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list
            apt-get update && apt-get install -y elasticsearch
            systemctl enable elasticsearch
            systemctl start elasticsearch
        `,
        serviceAccount: {
            email: "elasticsearch-sa@my-project.iam.gserviceaccount.com",
            scopes: ["https://www.googleapis.com/auth/cloud-platform"],
        },
    });
    
    // Optional: Create firewall rule to allow Elasticsearch access from within VPC
    const elasticsearchFirewall = new gcp.compute.Firewall("elasticsearch-internal", {
        network: "projects/my-project/global/networks/my-vpc",
        allows: [{
            protocol: "tcp",
            ports: ["9200", "9300"],
        }],
        sourceRanges: ["10.0.0.0/8"], // Only allow from private IP ranges
        targetTags: ["elasticsearch"],
    });
    

    elasticsearch-logs-to-cloud-logging

    Severity: medium · Enforcement: advisory

    Ensure instances have proper Cloud Logging configuration

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

    Configure Compute Engine instances with the Ops Agent for log forwarding. Ensure service accounts have proper scopes for Cloud Logging API access. Install logging agents via startup scripts or custom images.

    import * as gcp from "@pulumi/gcp";
    
    // Service account with logging permissions
    const loggingSA = new gcp.serviceaccount.Account("logging-sa", {
        accountId: "instance-logger",
        displayName: "Instance Logging Service Account",
    });
    
    // Grant logging.logWriter role to service account
    const loggingRole = new gcp.projects.IAMMember("logging-role", {
        project: "my-project",
        role: "roles/logging.logWriter",
        member: loggingSA.email.apply(email => `serviceAccount:${email}`),
    });
    
    // Instance with proper logging configuration
    const instanceWithLogging = new gcp.compute.Instance("instance-with-logging", {
        name: "app-instance",
        machineType: "n2-standard-4",
        zone: "us-central1-a",
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
            },
        },
        networkInterfaces: [{
            network: "default",
            subnetwork: "default",
        }],
        serviceAccount: {
            email: loggingSA.email,
            // IMPORTANT: Include cloud-platform scope for logging APIs
            scopes: ["https://www.googleapis.com/auth/cloud-platform"],
        },
        // Install Ops Agent for log forwarding
        metadataStartupScript: `#!/bin/bash
            # Install Google Cloud Ops Agent
            curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh
            bash add-google-cloud-ops-agent-repo.sh --also-install
    
            # Configure Ops Agent for application logs
            cat > /etc/google-cloud-ops-agent/config.yaml <<EOF
    logging:
      receivers:
        app_logs:
          type: files
          include_paths:
            - /var/log/app/*.log
            - /var/log/app/*.json
      processors:
        app_parser:
          type: parse_json
      service:
        pipelines:
          app_pipeline:
            receivers: [app_logs]
            processors: [app_parser]
    EOF
    
            # Restart Ops Agent to apply configuration
            systemctl restart google-cloud-ops-agent
        `,
        // Alternative: Use metadata for logging configuration
        metadata: {
            "google-logging-enabled": "true",
            "google-monitoring-enabled": "true",
        },
    });
    

    environment-label

    Severity: low · Enforcement: advisory

    Require all labelable resources to have an environment label

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Add Valid Environment Label

    Add an environment label with a valid value (development, staging, or production) to your GCP resources:

    const instance = new gcp.compute.Instance("my-instance", {
        labels: {
            environment: "production",  // Required: valid environment label
            // ... other labels
        },
        // ... other config
    });
    
    // For Cloud SQL instances, use userLabels within settings
    const sqlInstance = new gcp.sql.DatabaseInstance("my-database", {
        settings: {
            userLabels: {
                environment: "staging",  // Required: valid environment label
            },
            // ... other settings
        },
        // ... other config
    });
    
    // For GKE clusters, use resourceLabels
    const cluster = new gcp.container.Cluster("my-cluster", {
        resourceLabels: {
            environment: "development",  // Required: valid environment label
        },
        // ... other config
    });
    

    filestore-cmek

    Severity: high · Enforcement: advisory

    Ensure Cloud Filestore is encrypted

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

    firestore-pitr

    Severity: medium · Enforcement: advisory

    Firestore databases must have Point-In-Time Recovery (PITR) enabled for business continuity

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable Point-In-Time Recovery
    const firestoreDb = new gcp.firestore.Database("my-firestore-db", {
        name: "my-database",
        locationId: "us-central",
        type: "FIRESTORE_NATIVE",
        pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_ENABLED",  // Enable PITR
        // ... other config
    });
    

    firewall-no-http-ingress

    Severity: critical · Enforcement: advisory

    Require firewall rules to disallow inbound HTTP traffic from unauthorized sources

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Use HTTPS Instead of HTTP
    const firewallRule = new gcp.compute.Firewall("allow-https", {
        network: network.id,
        direction: "INGRESS",
        allows: [{
            protocol: "tcp",
            ports: ["443"],  // Use HTTPS (port 443) instead of HTTP (port 80)
        }],
        sourceRanges: ["0.0.0.0/0"],
        // ... other config
    });
    

    firewall-no-public-ingress

    Severity: critical · Enforcement: advisory

    Require firewall rules to disallow public internet ingress unless specifically authorized

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Use Private Network Ranges or Source Tags
    const firewallRule = new gcp.compute.Firewall("allow-private-ingress", {
        network: network.id,
        direction: "INGRESS",
        allows: [{
            protocol: "tcp",
            ports: ["443"],
        }],
        sourceRanges: ["10.0.0.0/8", "192.168.0.0/16"],  // Use private ranges instead of 0.0.0.0/0
        // Or use source tags for internal traffic control:
        // sourceTags: ["web-tier"],
        // ... other config
    });
    

    firewall-restrict-rdp-ingress

    Severity: high · Enforcement: advisory

    Ensures VPC firewall rules do not allow RDP (port 3389) from broad sources

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

    Restrict sourceRanges to specific CIDRs, or use IAP (35.235.240.0/20).

    firewall-restrict-ssh-ingress

    Severity: high · Enforcement: advisory

    Ensures VPC firewall rules do not allow SSH (port 22) from broad sources

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

    Restrict sourceRanges to specific CIDRs, or use IAP (35.235.240.0/20).

    firewall-strict

    Severity: high · Enforcement: advisory

    Enforce strict firewall rules with explicit allow/deny configuration

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Explicit and Restrictive Firewall Rules
    const firewallRule = new gcp.compute.Firewall("strict-firewall-rule", {
        network: network.id,
        direction: "INGRESS",  // Explicitly specify direction
        allows: [{
            protocol: "tcp",
            ports: ["443"],  // Specify explicit ports, not all ports
        }],
        sourceRanges: ["10.0.0.0/24"],  // Use restrictive source ranges for sensitive ports
        targetTags: ["web-servers"],  // Specify explicit targets
        // ... other config
    });
    

    gke-nodes-private

    Severity: high · Enforcement: advisory

    Ensures GKE clusters enable private nodes

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation

    Set privateClusterConfig.enablePrivateNodes to true.

    gke-private-endpoint

    Severity: high · Enforcement: advisory

    Restrict public access for GKE clusters by enabling private endpoint or configuring master authorized networks

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

    Enable private endpoint by setting privateClusterConfig.enablePrivateEndpoint: true, or configure masterAuthorizedNetworksConfig.cidrBlocks with specific IP ranges (avoid 0.0.0.0/0).

    gke-secrets-encryption

    Severity: high · Enforcement: advisory

    Require GKE clusters to have Application-layer Secrets Encryption enabled

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Application-layer Secrets Encryption
    const cluster = new gcp.container.Cluster("my-cluster", {
        databaseEncryption: {
            state: "ENCRYPTED",  // Enable secrets encryption
            keyName: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",  // Specify KMS key
        },
        // ... other config
    });
    

    hardcoded-secrets

    Severity: critical · Enforcement: advisory

    Prohibit hardcoded secrets in code and configuration

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

    Remove hardcoded secrets from resource configuration.

    Example Violations

    Compute Instance with hardcoded secrets:

    const instance = new gcp.compute.Instance("my-instance", {
        machineType: "e2-medium",
        bootDisk: { /* ... */ },
        networkInterfaces: [{ /* ... */ }],
        metadataStartupScript: `#!/bin/bash
    export DATABASE_PASSWORD="mySecretPassword123"
    export API_KEY="AIzaSyAbc123def456ghi789jkl012mno345pqr678"
    mysql -u admin -p"hardcodedPassword" -h db.example.com
    `,
    });
    

    Cloud Function with hardcoded environment variables:

    const cloudFunction = new gcp.cloudfunctions.Function("my-function", {
        runtime: "nodejs20",
        environmentVariables: {
            "DATABASE_PASSWORD": "mySecretPassword123",
            "API_KEY": "AIzaSyAbc123def456ghi789jkl012mno345pqr678",
        },
    });
    

    Cloud SQL with hardcoded root password:

    const sqlInstance = new gcp.sql.DatabaseInstance("my-db", {
        databaseVersion: "POSTGRES_15",
        rootPassword: "myHardcodedPassword123",
    });
    

    iam-no-broad-roles

    Severity: critical · Enforcement: advisory

    Prohibit overly broad IAM roles on projects, organizations, folders, and service accounts

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Specific Least-Privilege Roles
    const binding = new gcp.projects.IAMBinding("service-binding", {
        project: "my-project",
        role: "roles/storage.objectViewer",
        members: ["serviceAccount:my-app@my-project.iam.gserviceaccount.com"],
    });
    

    Replace broad roles such as roles/owner or roles/editor with the most specific role that grants only the permissions needed.

    iam-no-custom-role-excessive-permissions

    Severity: high · Enforcement: advisory

    Prevent IAM custom roles with excessive permissions for enhanced data access control.

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

    Review and refine custom role permissions. Remove excessive administrative permissions like setIamPolicy, admin-level permissions, and owner permissions. Follow the principle of least privilege by granting only the minimum permissions required for the role’s intended purpose. Consider breaking up roles with too many permissions.

    Example - Create custom role with limited permissions:

    import * as gcp from "@pulumi/gcp";
    
    const role = new gcp.projects.IAMCustomRole("limited-role", {
        roleId: "limitedViewer",
        title: "Limited Viewer",
        permissions: [
            "compute.instances.get",
            "compute.instances.list",
        ],
    });
    

    iam-policy-no-statements-with-admin-access

    Severity: critical · Enforcement: advisory

    Prevent IAM policy bindings with administrative access permissions for secure configuration.

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

    Review and refine IAM policy bindings. Replace service-specific administrative roles like ‘roles/compute.admin’, ‘roles/storage.admin’, ‘roles/bigquery.admin’ with specific, granular roles. Use predefined roles with minimal permissions required for the task. Follow the principle of least privilege by granting only necessary permissions for operations, not administrative control over entire services.

    Example - Replace admin role with specific permissions:

    import * as gcp from "@pulumi/gcp";
    
    // Instead of roles/compute.admin, use specific roles
    const binding = new gcp.projects.IAMMember("compute-viewer", {
        project: "my-project",
        role: "roles/compute.viewer",
        member: "serviceAccount:sa@project.iam.gserviceaccount.com",
    });
    

    iam-policy-no-wildcard-permissions

    Severity: critical · Enforcement: advisory

    Prevent IAM custom roles with wildcard permissions to enforce least privilege access control.

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

    Review and refine custom IAM roles. Remove wildcard () permissions and replace them with specific, granular permissions. Instead of using ‘compute.’ or ‘storage.*’, explicitly list the required permissions such as ‘compute.instances.get’, ‘compute.instances.list’, ‘storage.buckets.get’, etc. Follow the principle of least privilege by granting only the exact permissions needed for the role’s intended purpose.

    Example - Create custom role with specific permissions:

    import * as gcp from "@pulumi/gcp";
    
    const customRole = new gcp.organizations.IAMCustomRole("custom-role", {
        roleId: "computeViewer",
        orgId: "123456789",
        title: "Compute Viewer",
        permissions: [
            "compute.instances.get",
            "compute.instances.list",
        ],
    });
    

    iam-user-no-direct-policies-check

    Severity: high · Enforcement: advisory

    Prevent IAM users from having direct policy attachments for better access management.

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

    Remove direct IAM policy bindings from individual user and service accounts. Instead, create IAM groups and assign users to groups, or use predefined roles. For service accounts, grant permissions through workload identity federation or service account impersonation where possible. This improves manageability and follows the principle of least privilege.

    Example - Use groups instead of direct user bindings:

    import * as gcp from "@pulumi/gcp";
    
    // Grant permissions to a group instead of individual users
    const groupBinding = new gcp.projects.IAMMember("group-viewer", {
        project: "my-project",
        role: "roles/viewer",
        member: "group:dev-team@example.com",
    });
    

    instance-template-disk-cmek

    Severity: high · Enforcement: advisory

    Require instance template disks to have customer-managed (CMEK) or customer-supplied (CSEK) encryption keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure CMEK or CSEK Disk Encryption
    const template = new gcp.compute.InstanceTemplate("my-template", {
        disks: [{
            boot: true,
            sourceImage: "debian-cloud/debian-11",
            diskEncryptionKey: {
                kmsKeySelfLink: "projects/my-project/locations/us-central1/keyRings/my-ring/cryptoKeys/my-key",
            },
        }],
    });
    

    kms-key-configuration

    Severity: low · Enforcement: advisory

    Require proper Cloud KMS key creation and configuration

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure KMS Key with Version Template
    const cryptoKey = new gcp.kms.CryptoKey("my-crypto-key", {
        name: "my-key",
        keyRing: keyRing.id,
        versionTemplate: {
            algorithm: "GOOGLE_SYMMETRIC_ENCRYPTION",  // Specify cryptographic algorithm
            protectionLevel: "HSM",  // Set protection level (SOFTWARE, HSM, EXTERNAL, EXTERNAL_VPC)
        },
        rotationPeriod: "7776000s",  // Optional: Configure 90-day rotation period
        purpose: "ENCRYPT_DECRYPT",  // Optional: Explicitly set key purpose
        // ... other config
    });
    

    kms-key-iam

    Severity: high · Enforcement: advisory

    Require proper access controls for Cloud KMS key IAM policies

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Least-Privilege IAM Roles
    // Use specific roles instead of overprivileged roles
    const cryptoKeyBinding = new gcp.kms.CryptoKeyIAMBinding("key-access", {
        cryptoKeyId: cryptoKey.id,
        role: "roles/cloudkms.cryptoKeyEncrypterDecrypter",  // Use specific role
        members: [
            "serviceAccount:my-service@project.iam.gserviceaccount.com",  // Use specific service accounts
            "group:security-team@example.com",  // Or specific groups
        ],
        // Avoid: roles/owner, roles/editor, roles/cloudkms.admin
        // Avoid: allUsers, allAuthenticatedUsers, domain-wide access
        // ... other config
    });
    

    kms-key-lifecycle

    Severity: low · Enforcement: advisory

    Require proper Cloud KMS key deletion and lifecycle management

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure Key Lifecycle Management
    const cryptoKey = new kms.CryptoKey("my-crypto-key", {
        name: "my-key",
        keyRing: keyRing.id,
        destroyScheduledDuration: "2592000s",  // Set 30-day scheduled destruction period
        skipInitialVersionCreation: false,  // Create initial key version
        versionTemplate: {
            algorithm: "GOOGLE_SYMMETRIC_ENCRYPTION",
            protectionLevel: "SOFTWARE",
        },
        // ... other config
    });
    

    kms-key-rotation

    Severity: high · Enforcement: advisory

    Ensure Cloud KMS key rotation is enabled

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

    Enable automatic key rotation for Cloud KMS crypto keys by setting ‘rotationPeriod’. Key rotation limits the lifetime of encryption keys and reduces cryptographic risk.

    Example - Enable automatic key rotation:

    import * as gcp from "@pulumi/gcp";
    
    const key = new gcp.kms.CryptoKey("my-key", {
        name: "crypto-key",
        keyRing: keyring.id,
        rotationPeriod: "7776000s", // 90 days (configurable)
    });
    

    Common rotation periods:

    • 30 days: “2592000s”
    • 60 days: “5184000s”
    • 90 days: “7776000s” (recommended default)
    • 365 days: “31536000s” (maximum recommended)

    lb-cloud-armor-attached

    Severity: high · Enforcement: advisory

    Ensures external backend services have Cloud Armor security policy attached

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

    Attach a Cloud Armor security policy to external backend services using the securityPolicy property for DDoS protection and threat detection.

    lb-connection-draining

    Severity: medium · Enforcement: advisory

    Ensures backend services have connection draining configured for graceful shutdown

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

    Configure connectionDrainingTimeoutSec on backend services to enable graceful connection termination during service updates or maintenance.

    lb-managed-ssl-certificate

    Severity: high · Enforcement: advisory

    Ensure Application Load Balancer uses managed SSL certificates with proper configuration

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

    Attach SSL certificates to target HTTPS proxies via sslCertificates property. Create and configure SSL policy with minimum TLS 1.2 using minTlsVersion: TLS_1_2 and profile: MODERN or RESTRICTED for secure cipher suites. For managed SSL certificates, specify at least one domain in the managed.domains field.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Create managed SSL certificate
    const managedCert = new gcp.compute.ManagedSslCertificate("ssl-cert", {
        name: "my-managed-cert",
        managed: {
            domains: ["example.com", "www.example.com"]
        }
    });
    
    // Create SSL policy with secure TLS settings
    const sslPolicy = new gcp.compute.SSLPolicy("ssl-policy", {
        name: "secure-ssl-policy",
        profile: "MODERN",
        minTlsVersion: "TLS_1_2"
    });
    
    // Create HTTPS target proxy with managed certificate and SSL policy
    const httpsProxy = new gcp.compute.TargetHttpsProxy("https-proxy", {
        name: "app-https-proxy",
        urlMap: urlMap.id,
        sslCertificates: [managedCert.id],
        sslPolicy: sslPolicy.id
    });
    

    load-balancer-cross-region-load-balancing-enabled

    Severity: medium · Enforcement: advisory

    Ensure Load Balancer cross-region load balancing is enabled

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

    Use Global Load Balancers with loadBalancingScheme: EXTERNAL_MANAGED. Configure backend services with multiple backends across different regions. Configure health checks for automatic failover. Set connectionDrainingTimeoutSec for graceful handling of backend failures.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Create health check for automatic failover
    const healthCheck = new gcp.compute.HttpHealthCheck("health-check", {
        name: "multi-region-health-check",
        requestPath: "/health",
        checkIntervalSec: 5,
        timeoutSec: 3,
        healthyThreshold: 2,
        unhealthyThreshold: 2
    });
    
    // Create instance groups in multiple regions
    const usEastGroup = new gcp.compute.InstanceGroupManager("us-east", {
        name: "instance-group-us-east",
        baseInstanceName: "vm-us-east",
        zone: "us-east1-b",
        // ... instance template configuration
    });
    
    const usWestGroup = new gcp.compute.InstanceGroupManager("us-west", {
        name: "instance-group-us-west",
        baseInstanceName: "vm-us-west",
        zone: "us-west1-a",
        // ... instance template configuration
    });
    
    // Create global backend service with cross-region backends
    const backendService = new gcp.compute.BackendService("multi-region-backend", {
        name: "cross-region-backend",
        loadBalancingScheme: "EXTERNAL_MANAGED",
        healthChecks: healthCheck.id,
        connectionDrainingTimeoutSec: 300,
        backends: [
            {
                group: usEastGroup.instanceGroup,
                balancingMode: "UTILIZATION",
                capacityScaler: 1.0,
                maxUtilization: 0.8
            },
            {
                group: usWestGroup.instanceGroup,
                balancingMode: "UTILIZATION",
                capacityScaler: 1.0,
                maxUtilization: 0.8
            }
        ],
        logConfig: {
            enable: true,
            sampleRate: 1.0
        }
    });
    
    // Create URL map and forwarding rule
    const urlMap = new gcp.compute.URLMap("url-map", {
        name: "multi-region-url-map",
        defaultService: backendService.id
    });
    
    const httpsProxy = new gcp.compute.TargetHttpsProxy("https-proxy", {
        name: "https-proxy",
        urlMap: urlMap.id,
        sslCertificates: [sslCert.id]
    });
    
    const forwardingRule = new gcp.compute.GlobalForwardingRule("forwarding-rule", {
        name: "global-forwarding-rule",
        target: httpsProxy.id,
        portRange: "443",
        ipProtocol: "TCP",
        loadBalancingScheme: "EXTERNAL_MANAGED"
    });
    

    load-balancer-health-checks

    Severity: medium · Enforcement: advisory

    Require Cloud Load Balancers to enable health checks for monitoring backend instance health

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Configure Health Checks for Backend Service
    // Create a health check
    const healthCheck = new gcp.compute.HealthCheck("backend-health-check", {
        httpHealthCheck: {
            port: 80,
            requestPath: "/health",
        },
        checkIntervalSec: 10,
        timeoutSec: 5,
    });
    
    // Attach health check to backend service
    const backendService = new gcp.compute.BackendService("my-backend", {
        healthChecks: [healthCheck.id],  // Configure health checks for monitoring
        backends: [/* ... */],
        // ... other config
    });
    

    load-balancer-http-to-https-redirection

    Severity: high · Enforcement: advisory

    Ensure Load Balancer HTTP to HTTPS redirection is configured

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

    Configure URL map with HTTPS redirect by setting defaultUrlRedirect.httpsRedirect: true or configure path matchers with HTTPS redirects. Create separate HTTP and HTTPS target proxies, with HTTP proxy redirecting to HTTPS.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Create URL map with HTTP to HTTPS redirect
    const redirectUrlMap = new gcp.compute.URLMap("redirect-map", {
        name: "http-redirect",
        defaultUrlRedirect: {
            httpsRedirect: true,
            redirectResponseCode: "MOVED_PERMANENTLY_DEFAULT"
        }
    });
    
    // Create HTTP target proxy for redirection
    const httpProxy = new gcp.compute.TargetHttpProxy("http-proxy", {
        name: "http-redirect-proxy",
        urlMap: redirectUrlMap.id
    });
    
    // Create HTTP forwarding rule (port 80)
    const httpForwardingRule = new gcp.compute.GlobalForwardingRule("http-rule", {
        name: "http-forwarding-rule",
        target: httpProxy.id,
        portRange: "80",
        ipProtocol: "TCP",
        loadBalancingScheme: "EXTERNAL"
    });
    
    // Create HTTPS URL map with backend service
    const httpsUrlMap = new gcp.compute.URLMap("https-map", {
        name: "https-url-map",
        defaultService: backendService.id
    });
    
    // Create HTTPS target proxy
    const httpsProxy = new gcp.compute.TargetHttpsProxy("https-proxy", {
        name: "https-proxy",
        urlMap: httpsUrlMap.id,
        sslCertificates: [sslCert.id]
    });
    
    // Create HTTPS forwarding rule (port 443)
    const httpsForwardingRule = new gcp.compute.GlobalForwardingRule("https-rule", {
        name: "https-forwarding-rule",
        target: httpsProxy.id,
        portRange: "443",
        ipProtocol: "TCP",
        loadBalancingScheme: "EXTERNAL"
    });
    

    load-balancer-logging-enabled

    Severity: high · Enforcement: advisory

    Enable Load Balancer logging for monitoring

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

    Enable logging on backend services by configuring logConfig.enable: true and set logConfig.sampleRate (1.0 for full logging, lower values for sampling). Ensure logs are retained in Cloud Logging for security analysis and troubleshooting.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // For global backend service
    const backendService = new gcp.compute.BackendService("my-backend", {
        logConfig: {
            enable: true,
            sampleRate: 1.0  // 1.0 = 100% logging, 0.5 = 50% sampling
        },
        // ... other configuration
    });
    
    // For regional backend service
    const regionBackendService = new gcp.compute.RegionBackendService("my-region-backend", {
        logConfig: {
            enable: true,
            sampleRate: 1.0
        },
        // ... other configuration
    });
    

    load-balancer-multi-zone

    Severity: medium · Enforcement: advisory

    Require Cloud Load Balancers to be configured across multiple zones for high availability

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure Backends Across Multiple Zones
    // Create instance groups in multiple zones
    const instanceGroup1 = new gcp.compute.InstanceGroup("backend-zone-a", {
        zone: "us-central1-a",
        instances: [/* ... */],
    });
    
    const instanceGroup2 = new gcp.compute.InstanceGroup("backend-zone-b", {
        zone: "us-central1-b",
        instances: [/* ... */],
    });
    
    // Configure backend service with multi-zone backends
    const backendService = new gcp.compute.BackendService("multi-zone-backend", {
        backends: [
            { group: instanceGroup1.id },  // Backend in zone A
            { group: instanceGroup2.id },  // Backend in zone B for high availability
        ],
        // ... other config
    });
    

    load-balancer-tls-https-listeners-only

    Severity: high · Enforcement: advisory

    Ensure Load Balancer uses TLS/HTTPS listeners only

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

    Configure forwarding rules to use port 443 for HTTPS traffic. Use TargetHttpsProxy instead of TargetHttpProxy. For HTTP listeners, ensure they redirect to HTTPS via URL map configuration. Remove standalone HTTP listeners without HTTPS redirection.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Create SSL certificate (or use existing)
    const sslCert = new gcp.compute.ManagedSslCertificate("my-cert", {
        managed: {
            domains: ["example.com"]
        }
    });
    
    // Create HTTPS target proxy
    const httpsProxy = new gcp.compute.TargetHttpsProxy("https-proxy", {
        urlMap: urlMap.id,
        sslCertificates: [sslCert.id]
    });
    
    // Create forwarding rule on port 443
    const httpsForwardingRule = new gcp.compute.GlobalForwardingRule("https-rule", {
        target: httpsProxy.id,
        portRange: "443",
        ipProtocol: "TCP",
        loadBalancingScheme: "EXTERNAL"
    });
    
    // Optional: HTTP to HTTPS redirect
    const httpProxy = new gcp.compute.TargetHttpProxy("http-proxy", {
        urlMap: redirectUrlMap.id  // URL map configured for redirect
    });
    
    const httpForwardingRule = new gcp.compute.GlobalForwardingRule("http-rule", {
        target: httpProxy.id,
        portRange: "80",
        ipProtocol: "TCP",
        loadBalancingScheme: "EXTERNAL"
    });
    

    managed-instance-group-launch-template-public-ip-disabled

    Severity: high · Enforcement: advisory

    Ensure Managed Instance Group launch templates have public IP addresses disabled

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation

    Disable public IP in instance template:

    new gcp.compute.InstanceTemplate("my-template", {
      networkInterfaces: [{
        network: "my-vpc",
        subnetwork: "my-subnet",
        accessConfigs: [], // Empty array disables public IP
      }],
      // ... other config
    });
    

    This prevents unintended public accessibility.

    managed-instance-group-load-balancer-healthcheck-required

    Severity: medium · Enforcement: advisory

    Ensure Managed Instance Groups have Load Balancer health check required

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

    Configure health checks for Managed Instance Groups by setting ‘autoHealingPolicies’ with a health check resource. This ensures that unhealthy instances are automatically replaced, improving availability and reliability.

    Example Pulumi TypeScript:

    import * as gcp from "@pulumi/gcp";
    
    const healthCheck = new gcp.compute.HealthCheck("http-health-check", {
        httpHealthCheck: { port: 80 },
    });
    
    const mig = new gcp.compute.InstanceGroupManager("my-mig", {
        baseInstanceName: "app",
        zone: "us-central1-a",
        autoHealingPolicies: {
            healthCheck: healthCheck.id,
            initialDelaySec: 300,
        },
        targetPools: [/* load balancer target pools */],
        versions: [{ instanceTemplate: /* template */ }],
    });
    

    no-unrestricted-route-to-internet-gateway

    Severity: high · Enforcement: advisory

    Ensure no unrestricted route to Internet Gateway for monitoring

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

    Route internet-bound traffic through Cloud NAT with logging enabled instead of direct internet gateway routes. Enable VPC Flow Logs for traffic monitoring. Use specific routes for known destinations. Configure firewall rules to control outbound traffic.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Bad: Direct route to default internet gateway (triggers violation)
    const directInternetRoute = new gcp.compute.Route("direct-internet-route", {
        network: network.id,
        destRange: "0.0.0.0/0",  // Default route
        nextHopGateway: "default-internet-gateway",  // Direct internet access
        priority: 1000,
    });
    
    // Good: Route through Cloud NAT for monitored egress
    const natRouter = new gcp.compute.Router("nat-router", {
        network: network.id,
        region: "us-central1",
    });
    
    const cloudNat = new gcp.compute.RouterNat("cloud-nat", {
        router: natRouter.name,
        region: natRouter.region,
        natIpAllocateOption: "AUTO_ONLY",
        sourceSubnetworkIpRangesToNat: "ALL_SUBNETWORKS_ALL_IP_RANGES",
        logConfig: {
            enable: true,
            filter: "ERRORS_ONLY",  // or "TRANSLATIONS_ONLY", "ALL"
        },
    });
    
    // Good: Specific route for known destination
    const specificRoute = new gcp.compute.Route("specific-route", {
        network: network.id,
        destRange: "10.128.0.0/20",  // Specific destination
        nextHopGateway: "default-internet-gateway",
        priority: 1000,
    });
    
    // Good: Route through internal load balancer for centralized egress
    const ilbRoute = new gcp.compute.Route("ilb-egress-route", {
        network: network.id,
        destRange: "0.0.0.0/0",
        nextHopIlb: ilb.selfLink,  // Centralized egress control
        priority: 1000,
    });
    

    Recommended patterns:

    1. Use Cloud NAT with logging enabled for internet-bound traffic
    2. Enable VPC Flow Logs on subnets for comprehensive monitoring
    3. Use specific routes (not 0.0.0.0/0) when possible
    4. Route through ILB for centralized egress control and monitoring

    persistent-disk-cmek

    Severity: high · Enforcement: advisory

    Ensures persistent disks have customer-managed (CMEK) or customer-supplied (CSEK) encryption keys

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

    Configure diskEncryptionKey with either kmsKeySelfLink (CMEK), rawKey, or rsaEncryptedKey (CSEK).

    persistent-disk-in-backup-plan

    Severity: high · Enforcement: advisory

    Perform automated backups for Persistent Disks and maintain isolated recovery data

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

    Create a resource policy for automated disk snapshots and attach it to persistent disks using the resourcePolicies property with appropriate retention period.

    persistent-disk-snapshot-not-publicly-restorable

    Severity: high · Enforcement: advisory

    Restrict public access to Persistent Disk snapshots

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

    Remove IAM bindings granting allUsers or allAuthenticatedUsers permissions to snapshots. Use specific service accounts or groups for snapshot access.

    persistent-disk-unused

    Severity: low · Enforcement: advisory

    Ensure Persistent Disks are not unused

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

    Review unattached persistent disks and either attach them to instances or delete them if no longer needed. Unattached disks incur storage costs without providing value.

    private-service-connect

    Severity: high · Enforcement: advisory

    Require Private Service Connect endpoints to have restrictive security policies

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Secure Private Service Connect
    // Create Service Attachment with manual connection approval
    const serviceAttachment = new gcp.compute.ServiceAttachment("psc-service", {
        connectionPreference: "ACCEPT_MANUAL",  // Require manual approval for connections
        consumerAcceptLists: [{
            projectIdOrNum: "consumer-project-123",
            connectionLimit: 10,  // Limit connections to minimize attack surface
        }],
        targetService: backendService.id,
        // ... other config
    });
    
    // Create Forwarding Rule for PSC with internal load balancing
    const forwardingRule = new gcp.compute.ForwardingRule("psc-endpoint", {
        network: network.id,  // Specify network for proper isolation
        loadBalancingScheme: "INTERNAL",  // Use internal scheme for private connectivity
        target: serviceAttachment.id,
        // ... other config
    });
    

    project-part-of-organization

    Severity: medium · Enforcement: advisory

    Ensure project is part of GCP Organization

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

    Migrate the project to an organization using ‘gcloud projects move’. Projects should be part of an organization to enable centralized governance, billing, and security controls.

    Example - Project in Organization:

    import * as gcp from "@pulumi/gcp";
    
    // COMPLIANT: Project associated with an organization
    const projectCompliant = new gcp.organizations.Project("compliant-project", {
        name: "Production Project",
        projectId: "prod-project-123",
        orgId: "123456789012",  // Compliant: orgId specified
        labels: {
            environment: "production",
            team: "platform"
        },
        autoCreateNetwork: false
    });
    
    // NON-COMPLIANT: Project without organization association
    const projectNonCompliant = new gcp.organizations.Project("standalone-project", {
        name: "Standalone Project",
        projectId: "standalone-project-456"
        // Missing orgId - not associated with organization
    });
    
    // COMPLIANT: Project in organization with folder structure
    const projectInFolder = new gcp.organizations.Project("folder-project", {
        name: "Dev Project",
        projectId: "dev-project-789",
        orgId: "123456789012",  // Compliant: associated with organization
        folderId: "folders/987654321",  // Optional: further organization
        labels: {
            environment: "development"
        }
    });
    

    pubsub-dead-letter-queue

    Severity: medium · Enforcement: advisory

    Require Pub/Sub subscriptions to have dead letter queue configuration

    • AU-5 Response to Audit Processing Failures — The information system alerts designated organizational officials in the event of an audit processing failure and takes additional actions.
    Remediation
    Fix: Configure Dead Letter Queue
    const deadLetterTopic = new gcp.pubsub.Topic("dead-letter-topic", {});
    
    const subscription = new gcp.pubsub.Subscription("my-subscription", {
        topic: topic.name,
        deadLetterPolicy: {
            deadLetterTopic: deadLetterTopic.id,  // Specify dead letter topic
            maxDeliveryAttempts: 5,  // Set max delivery attempts before moving to DLQ
        },
        // ... other config
    });
    

    pubsub-encrypted-kms

    Severity: medium · Enforcement: advisory

    Ensure Pub/Sub is encrypted with Cloud KMS

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

    Configure kmsKeyName property when creating Pub/Sub topics to use customer-managed encryption keys (CMEK) for enhanced security and key management control.

    Example - Pub/Sub Topic with Customer-Managed Encryption:

    import * as gcp from "@pulumi/gcp";
    
    // Create KMS KeyRing and CryptoKey for encryption
    const keyRing = new gcp.kms.KeyRing("pubsub-keyring", {
        name: "pubsub-keyring",
        location: "us-central1"
    });
    
    const cryptoKey = new gcp.kms.CryptoKey("pubsub-key", {
        name: "pubsub-encryption-key",
        keyRing: keyRing.id,
        rotationPeriod: "7776000s"  // 90 days
    });
    
    // Grant Pub/Sub service account access to the key
    const binding = new gcp.kms.CryptoKeyIAMBinding("pubsub-key-binding", {
        cryptoKeyId: cryptoKey.id,
        role: "roles/cloudkms.cryptoKeyEncrypterDecrypter",
        members: ["serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com"]
    });
    
    // COMPLIANT: Topic with customer-managed encryption key
    const topicCompliant = new gcp.pubsub.Topic("encrypted-topic", {
        name: "secure-topic",
        kmsKeyName: cryptoKey.id,  // Compliant: CMEK configured
        messageRetentionDuration: "86400s"
    });
    
    // NON-COMPLIANT: Topic without CMEK (uses Google-managed keys)
    const topicNonCompliant = new gcp.pubsub.Topic("default-topic", {
        name: "insecure-topic"
        // Missing kmsKeyName - uses default Google-managed encryption
    });
    

    pubsub-message-retention

    Severity: medium · Enforcement: advisory

    Require Pub/Sub subscriptions to have appropriate message retention policies

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    Remediation
    Fix: Configure Message Retention Duration
    const subscription = new gcp.pubsub.Subscription("my-subscription", {
        topic: topic.name,
        messageRetentionDuration: "604800s",  // Set retention to 7 days (in seconds)
        // ... other config
    });
    

    pubsub-subscription-iam-least-privilege

    Severity: high · Enforcement: advisory

    Enforce least privilege IAM policies for Pub/Sub subscriptions

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Least Privilege IAM Roles
    const subscriptionIamBinding = new gcp.pubsub.SubscriptionIAMBinding("subscription-subscriber-binding", {
        subscription: subscription.id,
        role: "roles/pubsub.subscriber",  // Use specific role instead of admin/owner/editor
        members: [
            "serviceAccount:app-service@project.iam.gserviceaccount.com",  // Use specific service accounts instead of allUsers
        ],
    });
    

    pubsub-topic-iam-least-privilege

    Severity: high · Enforcement: advisory

    Enforce least privilege IAM policies for Pub/Sub topics

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Least Privilege IAM Roles
    const topicIamBinding = new gcp.pubsub.TopicIAMBinding("topic-publisher-binding", {
        topic: topic.id,
        role: "roles/pubsub.publisher",  // Use specific role instead of admin/owner/editor
        members: [
            "serviceAccount:app-service@project.iam.gserviceaccount.com",  // Use specific service accounts instead of allUsers
        ],
    });
    

    resource-labeling

    Severity: low · Enforcement: advisory

    Require all GCP resources to have proper labeling for change tracking

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Add Required Labels for Change Tracking

    Add the required labels (environment, team, owner) to your GCP resources:

    const instance = new gcp.compute.Instance("my-instance", {
        labels: {
            environment: "production",  // Required: environment label
            team: "platform",           // Required: team label
            owner: "john-doe",          // Required: owner label
            // ... other labels
        },
        // ... other config
    });
    
    // For Cloud SQL instances, use userLabels within settings
    const sqlInstance = new gcp.sql.DatabaseInstance("my-database", {
        settings: {
            userLabels: {
                environment: "production",  // Required: environment label
                team: "data",               // Required: team label
                owner: "jane-smith",        // Required: owner label
            },
            // ... other settings
        },
        // ... other config
    });
    
    // For GKE clusters, use resourceLabels
    const cluster = new gcp.container.Cluster("my-cluster", {
        resourceLabels: {
            environment: "production",  // Required: environment label
            team: "infrastructure",     // Required: team label
            owner: "ops-team",          // Required: owner label
        },
        // ... other config
    });
    

    secretmanager-secret-cmek

    Severity: high · Enforcement: advisory

    Require Secret Manager secrets to use customer-managed Cloud KMS keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Customer-Managed KMS Encryption
    import * as gcp from "@pulumi/gcp";
    
    // Create a KMS KeyRing and CryptoKey
    const keyRing = new gcp.kms.KeyRing("my-keyring", {
        name: "secret-keyring",
        location: "us-central1",
    });
    
    const cryptoKey = new gcp.kms.CryptoKey("my-key", {
        name: "secret-encryption-key",
        keyRing: keyRing.id,
        rotationPeriod: "7776000s",  // 90 days
    });
    
    // Option 1: Auto-replication with customer-managed encryption
    const secretAuto = new gcp.secretmanager.Secret("my-secret-auto", {
        secretId: "my-cmek-secret",
        replication: {
            auto: {
                customerManagedEncryption: {
                    kmsKeyName: cryptoKey.id,  // Use customer-managed KMS key
                },
            },
        },
    });
    
    // Option 2: User-managed replication with customer-managed encryption
    const secretUserManaged = new gcp.secretmanager.Secret("my-secret-user", {
        secretId: "my-cmek-secret-regional",
        replication: {
            userManaged: {
                replicas: [
                    {
                        location: "us-central1",
                        customerManagedEncryption: {
                            kmsKeyName: cryptoKey.id,  // Use customer-managed KMS key
                        },
                    },
                    {
                        location: "us-east1",
                        customerManagedEncryption: {
                            kmsKeyName: cryptoKey.id,  // Specify for each replica
                        },
                    },
                ],
            },
        },
    });
    

    security-command-center-enabled

    Severity: high · Enforcement: advisory

    Ensure Security Command Center is enabled

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

    Enable the Security Command Center API service (securitycenter.googleapis.com) in your project or organization. Configure notification channels using gcp.securitycenter.NotificationConfig resources to receive security alerts. Consider enabling Security Command Center’s built-in detectors and custom modules for comprehensive security monitoring.

    Example - Enable Security Command Center:

    import * as gcp from "@pulumi/gcp";
    
    const sccService = new gcp.projects.Service("scc-api", {
        service: "securitycenter.googleapis.com",
    });
    
    const notifConfig = new gcp.securitycenter.NotificationConfig("scc-notify", {
        configId: "scc-notifications",
        organization: "123456789",
        pubsubTopic: topic.id,
        streamingConfig: { filter: 'state = "ACTIVE"' },
    });
    

    securitypolicy-has-custom-rules

    Severity: high · Enforcement: advisory

    Ensures Cloud Armor security policies have custom protection rules

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

    Add custom protection rules to the Cloud Armor security policy for DDoS protection, SQL injection prevention, XSS protection, or other security policies.

    service-account-key

    Severity: critical · Enforcement: advisory

    Ensure proper service account key usage and prohibit insecure authentication methods

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Use Strong Key Algorithm and Avoid Default Service Accounts
    const serviceAccount = new gcp.serviceaccount.Account("app-service-account", {
        accountId: "webapp-backend",  // Use application-specific service account
        displayName: "Web App Backend Service Account",
    });
    
    const serviceAccountKey = new gcp.serviceaccount.Key("app-key", {
        serviceAccountId: serviceAccount.name,
        keyAlgorithm: "KEY_ALG_RSA_2048",  // Use RSA_2048 or RSA_4096 for strong encryption
        // Avoid creating keys for default service accounts like:
        // - {project-number}-compute@developer.gserviceaccount.com
        // - {project-id}@appspot.gserviceaccount.com
    });
    

    service-account-restricted-names

    Severity: medium · Enforcement: advisory

    Restrict default service account creation with prohibited names

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Use Descriptive Service Account Names
    const serviceAccount = new gcp.serviceaccount.Account("backend-service-account", {
        accountId: "webapp-backend",  // Use specific, descriptive names (6-30 chars)
        displayName: "Web Application Backend Service Account",
        // Avoid generic/prohibited names like: default, admin, root, system, compute
        // Use names that describe the service purpose: webapp-backend, data-processor, etc.
    });
    

    single-environment-stack

    Severity: low · Enforcement: advisory

    Ensure all resources in a stack belong to the same environment

    • CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.
    Remediation
    Fix: Separate Resources into Environment-Specific Stacks

    Create separate Pulumi stacks for each environment to ensure proper separation:

    // Create separate stacks for each environment
    // Stack: dev-stack
    const devInstance = new gcp.compute.Instance("dev-instance", {
        labels: {
            environment: "development",  // All resources in this stack use "development"
            // ... other labels
        },
        // ... other config
    });
    
    // Stack: prod-stack
    const prodInstance = new gcp.compute.Instance("prod-instance", {
        labels: {
            environment: "production",  // All resources in this stack use "production"
            // ... other labels
        },
        // ... other config
    });
    

    subnet-auto-assign-external-ip-disabled

    Severity: medium · Enforcement: advisory

    Ensure Private Google Access is enabled on VPC subnets

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

    Enable Private Google Access on subnets by setting privateIpGoogleAccess: true. This allows instances without external IP addresses to access Google APIs and services. Use Cloud NAT for internet access without public IPs.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Enable Private Google Access on subnet
    const subnet = new gcp.compute.Subnetwork("my-subnet", {
        ipCidrRange: "10.0.0.0/24",
        network: network.id,
        region: "us-central1",
        privateIpGoogleAccess: true  // Allow instances without external IPs to access Google APIs
    });
    
    // Optional: Create Cloud NAT for outbound internet access
    const router = new gcp.compute.Router("my-router", {
        network: network.id,
        region: "us-central1"
    });
    
    const nat = new gcp.compute.RouterNat("my-nat", {
        router: router.name,
        region: router.region,
        natIpAllocateOption: "AUTO_ONLY",
        sourceSubnetworkIpRangesToNat: "ALL_SUBNETWORKS_ALL_IP_RANGES"
    });
    

    vpc-external-ip-associated

    Severity: medium · Enforcement: advisory

    Ensure VPC external IP addresses are associated

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation

    Review reserved external IP addresses and either associate them with resources (instances, forwarding rules) or release unused addresses. Use gcloud compute addresses list to identify unassociated addresses and gcloud compute addresses delete to remove them.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Create a static external IP address
    const staticIp = new gcp.compute.Address("my-static-ip", {
        name: "my-external-ip",
        region: "us-central1",
        addressType: "EXTERNAL",
    });
    
    // Associate it with a compute instance
    const instance = new gcp.compute.Instance("my-instance", {
        machineType: "f1-micro",
        zone: "us-central1-a",
        bootDisk: {
            initializeParams: {
                image: "debian-cloud/debian-11",
            },
        },
        networkInterfaces: [{
            network: "default",
            accessConfigs: [{
                natIp: staticIp.address,  // Associate the static IP
            }],
        }],
    });
    
    // Or associate with a forwarding rule
    const forwardingRule = new gcp.compute.ForwardingRule("my-forwarding-rule", {
        ipAddress: staticIp.address,  // Associate the static IP
        target: targetPool.selfLink,
        portRange: "80",
        region: "us-central1",
    });
    

    vpc-firewall-rule-associated-to-network

    Severity: high · Enforcement: advisory

    Ensure VPC firewall rules are associated to networks

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

    Associate firewall rules with VPC networks by specifying the network property with a valid VPC network reference (name, partial URL, or full URL). Ensure the network exists before creating the firewall rule.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    const firewallRule = new gcp.compute.Firewall("my-firewall-rule", {
        network: network.id,  // Reference to VPC network
        allows: [{
            protocol: "tcp",
            ports: ["80", "443"],
        }],
        sourceRanges: ["0.0.0.0/0"],
        targetTags: ["web-server"],
    });
    

    The network property can be specified as:

    • A resource reference: network.id or network.selfLink
    • A full URL: https://www.googleapis.com/compute/v1/projects/PROJECT/global/networks/NETWORK
    • A partial URL: projects/PROJECT/global/networks/NETWORK
    • A short name: network-name

    vpc-firewall-rule-unused

    Severity: low · Enforcement: advisory

    Ensure VPC firewall rules are not unused

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

    Review and remove disabled or unused firewall rules. Enable necessary rules or delete obsolete ones. Remove rules with test/temp/deprecated tags. Use gcloud compute firewall-rules list --filter='disabled=true' to identify disabled rules.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    // Good: Active firewall rule with clear purpose
    const activeFirewall = new gcp.compute.Firewall("web-allow-https", {
        network: network.id,
        disabled: false,  // Ensure rule is enabled
        allows: [{
            protocol: "tcp",
            ports: ["443"],
        }],
        sourceRanges: ["0.0.0.0/0"],
        targetTags: ["web-server"],
    });
    
    // Bad: Disabled firewall rule (should be removed or enabled)
    const disabledFirewall = new gcp.compute.Firewall("old-rule", {
        network: network.id,
        disabled: true,  // This will trigger a violation
        allows: [{
            protocol: "tcp",
            ports: ["8080"],
        }],
    });
    
    // Bad: Firewall rule with suspicious tags indicating it may be unused
    const testFirewall = new gcp.compute.Firewall("test-rule", {
        network: network.id,
        allows: [{
            protocol: "tcp",
            ports: ["22"],
        }],
        targetTags: ["test", "deprecated"],  // Will trigger a violation
    });
    
    // Use labels to track firewall rule usage and purpose
    const trackedFirewall = new gcp.compute.Firewall("tracked-rule", {
        network: network.id,
        allows: [{
            protocol: "tcp",
            ports: ["443"],
        }],
        sourceRanges: ["10.0.0.0/8"],
        targetTags: ["internal-api"],
    });
    

    To track firewall rule usage:

    1. Avoid using disabled: true - remove unused rules instead
    2. Don’t use tags like “test”, “temp”, “deprecated” in production
    3. Use descriptive names and regular audits to identify unused rules
    4. Review rules with high priority values (low precedence) that may never match

    vpc-flow-logs-enabled

    Severity: high · Enforcement: advisory

    Ensure VPC subnets have Flow Logs enabled for audit and monitoring

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

    Enable VPC Flow Logs on subnets by configuring logConfig with aggregationInterval (e.g., INTERVAL_5_SEC) and flowSampling (0.5 for 50% or 1.0 for 100%). Ensure flowSampling is greater than 0 to collect traffic logs.

    Pulumi TypeScript Example:

    import * as gcp from "@pulumi/gcp";
    
    const subnet = new gcp.compute.Subnetwork("my-subnet", {
        ipCidrRange: "10.0.0.0/24",
        network: network.id,
        region: "us-central1",
        logConfig: {
            aggregationInterval: "INTERVAL_5_SEC",  // or INTERVAL_30_SEC, INTERVAL_1_MIN, etc.
            flowSampling: 1.0,  // 1.0 = 100% sampling, 0.5 = 50%
            metadata: "INCLUDE_ALL_METADATA"
        },
        privateIpGoogleAccess: true
    });
    

    Valid aggregationInterval values: INTERVAL_5_SEC, INTERVAL_30_SEC, INTERVAL_1_MIN, INTERVAL_5_MIN, INTERVAL_10_MIN, INTERVAL_15_MIN

      The infrastructure as code platform for any cloud.