---
title: Google Cloud
url: /docs/reference/pre-built-policy-packs/cis/google-cloud/
---
> This [Pulumi Cloud](/docs/iac/concepts/pulumi-cloud/) feature is available in the [Enterprise edition](/pricing/).


This page lists all 102 policies in the **CIS 8.1** pack for **Google Cloud**, as published in `cis-google-cloud` version `1.0.3`.

## Policies by control

**1.1** — Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data, to include: end-user devices (including portable and mobile), network devices, non-computing/IoT devices, and servers. Ensure the inventory records the network address (if static), hardware address, machine name, enterprise asset owner, department for each asset, and whether the asset has been approved to connect to the network. For mobile end-user devices, MDM type tools can support this process, where appropriate. This inventory includes assets connected to the infrastructure physically, virtually, remotely, and those within cloud environments. Additionally, it includes assets that are regularly connected to the enterprise's network infrastructure, even if they are not under control of the enterprise. Review and update the inventory of all enterprise assets bi-annually, or more frequently.

- [compute-engine-instance-proper-configuration](#compute-engine-instance-proper-configuration)
- [compute-engine-os-config-compliance-association-compliant](#compute-engine-os-config-compliance-association-compliant)
- [vpc-external-ip-associated](#vpc-external-ip-associated)
- [vpc-firewall-rule-associated-to-network](#vpc-firewall-rule-associated-to-network)
- [vpc-firewall-rule-unused](#vpc-firewall-rule-unused)

**1.2** — Ensure that a process exists to address unauthorized assets on a weekly basis. The enterprise may choose to remove the asset from the network, deny the asset from connecting remotely to the network, or quarantine the asset.

- [security-command-center-enabled](#security-command-center-enabled)

**2.2** — Ensure that only currently supported software is designated as authorized in the software inventory for enterprise assets. If software is unsupported, yet necessary for the fulfillment of the enterprise's mission, document an exception detailing mitigating controls and residual risk acceptance. For any unsupported software without an exception documentation, designate as unauthorized. Review the software list to verify software support at least monthly, or more frequently.

- [app-engine-managed-updates-enabled](#app-engine-managed-updates-enabled)

**3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

- [ai-platform-notebook-no-direct-internet-access](#ai-platform-notebook-no-direct-internet-access)
- [bigquery-dataset-public-access-check](#bigquery-dataset-public-access-check)
- [cloud-functions-inside-vpc](#cloud-functions-inside-vpc)
- [cloud-functions-public-access-prohibited](#cloud-functions-public-access-prohibited)
- [cloud-logging-retention-period-365](#cloud-logging-retention-period-365)
- [cloud-run-service-configuration-check](#cloud-run-service-configuration-check)
- [cloud-sql-instance-not-publicly-accessible](#cloud-sql-instance-not-publicly-accessible)
- [cloud-storage-bucket-iam-policy-grantee-check](#cloud-storage-bucket-iam-policy-grantee-check)
- [cloud-storage-bucket-level-public-access-prohibited](#cloud-storage-bucket-level-public-access-prohibited)
- [cloud-storage-bucket-public-read-prohibited](#cloud-storage-bucket-public-read-prohibited)
- [cloud-storage-bucket-public-write-prohibited](#cloud-storage-bucket-public-write-prohibited)
- [cloud-storage-bucket-restrict-public-read-access](#cloud-storage-bucket-restrict-public-read-access)
- [compute-engine-instance-in-vpc](#compute-engine-instance-in-vpc)
- [compute-engine-instance-not-publicly-accessible](#compute-engine-instance-not-publicly-accessible)
- [compute-engine-instance-service-account-attached](#compute-engine-instance-service-account-attached)
- [compute-engine-instance-uses-os-login](#compute-engine-instance-uses-os-login)
- [database-migration-service-not-publicly-accessible](#database-migration-service-not-publicly-accessible)
- [dataproc-cluster-master-nodes-no-public-ip](#dataproc-cluster-master-nodes-no-public-ip)
- [dataproc-kerberos-enabled](#dataproc-kerberos-enabled)
- [elasticsearch-in-vpc-only](#elasticsearch-in-vpc-only)
- [gke-cluster-endpoint-restrict-public-access](#gke-cluster-endpoint-restrict-public-access)
- [iam-no-custom-role-excessive-permissions](#iam-no-custom-role-excessive-permissions)
- [iam-policy-no-statements-with-full-access](#iam-policy-no-statements-with-full-access)
- [iam-user-no-direct-policies-check](#iam-user-no-direct-policies-check)
- [managed-instance-group-launch-template-public-ip-disabled](#managed-instance-group-launch-template-public-ip-disabled)
- [persistent-disk-snapshot-not-publicly-restorable](#persistent-disk-snapshot-not-publicly-restorable)
- [subnet-auto-assign-external-ip-disabled](#subnet-auto-assign-external-ip-disabled)

**3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

- [bigquery-audit-logging-enabled](#bigquery-audit-logging-enabled)
- [cloud-armor-logging-enabled](#cloud-armor-logging-enabled)
- [cloud-functions-concurrency-check](#cloud-functions-concurrency-check)
- [cloud-sql-logging-enabled](#cloud-sql-logging-enabled)
- [cloud-storage-bucket-logging-enabled](#cloud-storage-bucket-logging-enabled)
- [compute-engine-instance-detailed-monitoring-enabled](#compute-engine-instance-detailed-monitoring-enabled)
- [elasticsearch-logs-to-cloud-logging](#elasticsearch-logs-to-cloud-logging)
- [load-balancer-logging-enabled](#load-balancer-logging-enabled)
- [no-unrestricted-route-to-internet-gateway](#no-unrestricted-route-to-internet-gateway)

**3.10** — Encrypt sensitive data in transit. Example implementations can include: Transport Layer Security (TLS) and Open Secure Shell (OpenSSH).

- [application-load-balancer-managed-ssl-certificate](#application-load-balancer-managed-ssl-certificate)
- [cloud-storage-bucket-ssl-requests-only](#cloud-storage-bucket-ssl-requests-only)
- [load-balancer-http-to-https-redirection](#load-balancer-http-to-https-redirection)
- [load-balancer-managed-ssl-certificate](#load-balancer-managed-ssl-certificate)
- [load-balancer-tls-https-listeners-only](#load-balancer-tls-https-listeners-only)

**3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

- [ai-platform-endpoint-configuration-kms-key-configured](#ai-platform-endpoint-configuration-kms-key-configured)
- [ai-platform-notebook-instance-kms-key-configured](#ai-platform-notebook-instance-kms-key-configured)
- [bigquery-dataset-encryption-enabled](#bigquery-dataset-encryption-enabled)
- [cloud-filestore-encrypted-check](#cloud-filestore-encrypted-check)
- [cloud-logging-encrypted](#cloud-logging-encrypted)
- [cloud-sql-storage-encrypted](#cloud-sql-storage-encrypted)
- [cloud-storage-bucket-encryption-enabled](#cloud-storage-bucket-encryption-enabled)
- [cloud-storage-default-encryption-kms](#cloud-storage-default-encryption-kms)
- [elasticsearch-encrypted-at-rest](#elasticsearch-encrypted-at-rest)
- [kms-key-not-scheduled-for-deletion](#kms-key-not-scheduled-for-deletion)
- [persistent-disk-encrypted](#persistent-disk-encrypted)
- [pubsub-encrypted-kms](#pubsub-encrypted-kms)
- [secret-manager-using-cmek](#secret-manager-using-cmek)

**4.1** — Establish and maintain a documented secure configuration process for enterprise assets (end-user devices, including portable and mobile, non-computing/IoT devices, and servers) and software (operating systems and applications). Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

- [bigquery-maintenance-settings-check](#bigquery-maintenance-settings-check)
- [project-part-of-organization](#project-part-of-organization)

**4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

- [cloud-storage-bucket-default-encryption-enabled](#cloud-storage-bucket-default-encryption-enabled)
- [cloud-storage-bucket-versioning-enabled](#cloud-storage-bucket-versioning-enabled)
- [iam-policy-no-statements-with-admin-access](#iam-policy-no-statements-with-admin-access)
- [kms-key-rotation-enabled](#kms-key-rotation-enabled)
- [managed-instance-group-load-balancer-healthcheck-required](#managed-instance-group-load-balancer-healthcheck-required)
- [persistent-disk-attached-encryption-enabled](#persistent-disk-attached-encryption-enabled)
- [persistent-disk-unused](#persistent-disk-unused)
- [restricted-ssh](#restricted-ssh)
- [vpc-firewall-rule-restrict-ingress-ssh-all](#vpc-firewall-rule-restrict-ingress-ssh-all)

**5.4** — Restrict administrator privileges to dedicated administrator accounts on enterprise assets. Conduct general computing activities, such as internet browsing, email, and productivity suite use, from the user's primary, non-privileged account.

- [iam-policy-no-wildcard-permissions](#iam-policy-no-wildcard-permissions)

**7.1** — Establish and maintain a documented vulnerability management process for enterprise assets. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

- [cloud-security-scanner-enabled](#cloud-security-scanner-enabled)
- [compute-engine-os-config-compliance-patch-compliant](#compute-engine-os-config-compliance-patch-compliant)

**7.3** — Perform operating system updates on enterprise assets through automated patch management on a monthly, or more frequent, basis.

- [compute-engine-os-config-compliance-patch-compliant](#compute-engine-os-config-compliance-patch-compliant)

**8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

- [api-gateway-logging-configuration](#api-gateway-logging-configuration)
- [cloud-armor-security-policy-logging-enabled](#cloud-armor-security-policy-logging-enabled)
- [cloud-audit-logs-cloud-logging-enabled](#cloud-audit-logs-cloud-logging-enabled)
- [cloud-audit-logs-security-trail-enabled](#cloud-audit-logs-security-trail-enabled)
- [cloud-cdn-logging-enabled](#cloud-cdn-logging-enabled)
- [vpc-flow-logs-enabled](#vpc-flow-logs-enabled)

**8.3** — Ensure that logging destinations maintain adequate storage to comply with the enterprise's audit log management process.

- [cloud-audit-logs-integrity-monitoring-enabled](#cloud-audit-logs-integrity-monitoring-enabled)
- [cloud-audit-logs-multi-region-trail-enabled](#cloud-audit-logs-multi-region-trail-enabled)

**8.5** — Configure detailed audit logging for enterprise assets containing sensitive data. Include event source, date, username, timestamp, source addresses, destination addresses, and other useful elements that could assist in a forensic investigation.

- [cloud-audit-logs-data-access-events-enabled](#cloud-audit-logs-data-access-events-enabled)

**11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.

- [cloud-firestore-in-backup-plan](#cloud-firestore-in-backup-plan)
- [cloud-firestore-pitr-enabled](#cloud-firestore-pitr-enabled)
- [cloud-sql-backup-enabled](#cloud-sql-backup-enabled)
- [cloud-sql-instance-backup-enabled](#cloud-sql-instance-backup-enabled)
- [cloud-storage-bucket-cross-region-replication-enabled](#cloud-storage-bucket-cross-region-replication-enabled)
- [compute-engine-optimized-instance](#compute-engine-optimized-instance)
- [persistent-disk-in-backup-plan](#persistent-disk-in-backup-plan)

**11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

- [cloud-firestore-in-backup-plan](#cloud-firestore-in-backup-plan)
- [cloud-firestore-pitr-enabled](#cloud-firestore-pitr-enabled)
- [cloud-sql-backup-enabled](#cloud-sql-backup-enabled)
- [cloud-storage-bucket-cross-region-replication-enabled](#cloud-storage-bucket-cross-region-replication-enabled)
- [compute-engine-optimized-instance](#compute-engine-optimized-instance)
- [persistent-disk-in-backup-plan](#persistent-disk-in-backup-plan)

**12.1** — Ensure network infrastructure is kept up-to-date. Example implementations include running the latest stable release of software and/or using currently supported network as a service (NaaS) offerings. Review software versions monthly, or more frequently, to verify software support.

- [compute-engine-instance-os-config-managed](#compute-engine-instance-os-config-managed)

**12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

- [certificate-manager-certificate-lifecycle-management](#certificate-manager-certificate-lifecycle-management)
- [cloud-firestore-autoscaling-enabled](#cloud-firestore-autoscaling-enabled)
- [cloud-sql-enhanced-networking-enabled](#cloud-sql-enhanced-networking-enabled)
- [cloud-sql-instance-deletion-protection-enabled](#cloud-sql-instance-deletion-protection-enabled)
- [cloud-sql-multi-region-support](#cloud-sql-multi-region-support)
- [load-balancer-cross-region-load-balancing-enabled](#load-balancer-cross-region-load-balancing-enabled)
- [load-balancer-deletion-protection-enabled](#load-balancer-deletion-protection-enabled)

**13.1** — Centralize security event alerting across enterprise assets for log correlation and analysis. Best practice implementation requires the use of a SIEM, which includes vendor-defined event correlation alerts. A log analytics platform configured with security-relevant correlation alerts also satisfies this Safeguard.

- [load-balancer-cloud-armor-enabled](#load-balancer-cloud-armor-enabled)

**16.1** — Establish and maintain a secure application development process. In the process, address such items as: secure application design standards, secure coding practices, developer training, vulnerability management, security of third-party code, and application security testing procedures. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

- [cloud-build-trigger-envvar-gcpcred-check](#cloud-build-trigger-envvar-gcpcred-check)
- [cloud-build-trigger-source-repo-url-check](#cloud-build-trigger-source-repo-url-check)

**16.12** — Apply static and dynamic analysis tools within the application life cycle to verify that secure coding practices are being followed.

- [cloud-build-trigger-envvar-gcpcred-check](#cloud-build-trigger-envvar-gcpcred-check)
- [cloud-build-trigger-source-repo-url-check](#cloud-build-trigger-source-repo-url-check)

## Policy details

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

**Severity:** medium · **Enforcement:** advisory

Ensure AI Platform endpoint configuration uses Cloud KMS

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

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:
```typescript
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

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

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:
```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```typescript
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

- **8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

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:
```typescript
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

- **2.2** — Ensure that only currently supported software is designated as authorized in the software inventory for enterprise assets. If software is unsupported, yet necessary for the fulfillment of the enterprise's mission, document an exception detailing mitigating controls and residual risk acceptance. For any unsupported software without an exception documentation, designate as unauthorized. Review the software list to verify software support at least monthly, or more frequently.

Remediation

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

```typescript
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
```

### application-load-balancer-managed-ssl-certificate

**Severity:** high · **Enforcement:** advisory

Ensure Application Load Balancer uses managed SSL certificates

- **3.10** — Encrypt sensitive data in transit. Example implementations can include: Transport Layer Security (TLS) and Open Secure Shell (OpenSSH).

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.

**Pulumi TypeScript Example:**

```typescript
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 URL map
const urlMap = new gcp.compute.URLMap("url-map", {
    name: "app-url-map",
    defaultService: backendService.id
});

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

// Create forwarding rule
const forwardingRule = new gcp.compute.GlobalForwardingRule("https-rule", {
    name: "https-forwarding-rule",
    target: httpsProxy.id,
    portRange: "443",
    ipProtocol: "TCP",
    loadBalancingScheme: "EXTERNAL_MANAGED"
});

// Regional example
const regionalCert = new gcp.compute.RegionSslCertificate("regional-cert", {
    name: "regional-ssl-cert",
    region: "us-central1",
    certificate: std.file({ input: "path/to/cert.pem" }).result,
    privateKey: std.file({ input: "path/to/key.pem" }).result
});

const regionalHttpsProxy = new gcp.compute.RegionTargetHttpsProxy("regional-proxy", {
    name: "regional-https-proxy",
    region: "us-central1",
    urlMap: regionalUrlMap.id,
    sslCertificates: [regionalCert.id],
    sslPolicy: sslPolicy.id
});
```

### bigquery-audit-logging-enabled

**Severity:** high · **Enforcement:** advisory

Enable BigQuery audit logging for monitoring

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:
```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-encryption-enabled

**Severity:** high · **Enforcement:** advisory

Enable BigQuery dataset encryption

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Configure `defaultEncryptionConfiguration.kmsKeyName` for datasets or `encryptionConfiguration.kmsKeyName` for tables. Create a Cloud KMS key in the same region as the BigQuery resource and grant the BigQuery service account encrypt/decrypt permissions on the key.

Example TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

// Create KMS key in same region as dataset
const keyRing = new gcp.kms.KeyRing("bigquery-keyring", {
    location: "us"
});

const cryptoKey = new gcp.kms.CryptoKey("bigquery-key", {
    keyRing: keyRing.id,
    rotationPeriod: "7776000s" // 90 days
});

// Dataset with CMEK encryption
const dataset = new gcp.bigquery.Dataset("encrypted-dataset", {
    datasetId: "my_dataset",
    location: "US",
    defaultEncryptionConfiguration: {
        kmsKeyName: cryptoKey.id
    }
});

// Table with CMEK encryption
const table = new gcp.bigquery.Table("encrypted-table", {
    datasetId: dataset.datasetId,
    tableId: "my_table",
    encryptionConfiguration: {
        kmsKeyName: cryptoKey.id
    }
});
```

### bigquery-dataset-public-access-check

**Severity:** high · **Enforcement:** advisory

Ensure BigQuery datasets are not publicly accessible

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```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

- **4.1** — Establish and maintain a documented secure configuration process for enterprise assets (end-user devices, including portable and mobile, non-computing/IoT devices, and servers) and software (operating systems and applications). Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

Remediation

Configure BigQuery datasets with appropriate maintenance settings:

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

### certificate-manager-certificate-lifecycle-management

**Severity:** medium · **Enforcement:** advisory

Ensure proper certificate lifecycle management to prevent expiration

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

Remediation

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

```typescript
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-enabled

**Severity:** high · **Enforcement:** advisory

Ensure backend services with Cloud Armor have logging enabled

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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.

```typescript
import * as gcp from "@pulumi/gcp";

// Step 1: Create Cloud Armor security policy
const armorPolicy = new gcp.compute.SecurityPolicy("armor-policy", {
    name: "security-policy",
    type: "CLOUD_ARMOR",
    rules: [{
        action: "deny(403)",
        priority: 1000,
        match: {
            versionedExpr: "SRC_IPS_V1",
            config: {
                srcIpRanges: ["192.168.1.0/24"]
            }
        }
    }]
});

// Step 2: CRITICAL - Enable logging on backend service
const backendService = new gcp.compute.BackendService("backend", {
    name: "backend-service",
    securityPolicy: armorPolicy.selfLink,
    logConfig: {
        enable: true,        // REQUIRED for Cloud Armor logging
        sampleRate: 1.0      // 1.0 = 100% logging, 0.5 = 50% sampling
    }
});

// Regional backend service also needs logging
const regionalBackend = new gcp.compute.RegionBackendService("regional-backend", {
    name: "regional-backend",
    region: "us-central1",
    securityPolicy: armorPolicy.selfLink,
    logConfig: {
        enable: true,        // REQUIRED for Cloud Armor logging
        sampleRate: 1.0
    }
});
```

Cloud Armor logs include:
- Security policy name
- Matched rule priority and action
- Request details and outcomes
- Attack signatures and threat indicators

### cloud-armor-security-policy-logging-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Armor security policies have logging enabled through their backend services

- **8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

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.

```typescript
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
    }
});

// Regional backend service also needs logging
const regionalBackend = new gcp.compute.RegionBackendService("regional-backend", {
    name: "regional-backend",
    region: "us-central1",
    securityPolicy: securityPolicy.selfLink,
    logConfig: {
        enable: true,
        sampleRate: 1.0
    }
});
```

Cloud Armor logs include:
- Security policy name and evaluation results
- Matched rule priority and action taken
- Request details and outcomes
- Attack signatures and threat indicators

### cloud-audit-logs-cloud-logging-enabled

**Severity:** high · **Enforcement:** advisory

Enable Cloud Audit Logs Cloud Logging integration for monitoring

- **8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

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.

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

**Severity:** high · **Enforcement:** advisory

Enable Cloud Audit Logs data access events for monitoring

- **8.5** — Configure detailed audit logging for enterprise assets containing sensitive data. Include event source, date, username, timestamp, source addresses, destination addresses, and other useful elements that could assist in a forensic investigation.

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:
```typescript
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

- **8.3** — Ensure that logging destinations maintain adequate storage to comply with the enterprise's audit log management process.

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

- **8.3** — Ensure that logging destinations maintain adequate storage to comply with the enterprise's audit log management process.

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-audit-logs-security-trail-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Audit Logs security trail is enabled

- **8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

Remediation

Enable Cloud Audit Logs by creating a gcp.logging.ProjectSink or gcp.logging.OrganizationSink resource that captures admin activity and data access logs. Configure the sink to export logs to Cloud Storage, BigQuery, or Pub/Sub for long-term retention and analysis.

### cloud-build-trigger-envvar-gcpcred-check

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Build trigger environment variables do not contain GCP credentials

- **16.1** — Establish and maintain a secure application development process. In the process, address such items as: secure application design standards, secure coding practices, developer training, vulnerability management, security of third-party code, and application security testing procedures. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.
- **16.12** — Apply static and dynamic analysis tools within the application life cycle to verify that secure coding practices are being followed.

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.

```typescript
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

- **16.1** — Establish and maintain a secure application development process. In the process, address such items as: secure application design standards, secure coding practices, developer training, vulnerability management, security of third-party code, and application security testing procedures. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.
- **16.12** — Apply static and dynamic analysis tools within the application life cycle to verify that secure coding practices are being followed.

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.

```typescript
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-logging-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud CDN has logging enabled for audit and monitoring

- **8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

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:
```typescript
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-filestore-encrypted-check

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Filestore is encrypted

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Configure customer-managed encryption keys (CMEK) by setting kmsKeyName to a Cloud KMS key when creating Filestore instances for enhanced security.

```typescript
import * as gcp from "@pulumi/gcp";

// Create KMS key for encryption
const filestoreKeyring = new gcp.kms.KeyRing("filestore-keyring", {
    name: "filestore-keyring",
    location: "us-central1"
});

const filestoreKey = new gcp.kms.CryptoKey("filestore-key", {
    name: "filestore-key",
    keyRing: filestoreKeyring.id
});

// COMPLIANT: Filestore instance with CMEK configured
const instanceCompliant = new gcp.filestore.Instance("encrypted-filestore", {
    name: "encrypted-filestore",
    location: "us-central1",
    tier: "ENTERPRISE",
    fileShares: {
        capacityGb: 1024,
        name: "share1"
    },
    networks: [{
        network: "default",
        modes: ["MODE_IPV4"]
    }],
    kmsKeyName: filestoreKey.id  // Compliant: CMEK configured
});

// NON-COMPLIANT: Filestore instance without CMEK
const instanceNonCompliant = new gcp.filestore.Instance("default-encrypted", {
    name: "default-encrypted",
    location: "us-central1",
    tier: "BASIC_HDD",
    fileShares: {
        capacityGb: 1024,
        name: "share1"
    },
    networks: [{
        network: "default",
        modes: ["MODE_IPV4"]
    }]
    // Missing kmsKeyName - uses Google-managed keys
});
```

### cloud-firestore-autoscaling-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Cloud Firestore autoscaling is enabled

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

Remediation

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

```typescript
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

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.
- **11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

Remediation

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

```typescript
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-firestore-pitr-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Firestore point-in-time recovery is enabled and maintain isolated recovery data

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.
- **11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

Remediation

Enable point-in-time recovery by setting pointInTimeRecoveryEnablement to 'POINT_IN_TIME_RECOVERY_ENABLED'. Also set deleteProtectionState to 'DELETE_PROTECTION_ENABLED'.

```typescript
import * as gcp from "@pulumi/gcp";

// COMPLIANT: Firestore database with PITR and deletion protection enabled
const databaseCompliant = new gcp.firestore.Database("compliant-db", {
    name: "production-db",
    locationId: "nam5",
    type: "FIRESTORE_NATIVE",
    concurrencyMode: "OPTIMISTIC",
    appEngineIntegrationMode: "DISABLED",
    pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_ENABLED",  // Compliant
    deleteProtectionState: "DELETE_PROTECTION_ENABLED"  // Compliant
});

// NON-COMPLIANT: Firestore database without PITR
const databaseNonCompliant = new gcp.firestore.Database("no-pitr-db", {
    name: "test-db",
    locationId: "us-central1",
    type: "FIRESTORE_NATIVE",
    pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_DISABLED",  // Non-compliant
    deleteProtectionState: "DELETE_PROTECTION_DISABLED"  // Non-compliant
});

// NON-COMPLIANT: Datastore mode (PITR not available)
const datastoreMode = new gcp.firestore.Database("datastore-db", {
    name: "datastore-db",
    locationId: "us-central1",
    type: "DATASTORE_MODE",  // Non-compliant: PITR only available in FIRESTORE_NATIVE
    pointInTimeRecoveryEnablement: "POINT_IN_TIME_RECOVERY_ENABLED"
});
```

### cloud-functions-concurrency-check

**Severity:** medium · **Enforcement:** advisory

Configure Cloud Functions concurrency for monitoring

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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.

```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Configure VPC connector for Cloud Functions:

```typescript
// 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-functions-public-access-prohibited

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Functions prohibit public access

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Remove IAM bindings and members that grant `allUsers` or `allAuthenticatedUsers` permissions. Use Cloud IAM to grant `roles/cloudfunctions.invoker` only to specific service accounts, users, or groups. For HTTP-triggered functions requiring public access, implement authentication in the function code.

```typescript
import * as gcp from "@pulumi/gcp";

// COMPLIANT: Grant access to specific user
const member = new gcp.cloudfunctions.FunctionIamMember("function-member", {
    project: myFunction.project,
    region: myFunction.region,
    cloudFunction: myFunction.name,
    role: "roles/cloudfunctions.invoker",
    member: "user:jane@example.com",
});

// NON-COMPLIANT: Grants public access
const publicMember = new gcp.cloudfunctions.FunctionIamMember("public-member", {
    cloudFunction: myFunction.name,
    role: "roles/cloudfunctions.invoker",
    member: "allUsers", // Violates policy
});
```

### cloud-logging-encrypted

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Logging is encrypted

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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.

```typescript
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

- **7.1** — Establish and maintain a documented vulnerability management process for enterprise assets. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:
```typescript
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-backup-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud SQL backup is enabled and maintain isolated recovery data

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.
- **11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

Remediation

Enable automated backups and deletion protection. Set backupConfiguration.enabled to true, deletionProtection to true, and configure cross-region backup location for isolated recovery data.

Example Pulumi TypeScript:
```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",
        availabilityType: "REGIONAL",
        backupConfiguration: {
            enabled: true,
            startTime: "03:00",
            pointInTimeRecoveryEnabled: true,
            location: "us-west1", // Different region for isolation
            backupRetentionSettings: {
                retainedBackups: 7,
                retentionUnit: "COUNT",
            },
            transactionLogRetentionDays: 7,
        },
    },
});
```

### cloud-sql-enhanced-networking-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Cloud SQL enhanced networking is enabled

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

Remediation

Enable private IP by setting ipv4Enabled to false and configuring privateNetwork. Set requireSsl to true to enforce encrypted connections.

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const instance = new gcp.sql.DatabaseInstance("secure-db", {
    databaseVersion: "POSTGRES_15",
    region: "us-central1",
    settings: {
        tier: "db-f1-micro",
        ipConfiguration: {
            ipv4Enabled: false,
            privateNetwork: vpc.id,
            requireSsl: true,
        },
    },
});
```

### cloud-sql-instance-backup-enabled

**Severity:** high · **Enforcement:** advisory

Perform automated backups for Cloud SQL instances

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.

Remediation

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

Example Pulumi TypeScript:
```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",
            },
        },
    },
});
```

### cloud-sql-instance-deletion-protection-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud SQL instance deletion protection is enabled

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

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:
```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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```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

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:
```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-multi-region-support

**Severity:** medium · **Enforcement:** advisory

Ensure Cloud SQL multi-region support is enabled

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

Remediation

Configure Cloud SQL with REGIONAL availability type for high availability. Deploy cross-region read replicas and configure multi-region backup storage for disaster recovery.

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const instance = new gcp.sql.DatabaseInstance("ha-db", {
    databaseVersion: "POSTGRES_15",
    region: "us-central1",
    settings: {
        tier: "db-f1-micro",
        availabilityType: "REGIONAL",
        backupConfiguration: {
            enabled: true,
            location: "us", // Multi-region backup
        },
    },
});
```

### cloud-sql-storage-encrypted

**Severity:** high · **Enforcement:** advisory

Ensure Cloud SQL storage is encrypted

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

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:
```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-cross-region-replication-enabled

**Severity:** high · **Enforcement:** advisory

Perform automated backups for Cloud Storage buckets with cross-region replication and maintain isolated recovery data

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.
- **11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

Remediation

Use multi-region (US, EU, ASIA) or dual-region storage locations for automatic cross-region replication. Enable versioning and configure lifecycle rules for backup management.

### cloud-storage-bucket-default-encryption-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage buckets have default encryption enabled

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

Remediation

Configure Cloud Storage buckets to use customer-managed encryption keys (CMEK) by setting the 'encryption.defaultKmsKeyName' property with a Cloud KMS key.

### cloud-storage-bucket-encryption-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage bucket encryption is enabled

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Configure the encryption property with defaultKmsKeyName to specify a Cloud KMS key for bucket encryption using customer-managed encryption keys (CMEK).

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const bucket = new gcp.storage.Bucket("my-bucket", {
    location: "US",
    encryption: {
        defaultKmsKeyName: "projects/my-project/locations/us/keyRings/my-keyring/cryptoKeys/my-key",
    },
});
```

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

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage bucket IAM policy grantee check

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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-level-public-access-prohibited

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage bucket level public access is prohibited

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Enable uniform bucket-level access and set publicAccessPrevention to 'enforced' to prevent individual objects from being made public.

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const bucket = new gcp.storage.Bucket("private-bucket", {
    location: "US",
    uniformBucketLevelAccess: true,
    publicAccessPrevention: "enforced",
});
```

### cloud-storage-bucket-logging-enabled

**Severity:** high · **Enforcement:** advisory

Enable Cloud Storage bucket logging for monitoring

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

Remediation

Configure the logging property with logBucket set to a destination bucket and optionally logObjectPrefix for organized log storage.

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const logBucket = new gcp.storage.Bucket("log-bucket", {
    location: "US",
});

const bucket = new gcp.storage.Bucket("monitored-bucket", {
    location: "US",
    logging: {
        logBucket: logBucket.name,
        logObjectPrefix: "access-logs/",
    },
});
```

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const bucket = new gcp.storage.Bucket("my-bucket", {
    location: "US",
    logging: {
        logBucket: "my-log-bucket",
        logObjectPrefix: "bucket-logs/",
    },
});
```

### cloud-storage-bucket-public-read-prohibited

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage bucket public read is prohibited

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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.

### cloud-storage-bucket-public-write-prohibited

**Severity:** critical · **Enforcement:** advisory

Ensure Cloud Storage bucket public write is prohibited

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```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-restrict-public-read-access

**Severity:** high · **Enforcement:** advisory

Restrict public access for Cloud Storage buckets

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Remove IAM bindings granting allUsers or allAuthenticatedUsers read permissions. Enable uniform bucket-level access and use specific service accounts or groups.

### cloud-storage-bucket-ssl-requests-only

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage buckets require SSL requests only

- **3.10** — Encrypt sensitive data in transit. Example implementations can include: Transport Layer Security (TLS) and Open Secure Shell (OpenSSH).

Remediation

Enable uniform bucket-level access and set publicAccessPrevention to 'enforced'. Configure IAM conditions requiring secure transport for all bucket access.

### cloud-storage-bucket-versioning-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage bucket versioning is enabled

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

Remediation

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

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const bucket = new gcp.storage.Bucket("versioned-bucket", {
    location: "US",
    versioning: {
        enabled: true,
    },
});
```

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const bucket = new gcp.storage.Bucket("my-bucket", {
    location: "US",
    versioning: {
        enabled: true,
    },
});
```

### cloud-storage-default-encryption-kms

**Severity:** high · **Enforcement:** advisory

Ensure Cloud Storage default encryption uses Cloud KMS

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Configure the encryption property with defaultKmsKeyName to specify a Cloud KMS key for bucket encryption.

### compute-engine-instance-detailed-monitoring-enabled

**Severity:** medium · **Enforcement:** advisory

Enable Compute Engine instance detailed monitoring

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:
```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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Deploy instances in custom VPC with explicit subnetwork:

```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Remove accessConfigs from networkInterfaces to disable external IP assignment:

```typescript
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

- **12.1** — Ensure network infrastructure is kept up-to-date. Example implementations include running the latest stable release of software and/or using currently supported network as a service (NaaS) offerings. Review software versions monthly, or more frequently, to verify software support.

Remediation

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

```typescript
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

- **1.1** — Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data, to include: end-user devices (including portable and mobile), network devices, non-computing/IoT devices, and servers. Ensure the inventory records the network address (if static), hardware address, machine name, enterprise asset owner, department for each asset, and whether the asset has been approved to connect to the network. For mobile end-user devices, MDM type tools can support this process, where appropriate. This inventory includes assets connected to the infrastructure physically, virtually, remotely, and those within cloud environments. Additionally, it includes assets that are regularly connected to the enterprise's network infrastructure, even if they are not under control of the enterprise. Review and update the inventory of all enterprise assets bi-annually, or more frequently.

Remediation

Configure instances with appropriate settings based on their type:

For production instances:
```typescript
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:
```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Attach a custom service account with explicit scopes:

```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Add metadata keys to enable OS Login:

```typescript
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

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.
- **11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

Remediation

Enable deletion protection and configure boot disk:

```typescript
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

- **1.1** — Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data, to include: end-user devices (including portable and mobile), network devices, non-computing/IoT devices, and servers. Ensure the inventory records the network address (if static), hardware address, machine name, enterprise asset owner, department for each asset, and whether the asset has been approved to connect to the network. For mobile end-user devices, MDM type tools can support this process, where appropriate. This inventory includes assets connected to the infrastructure physically, virtually, remotely, and those within cloud environments. Additionally, it includes assets that are regularly connected to the enterprise's network infrastructure, even if they are not under control of the enterprise. Review and update the inventory of all enterprise assets bi-annually, or more frequently.

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:
```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

- **7.1** — Establish and maintain a documented vulnerability management process for enterprise assets. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.
- **7.3** — Perform operating system updates on enterprise assets through automated patch management on a monthly, or more frequent, basis.

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

### database-migration-service-not-publicly-accessible

**Severity:** high · **Enforcement:** advisory

Prevent public accessibility of Database Migration Service instances

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```typescript
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
    }
});
```

### 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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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.

```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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.

```typescript
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

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

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.

```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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.

```typescript
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

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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.

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

### gke-cluster-endpoint-restrict-public-access

**Severity:** high · **Enforcement:** advisory

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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Enable private endpoint by setting `privateClusterConfig.enablePrivateEndpoint: true`, or configure `masterAuthorizedNetworksConfig.cidrBlocks` with specific IP ranges (avoid 0.0.0.0/0). Consider also enabling `privateClusterConfig.enablePrivateNodes: true` for node isolation.

Pulumi TypeScript example:
```typescript
import * as gcp from "@pulumi/gcp";

// Option 1: Private GKE cluster (recommended)
const privateCluster = new gcp.container.Cluster("private-gke", {
    location: "us-central1",
    // Enable private cluster configuration
    privateClusterConfig: {
        enablePrivateEndpoint: true,  // Control plane only accessible via private IPs
        enablePrivateNodes: true,     // Nodes use private IPs only
        masterIpv4CidrBlock: "172.16.0.0/28",
    },
    // Required for private clusters
    ipAllocationPolicy: {},
    initialNodeCount: 1,
});

// Option 2: Public cluster with authorized networks
const authorizedCluster = new gcp.container.Cluster("authorized-gke", {
    location: "us-central1",
    // Restrict access to specific IP ranges
    masterAuthorizedNetworksConfig: {
        cidrBlocks: [
            {
                cidrBlock: "10.0.0.0/8",
                displayName: "Corporate Network",
            },
            {
                cidrBlock: "192.168.1.0/24",
                displayName: "VPN Gateway",
            },
        ],
    },
    initialNodeCount: 1,
});
```

### iam-no-custom-role-excessive-permissions

**Severity:** high · **Enforcement:** advisory

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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```typescript
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.

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

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:
```typescript
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-statements-with-full-access

**Severity:** critical · **Enforcement:** advisory

Prevent IAM policy bindings with full access permissions for enhanced data security.

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Review and refine IAM policy bindings. Replace broad roles like 'roles/owner' and 'roles/editor' with specific, granular roles. Use predefined roles with minimal permissions required. Follow the principle of least privilege by granting only necessary permissions.

Example - Replace owner/editor with specific roles:
```typescript
import * as gcp from "@pulumi/gcp";

// Instead of roles/editor, use specific roles
const binding = new gcp.projects.IAMMember("storage-admin", {
    project: "my-project",
    role: "roles/storage.objectAdmin",
    member: "user:admin@example.com",
});
```

### iam-policy-no-wildcard-permissions

**Severity:** critical · **Enforcement:** advisory

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

- **5.4** — Restrict administrator privileges to dedicated administrator accounts on enterprise assets. Conduct general computing activities, such as internet browsing, email, and productivity suite use, from the user's primary, non-privileged account.

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:
```typescript
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.

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:
```typescript
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",
});
```

### kms-key-not-scheduled-for-deletion

**Severity:** high · **Enforcement:** advisory

Ensure Cloud KMS keys are not scheduled for deletion

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Cancel any pending key deletions by removing destroyScheduledDuration. Implement key rotation policies instead of destroying active encryption keys to maintain data access.

Example - Create KMS key without scheduled deletion:
```typescript
import * as gcp from "@pulumi/gcp";

const key = new gcp.kms.CryptoKey("my-key", {
    name: "crypto-key",
    keyRing: keyring.id,
    rotationPeriod: "7776000s",
    // Do not set destroyScheduledDuration
});
```

### kms-key-rotation-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Cloud KMS key rotation is enabled

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

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:
```typescript
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)

### load-balancer-cloud-armor-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Load Balancer has Cloud Armor enabled for network monitoring and defense

- **13.1** — Centralize security event alerting across enterprise assets for log correlation and analysis. Best practice implementation requires the use of a SIEM, which includes vendor-defined event correlation alerts. A log analytics platform configured with security-relevant correlation alerts also satisfies this Safeguard.

Remediation

Create a Cloud Armor security policy using `gcp.compute.SecurityPolicy` and attach it to backend services via the `securityPolicy` property. Configure rules for DDoS protection, rate limiting, and geographic restrictions. Enable logging for security monitoring.

**Pulumi TypeScript Example:**

```typescript
import * as gcp from "@pulumi/gcp";

// Create Cloud Armor security policy
const securityPolicy = new gcp.compute.SecurityPolicy("cloud-armor", {
    name: "my-security-policy",
    description: "Cloud Armor policy for DDoS protection and rate limiting",
    adaptiveProtectionConfig: {
        layer7DdosDefenseConfig: {
            enable: true
        }
    },
    rules: [
        {
            action: "rate_based_ban",
            priority: 1000,
            match: {
                versionedExpr: "SRC_IPS_V1",
                config: {
                    srcIpRanges: ["*"]
                }
            },
            rateLimitOptions: {
                conformAction: "allow",
                exceedAction: "deny(429)",
                rateLimitThreshold: {
                    count: 100,
                    intervalSec: 60
                },
                banDurationSec: 600
            },
            description: "Rate limit: 100 requests per minute"
        },
        {
            action: "deny(403)",
            priority: 2000,
            match: {
                versionedExpr: "SRC_IPS_V1",
                config: {
                    srcIpRanges: ["203.0.113.0/24"]  // Block malicious IP range
                }
            },
            description: "Block known malicious IPs"
        },
        {
            action: "allow",
            priority: 2147483647,
            match: {
                versionedExpr: "SRC_IPS_V1",
                config: {
                    srcIpRanges: ["*"]
                }
            },
            description: "Default allow rule"
        }
    ]
});

// Attach Cloud Armor to backend service
const backendService = new gcp.compute.BackendService("backend", {
    name: "protected-backend",
    securityPolicy: securityPolicy.id,
    loadBalancingScheme: "EXTERNAL_MANAGED",
    healthChecks: healthCheck.id,
    backends: [{
        group: instanceGroup.id,
        balancingMode: "UTILIZATION"
    }],
    logConfig: {
        enable: true,
        sampleRate: 1.0
    }
});
```

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

**Severity:** medium · **Enforcement:** advisory

Ensure Load Balancer cross-region load balancing is enabled

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

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:**

```typescript
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-deletion-protection-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Load Balancer has high availability configuration

- **12.2** — Design and maintain a secure network architecture. A secure network architecture must address segmentation, least privilege, and availability, at a minimum. Example implementations may include documentation, policy, and design components.

Remediation

Configure load balancers for high availability:
- Backend services should have multiple backend groups across availability zones
- Health checks should be configured for automatic failover
- Connection draining timeout should be set for graceful shutdowns
- Consider using global load balancers for cross-region failover

**Pulumi TypeScript Example:**

```typescript
import * as gcp from "@pulumi/gcp";

// Create health check for availability monitoring
const healthCheck = new gcp.compute.HealthCheck("health-check", {
    name: "backend-health-check",
    checkIntervalSec: 10,
    timeoutSec: 5,
    healthyThreshold: 2,
    unhealthyThreshold: 3,
    httpHealthCheck: {
        port: 80,
        requestPath: "/health"
    }
});

// Create backend service with high availability configuration
const backendService = new gcp.compute.BackendService("backend", {
    name: "ha-backend",
    healthChecks: healthCheck.id,
    connectionDrainingTimeoutSec: 30,  // Graceful connection draining
    loadBalancingScheme: "EXTERNAL",
    protocol: "HTTP",
    timeoutSec: 30,
    backends: [
        {
            group: instanceGroup1.id,
            balancingMode: "UTILIZATION",
            capacityScaler: 1.0,
            maxUtilization: 0.8
        },
        {
            group: instanceGroup2.id,  // Multiple backend groups for HA
            balancingMode: "UTILIZATION",
            capacityScaler: 1.0,
            maxUtilization: 0.8
        }
    ]
});

// Regional backend service with health checks
const regionalBackend = new gcp.compute.RegionBackendService("regional-backend", {
    name: "regional-ha-backend",
    region: "us-central1",
    healthChecks: healthCheck.id,
    connectionDrainingTimeoutSec: 30,
    loadBalancingScheme: "INTERNAL",
    backends: [
        {
            group: regionalInstanceGroup1.id,
            balancingMode: "CONNECTION"
        },
        {
            group: regionalInstanceGroup2.id,
            balancingMode: "CONNECTION"
        }
    ]
});
```

### load-balancer-http-to-https-redirection

**Severity:** high · **Enforcement:** advisory

Ensure Load Balancer HTTP to HTTPS redirection is configured

- **3.10** — Encrypt sensitive data in transit. Example implementations can include: Transport Layer Security (TLS) and Open Secure Shell (OpenSSH).

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:**

```typescript
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

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:**

```typescript
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-managed-ssl-certificate

**Severity:** high · **Enforcement:** advisory

Ensure Load Balancer uses managed SSL certificates

- **3.10** — Encrypt sensitive data in transit. Example implementations can include: Transport Layer Security (TLS) and Open Secure Shell (OpenSSH).

Remediation

Create managed SSL certificates using `gcp.compute.ManagedSslCertificate` with domains specified. Attach certificates to HTTPS target proxies via `sslCertificates` property. Google will automatically provision and renew certificates.

**Pulumi TypeScript Example:**

```typescript
import * as gcp from "@pulumi/gcp";

// Create Google-managed SSL certificate
const managedCert = new gcp.compute.ManagedSslCertificate("managed-cert", {
    name: "auto-renew-cert",
    managed: {
        domains: [
            "example.com",
            "www.example.com",
            "api.example.com"
        ]
    }
});

// Create backend service
const backendService = new gcp.compute.BackendService("backend", {
    name: "my-backend-service",
    healthChecks: healthCheck.id,
    backends: [{
        group: instanceGroup.id,
        balancingMode: "UTILIZATION"
    }]
});

// Create URL map
const urlMap = new gcp.compute.URLMap("url-map", {
    name: "lb-url-map",
    defaultService: backendService.id
});

// Create HTTPS proxy with managed certificate
const httpsProxy = new gcp.compute.TargetHttpsProxy("https-proxy", {
    name: "lb-https-proxy",
    urlMap: urlMap.id,
    sslCertificates: [managedCert.id]
});

// Create global forwarding rule
const forwardingRule = new gcp.compute.GlobalForwardingRule("https-rule", {
    name: "lb-forwarding-rule",
    target: httpsProxy.id,
    portRange: "443",
    ipProtocol: "TCP",
    loadBalancingScheme: "EXTERNAL"
});

// Regional managed SSL certificate example
const regionalHttpsProxy = new gcp.compute.RegionTargetHttpsProxy("regional-proxy", {
    name: "regional-https-proxy",
    region: "us-central1",
    urlMap: regionalUrlMap.id,
    sslCertificates: [managedCert.id]
});
```

### load-balancer-tls-https-listeners-only

**Severity:** high · **Enforcement:** advisory

Ensure Load Balancer uses TLS/HTTPS listeners only

- **3.10** — Encrypt sensitive data in transit. Example implementations can include: Transport Layer Security (TLS) and Open Secure Shell (OpenSSH).

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:**

```typescript
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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

Remediation

Disable public IP in instance template:

```typescript
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

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

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:
```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

- **3.8** — Document data flows. Data flow documentation includes service provider data flows and should be based on the enterprise's data management process. Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:**

```typescript
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-attached-encryption-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Persistent Disks are encrypted when attached

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

Remediation

Configure persistent disks to use customer-managed encryption keys (CMEK) by setting the 'diskEncryptionKey' property with a KMS key. If CMEK is not required, Google-managed encryption is enabled by default.

### persistent-disk-encrypted

**Severity:** high · **Enforcement:** advisory

Ensure Persistent Disks are encrypted

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Configure diskEncryptionKey property with kmsKeySelfLink to use customer-managed encryption keys (CMEK) for enhanced security.

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const disk = new gcp.compute.Disk("my-disk", {
    zone: "us-central1-a",
    type: "pd-standard",
    size: 10,
    diskEncryptionKey: {
        kmsKeySelfLink: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",
    },
});
```

### persistent-disk-in-backup-plan

**Severity:** high · **Enforcement:** advisory

Perform automated backups for Persistent Disks and maintain isolated recovery data

- **11.2** — Perform automated backups of in-scope enterprise assets. Run backups weekly, or more frequently, based on the sensitivity of the data.
- **11.4** — Establish and maintain an isolated instance of recovery data. Example implementations include version controlling backup destinations through offline, cloud, or off-site systems or services.

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

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

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.

### project-part-of-organization

**Severity:** medium · **Enforcement:** advisory

Ensure project is part of GCP Organization

- **4.1** — Establish and maintain a documented secure configuration process for enterprise assets (end-user devices, including portable and mobile, non-computing/IoT devices, and servers) and software (operating systems and applications). Review and update documentation annually, or when significant enterprise changes occur that could impact this Safeguard.

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:
```typescript
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-encrypted-kms

**Severity:** medium · **Enforcement:** advisory

Ensure Pub/Sub is encrypted with Cloud KMS

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

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:
```typescript
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
});
```

### restricted-ssh

**Severity:** high · **Enforcement:** advisory

Restrict SSH access for monitoring compliance

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

Remediation

Restrict SSH access by updating firewall rule sourceRanges to specific trusted IP CIDR blocks instead of 0.0.0.0/0. Use Identity-Aware Proxy (IAP) with source range 35.235.240.0/20 for secure SSH access. Implement bastion hosts or VPN for remote access.

Example Pulumi TypeScript:
```typescript
import * as gcp from "@pulumi/gcp";

const sshFirewall = new gcp.compute.Firewall("restricted-ssh", {
    network: vpc.id,
    direction: "INGRESS",
    sourceRanges: [
        "10.0.0.0/8",        // Internal network
        "35.235.240.0/20",   // IAP for SSH
    ],
    allows: [{
        protocol: "tcp",
        ports: ["22"],
    }],
});
```

### secret-manager-using-cmek

**Severity:** high · **Enforcement:** advisory

Ensure Secret Manager uses customer-managed encryption keys

- **3.11** — Encrypt sensitive data at rest on servers, applications, and databases. Storage-layer encryption, also known as server-side encryption, meets the minimum requirement of this Safeguard. Additional encryption methods may include application-layer encryption, also known as client-side encryption, where access to the data storage device(s) does not permit access to the plain-text data.

Remediation

Configure Secret Manager secrets with customer-managed encryption keys (CMEK). Set the replication property with customerManagedEncryption and kmsKeyName for automatic replication, or configure customerManagedEncryption on each replica for user-managed replication. This provides enhanced security and key management control over sensitive secrets.

```typescript
import * as gcp from "@pulumi/gcp";

// Create KMS keys for encryption
const keyring = new gcp.kms.KeyRing("secret-keyring", {
    name: "secret-keyring",
    location: "us-central1"
});

const kmsKey = new gcp.kms.CryptoKey("secret-key", {
    name: "secret-key",
    keyRing: keyring.id
});

// COMPLIANT: Secret with auto replication and CMEK
const secretAutoCompliant = new gcp.secretmanager.Secret("auto-cmek-secret", {
    secretId: "api-key",
    replication: {
        auto: {
            customerManagedEncryption: {
                kmsKeyName: kmsKey.id  // Compliant: CMEK configured
            }
        }
    }
});

// COMPLIANT: Secret with user-managed replication and CMEK per region
const secretUserManagedCompliant = new gcp.secretmanager.Secret("user-managed-cmek", {
    secretId: "database-password",
    replication: {
        userManaged: {
            replicas: [
                {
                    location: "us-central1",
                    customerManagedEncryption: {
                        kmsKeyName: kmsKey.id  // Compliant: CMEK per replica
                    }
                },
                {
                    location: "us-east1",
                    customerManagedEncryption: {
                        kmsKeyName: kmsKeyEast.id
                    }
                }
            ]
        }
    }
});

// NON-COMPLIANT: Secret without CMEK (uses Google-managed keys)
const secretNonCompliant = new gcp.secretmanager.Secret("no-cmek-secret", {
    secretId: "api-token",
    replication: {
        auto: {}  // Missing customerManagedEncryption
    }
});

// NON-COMPLIANT: User-managed replication without CMEK
const secretUserManagedNonCompliant = new gcp.secretmanager.Secret("no-cmek-user-managed", {
    secretId: "credentials",
    replication: {
        userManaged: {
            replicas: [
                {
                    location: "us-central1"
                    // Missing customerManagedEncryption
                }
            ]
        }
    }
});
```

### security-command-center-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Security Command Center is enabled

- **1.2** — Ensure that a process exists to address unauthorized assets on a weekly basis. The enterprise may choose to remove the asset from the network, deny the asset from connecting remotely to the network, or quarantine the asset.

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:
```typescript
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"' },
});
```

### subnet-auto-assign-external-ip-disabled

**Severity:** medium · **Enforcement:** advisory

Ensure Private Google Access is enabled on VPC subnets

- **3.3** — Configure data access control lists based on a user's need to know. Apply data access control lists, also known as access permissions, to local and remote file systems, databases, and applications.

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:**

```typescript
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

- **1.1** — Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data, to include: end-user devices (including portable and mobile), network devices, non-computing/IoT devices, and servers. Ensure the inventory records the network address (if static), hardware address, machine name, enterprise asset owner, department for each asset, and whether the asset has been approved to connect to the network. For mobile end-user devices, MDM type tools can support this process, where appropriate. This inventory includes assets connected to the infrastructure physically, virtually, remotely, and those within cloud environments. Additionally, it includes assets that are regularly connected to the enterprise's network infrastructure, even if they are not under control of the enterprise. Review and update the inventory of all enterprise assets bi-annually, or more frequently.

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:**

```typescript
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:** mandatory

Ensure VPC firewall rules are associated to networks

- **1.1** — Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data, to include: end-user devices (including portable and mobile), network devices, non-computing/IoT devices, and servers. Ensure the inventory records the network address (if static), hardware address, machine name, enterprise asset owner, department for each asset, and whether the asset has been approved to connect to the network. For mobile end-user devices, MDM type tools can support this process, where appropriate. This inventory includes assets connected to the infrastructure physically, virtually, remotely, and those within cloud environments. Additionally, it includes assets that are regularly connected to the enterprise's network infrastructure, even if they are not under control of the enterprise. Review and update the inventory of all enterprise assets bi-annually, or more frequently.

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:**

```typescript
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-restrict-ingress-ssh-all

**Severity:** high · **Enforcement:** advisory

Restrict SSH access from all IPs in firewall rules

- **4.6** — Securely manage enterprise assets and software. Example implementations include managing configuration through version-controlled Infrastructure-as-Code (IaC) and accessing administrative interfaces over secure network protocols, such as Secure Shell (SSH) and Hypertext Transfer Protocol Secure (HTTPS). Do not use insecure management protocols, such as Telnet (Teletype Network) and HTTP, unless operationally essential.

Remediation

Restrict SSH access by updating firewall rules to allow SSH (port 22) only from specific trusted IP ranges. Remove rules that allow SSH from 0.0.0.0/0 or ::/0. Use Identity-Aware Proxy (IAP) or bastion hosts for secure SSH access.

**Pulumi TypeScript Example:**

```typescript
import * as gcp from "@pulumi/gcp";

// Secure SSH rule - restrict to specific IPs
const sshFirewall = new gcp.compute.Firewall("ssh-restricted", {
    network: "default",
    direction: "INGRESS",
    allows: [{
        protocol: "tcp",
        ports: ["22"]
    }],
    sourceRanges: [
        "203.0.113.0/24",  // Replace with your trusted IP ranges
        "198.51.100.0/24"
    ],
    targetTags: ["ssh-enabled"]
});

// Alternative: Use IAP for SSH (recommended)
const iapSshFirewall = new gcp.compute.Firewall("ssh-iap", {
    network: "default",
    direction: "INGRESS",
    allows: [{
        protocol: "tcp",
        ports: ["22"]
    }],
    sourceRanges: ["35.235.240.0/20"],  // IAP IP range
    description: "Allow SSH via Identity-Aware Proxy"
});
```

### vpc-firewall-rule-unused

**Severity:** low · **Enforcement:** advisory

Ensure VPC firewall rules are not unused

- **1.1** — Establish and maintain an accurate, detailed, and up-to-date inventory of all enterprise assets with the potential to store or process data, to include: end-user devices (including portable and mobile), network devices, non-computing/IoT devices, and servers. Ensure the inventory records the network address (if static), hardware address, machine name, enterprise asset owner, department for each asset, and whether the asset has been approved to connect to the network. For mobile end-user devices, MDM type tools can support this process, where appropriate. This inventory includes assets connected to the infrastructure physically, virtually, remotely, and those within cloud environments. Additionally, it includes assets that are regularly connected to the enterprise's network infrastructure, even if they are not under control of the enterprise. Review and update the inventory of all enterprise assets bi-annually, or more frequently.

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:**

```typescript
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

- **8.2** — Collect audit logs. Ensure that logging, per the enterprise's audit log management process, has been enabled across enterprise assets.

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:**

```typescript
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


