Built-in scenario

sample_gcp_plan.json

GCP Inventory Demo

Analyzed sample_gcp_plan.json with 14 normalized resources and 3 trust boundaries.

Analyze another plan

Active findings

12

Trust boundaries

3

Resources

14

Observations

0
High 2
Medium 10
Low 0

Analysis coverage

Audit trail for this run

Terraform resources 14
Unsupported 0
Enabled rules 29
Unresolved refs 0

Resource coverage

Provider resources considered
14
Normalized resources
14

No unsupported AWS resource types were encountered.

Rule coverage

Registered rules
29
Disabled rules
0
  • gcp-sensitive-resource-iam-external-access2
  • gcp-cloud-sql-public-authorized-network1
  • gcp-cloud-sql-backup-disabled1
  • gcp-cloud-sql-public-ip-without-private-network1
  • gcp-cloud-sql-ssl-not-required1
  • gcp-cloud-sql-deletion-protection-disabled1
  • gcp-gcs-public-access1
  • gcp-gcs-public-access-prevention-not-enforced1
  • gcp-gcs-versioning-disabled1
  • gcp-gcs-customer-managed-encryption-missing1
  • gcp-public-compute-broad-ingress1

Findings

Severity bands

High

2

Cloud SQL instance accepts public authorized network access

gcp-cloud-sql-public-authorized-network

google_sql_database_instance.app has a public Cloud SQL IPv4 endpoint and an authorized network that allows internet-wide client sources. That weakens the database trust boundary even when database authentication is still required.

Category
Information Disclosure
Boundary
internet-to-service:internet->google_sql_database_instance.app
Resources
google_sql_database_instance.app
Evidence
  • authorized networks: anywhere (0.0.0.0/0)
  • public exposure reasons: authorized network `anywhere` allows 0.0.0.0/0

Sensitive GCP resource IAM binding allows broad or external access

gcp-sensitive-resource-iam-external-access

google_secret_manager_secret.api_key grants `roles/secretmanager.secretAccessor` to `allAuthenticatedUsers` through GCP IAM. Public, broad-domain, or foreign-project principals can access sensitive secrets or cryptographic key operations outside the expected project trust boundary.

Category
Information Disclosure
Boundary
not-applicable
Resources
google_secret_manager_secret.api_key, google_secret_manager_secret_iam_member.public_accessor
Evidence
  • iam binding: source=google_secret_manager_secret_iam_member.public_accessor; role=roles/secretmanager.secretAccessor; member=allAuthenticatedUsers
  • trust scope: member is public GCP principal `allAuthenticatedUsers`
  • resource policy sources: google_secret_manager_secret_iam_member.public_accessor

Medium

10

Cloud SQL automated backups are disabled

gcp-cloud-sql-backup-disabled

google_sql_database_instance.app does not have Cloud SQL automated backups enabled. A destructive change, operator error, or data corruption event would have fewer managed recovery points.

Category
Denial of Service
Boundary
not-applicable
Resources
google_sql_database_instance.app
Evidence
  • backup posture: backup_configuration.enabled is false; point_in_time_recovery_enabled is false; engine is POSTGRES_15

Cloud SQL deletion protection is disabled

gcp-cloud-sql-deletion-protection-disabled

google_sql_database_instance.app has Cloud SQL deletion protection disabled. Accidental or unauthorized infrastructure changes could destroy the managed database instance without this provider-level guardrail.

Category
Denial of Service
Boundary
not-applicable
Resources
google_sql_database_instance.app
Evidence
  • lifecycle posture: deletion_protection is false

Cloud SQL public IPv4 is enabled without private network access

gcp-cloud-sql-public-ip-without-private-network

google_sql_database_instance.app has Cloud SQL public IPv4 enabled without a private network attachment. That keeps database client access on a public endpoint instead of an internal VPC path.

Category
Information Disclosure
Boundary
internet-to-service:internet->google_sql_database_instance.app
Resources
google_sql_database_instance.app
Evidence
  • network posture: ipv4_enabled is true; private_network is unset; authorized_networks configured: 1
  • public access reasons: Cloud SQL public IPv4 access is enabled

Cloud SQL public client access does not require SSL

gcp-cloud-sql-ssl-not-required

google_sql_database_instance.app allows Cloud SQL public IPv4 client access without requiring encrypted client connections. Credentials and database traffic should not depend on client-side optional TLS behavior.

Category
Information Disclosure
Boundary
internet-to-service:internet->google_sql_database_instance.app
Resources
google_sql_database_instance.app
Evidence
  • ssl posture: require_ssl is false; ssl_mode is unset; ipv4_enabled is true

GCS bucket does not enforce Public Access Prevention

gcp-gcs-public-access-prevention-not-enforced

google_storage_bucket.logs does not enforce GCS Public Access Prevention. Public principals can still be introduced through bucket IAM unless an organization-level policy blocks them.

Category
Information Disclosure
Boundary
internet-to-service:internet->google_storage_bucket.logs
Resources
google_storage_bucket.logs
Evidence
  • access control posture: public_access_prevention is unset
  • public exposure reasons: google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers

GCS bucket is publicly accessible

gcp-gcs-public-access

google_storage_bucket.logs is publicly reachable through GCS IAM grants. Public bucket access is a common source of unintended object disclosure.

Category
Information Disclosure
Boundary
internet-to-service:internet->google_storage_bucket.logs
Resources
google_storage_bucket.logs
Evidence
  • public exposure reasons: google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers

GCS sensitive bucket does not use customer-managed encryption

gcp-gcs-customer-managed-encryption-missing

google_storage_bucket.logs relies on default GCS encryption rather than a customer-managed KMS key. Sensitive buckets lose key ownership, rotation, and separation-of-duties controls that a CMEK can provide.

Category
Information Disclosure
Boundary
not-applicable
Resources
google_storage_bucket.logs
Evidence
  • encryption posture: default_kms_key_name is unset; customer_managed_encryption is false

GCS sensitive bucket versioning is disabled

gcp-gcs-versioning-disabled

google_storage_bucket.logs stores sensitive GCS data without bucket versioning. Accidental overwrites, deletes, or destructive changes have fewer object-level recovery options.

Category
Denial of Service
Boundary
not-applicable
Resources
google_storage_bucket.logs
Evidence
  • data protection posture: versioning.enabled is false; data_sensitivity is sensitive

Internet-exposed GCP compute instance permits broad ingress

gcp-public-compute-broad-ingress

google_compute_instance.web has an external access config and matching GCP firewall rules allow administrative access or all ports from the public internet. That broad ingress raises the chance of unauthenticated probing and credential attacks.

Category
Spoofing
Boundary
internet-to-service:internet->google_compute_instance.web
Resources
google_compute_instance.web, google_compute_firewall.public_ssh
Evidence
  • firewall rules: google_compute_firewall.public_ssh ingress tcp 22 from 0.0.0.0/0
  • network tags: web
  • public exposure reasons: compute instance has an external access config and matching firewall rules allow internet ingress

Sensitive GCP resource IAM binding allows broad or external access

gcp-sensitive-resource-iam-external-access

google_kms_crypto_key.customer grants `roles/cloudkms.cryptoKeyDecrypter` to `serviceAccount:decryptor@partner-project.iam.gserviceaccount.com` through GCP IAM. Public, broad-domain, or foreign-project principals can access sensitive secrets or cryptographic key operations outside the expected project trust boundary.

Category
Information Disclosure
Boundary
not-applicable
Resources
google_kms_crypto_key.customer, google_kms_crypto_key_iam_member.partner_decrypter
Evidence
  • iam binding: source=google_kms_crypto_key_iam_member.partner_decrypter; role=roles/cloudkms.cryptoKeyDecrypter; member=serviceAccount:decryptor@partner-project.iam.gserviceaccount.com
  • trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`
  • resource policy sources: google_kms_crypto_key_iam_member.partner_decrypter

Low

0

No low findings.

Observations

Controls and mitigating signals

No observations were recorded for this plan.

Trust boundaries

Crossings that drive the model

internet-to-service

internet -> google_compute_instance.web

The resource is directly reachable or intentionally exposed to unauthenticated network clients.

internet-to-service

internet -> google_sql_database_instance.app

The resource is directly reachable or intentionally exposed to unauthenticated network clients.

internet-to-service

internet -> google_storage_bucket.logs

The resource is directly reachable or intentionally exposed to unauthenticated network clients.

Raw outputs

Stable contract and markdown

JSON report
{
  "kind": "tfstride-report",
  "version": "1.1",
  "tool": {
    "name": "tfstride",
    "version": "0.2.8"
  },
  "title": "GCP Inventory Demo",
  "analyzed_file": "sample_gcp_plan.json",
  "analyzed_path": "sample_gcp_plan.json",
  "summary": {
    "normalized_resources": 14,
    "unsupported_resources": 0,
    "trust_boundaries": 3,
    "active_findings": 12,
    "total_findings": 12,
    "suppressed_findings": 0,
    "baselined_findings": 0,
    "severity_counts": {
      "high": 2,
      "medium": 10,
      "low": 0
    }
  },
  "filtering": {
    "total_findings": 12,
    "active_findings": 12,
    "suppressed_findings": 0,
    "baselined_findings": 0,
    "suppressions_path": null,
    "baseline_path": null
  },
  "analysis_coverage": {
    "resources": {
      "total_resources": 14,
      "provider_resources": 14,
      "normalized_resources": 14,
      "unsupported_resources": 0,
      "unsupported_resource_types": {}
    },
    "rules": {
      "registered_rule_count": 29,
      "enabled_rules": [
        "aws-public-compute-broad-ingress",
        "aws-database-permissive-ingress",
        "aws-rds-storage-encryption-disabled",
        "aws-s3-public-access",
        "aws-sensitive-resource-policy-external-access",
        "aws-service-resource-policy-external-access",
        "aws-iam-wildcard-permissions",
        "aws-workload-role-sensitive-permissions",
        "aws-missing-tier-segmentation",
        "aws-private-data-transitive-exposure",
        "aws-control-plane-sensitive-workload-chain",
        "aws-role-trust-expansion",
        "aws-role-trust-missing-narrowing",
        "gcp-sensitive-resource-iam-external-access",
        "gcp-public-workload-sensitive-data-access",
        "gcp-cloud-sql-public-authorized-network",
        "gcp-cloud-sql-backup-disabled",
        "gcp-cloud-sql-public-ip-without-private-network",
        "gcp-cloud-sql-ssl-not-required",
        "gcp-cloud-sql-point-in-time-recovery-disabled",
        "gcp-cloud-sql-deletion-protection-disabled",
        "gcp-gcs-public-access",
        "gcp-gcs-uniform-bucket-level-access-disabled",
        "gcp-gcs-public-access-prevention-not-enforced",
        "gcp-gcs-versioning-disabled",
        "gcp-gcs-customer-managed-encryption-missing",
        "gcp-public-compute-broad-ingress",
        "gcp-project-iam-broad-principal",
        "gcp-project-iam-privileged-role"
      ],
      "disabled_rules": [],
      "severity_overrides": {},
      "finding_counts_by_rule": {
        "aws-public-compute-broad-ingress": 0,
        "aws-database-permissive-ingress": 0,
        "aws-rds-storage-encryption-disabled": 0,
        "aws-s3-public-access": 0,
        "aws-sensitive-resource-policy-external-access": 0,
        "aws-service-resource-policy-external-access": 0,
        "aws-iam-wildcard-permissions": 0,
        "aws-workload-role-sensitive-permissions": 0,
        "aws-missing-tier-segmentation": 0,
        "aws-private-data-transitive-exposure": 0,
        "aws-control-plane-sensitive-workload-chain": 0,
        "aws-role-trust-expansion": 0,
        "aws-role-trust-missing-narrowing": 0,
        "gcp-sensitive-resource-iam-external-access": 2,
        "gcp-public-workload-sensitive-data-access": 0,
        "gcp-cloud-sql-public-authorized-network": 1,
        "gcp-cloud-sql-backup-disabled": 1,
        "gcp-cloud-sql-public-ip-without-private-network": 1,
        "gcp-cloud-sql-ssl-not-required": 1,
        "gcp-cloud-sql-point-in-time-recovery-disabled": 0,
        "gcp-cloud-sql-deletion-protection-disabled": 1,
        "gcp-gcs-public-access": 1,
        "gcp-gcs-uniform-bucket-level-access-disabled": 0,
        "gcp-gcs-public-access-prevention-not-enforced": 1,
        "gcp-gcs-versioning-disabled": 1,
        "gcp-gcs-customer-managed-encryption-missing": 1,
        "gcp-public-compute-broad-ingress": 1,
        "gcp-project-iam-broad-principal": 0,
        "gcp-project-iam-privileged-role": 0
      }
    },
    "references": {
      "unresolved_reference_count": 0,
      "unresolved_references": []
    }
  },
  "inventory": {
    "provider": "gcp",
    "unsupported_resources": [],
    "metadata": {
      "supported_resource_types": [
        "google_compute_firewall",
        "google_compute_forwarding_rule",
        "google_compute_global_forwarding_rule",
        "google_compute_instance",
        "google_compute_network",
        "google_compute_route",
        "google_compute_router",
        "google_compute_router_nat",
        "google_compute_subnetwork",
        "google_kms_crypto_key",
        "google_kms_crypto_key_iam_binding",
        "google_kms_crypto_key_iam_member",
        "google_kms_crypto_key_iam_policy",
        "google_project_iam_member",
        "google_secret_manager_secret",
        "google_secret_manager_secret_iam_binding",
        "google_secret_manager_secret_iam_member",
        "google_secret_manager_secret_iam_policy",
        "google_service_account",
        "google_service_account_iam_binding",
        "google_service_account_iam_member",
        "google_service_account_iam_policy",
        "google_service_account_key",
        "google_sql_database_instance",
        "google_storage_bucket",
        "google_storage_bucket_iam_binding",
        "google_storage_bucket_iam_member",
        "google_storage_bucket_iam_policy"
      ],
      "total_input_resources": 14,
      "provider_resource_count": 14,
      "normalized_resource_count": 14,
      "unsupported_resource_types": {}
    },
    "resources": [
      {
        "address": "google_compute_firewall.public_ssh",
        "provider": "gcp",
        "resource_type": "google_compute_firewall",
        "name": "public_ssh",
        "category": "network",
        "identifier": "tfstride-public-ssh",
        "arn": null,
        "vpc_id": "google_compute_network.main.name",
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [
          {
            "direction": "ingress",
            "protocol": "tcp",
            "from_port": 22,
            "to_port": 22,
            "cidr_blocks": [
              "0.0.0.0/0"
            ],
            "ipv6_cidr_blocks": [],
            "referenced_security_group_ids": [],
            "description": null
          }
        ],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "name": "tfstride-public-ssh",
          "self_link": null,
          "project": null,
          "network": "google_compute_network.main.name",
          "allow": [
            {
              "protocol": "tcp",
              "ports": [
                "22"
              ]
            }
          ],
          "deny": [],
          "source_ranges": [
            "0.0.0.0/0"
          ],
          "destination_ranges": [],
          "target_tags": [
            "web"
          ],
          "source_tags": [],
          "target_service_accounts": [],
          "source_service_accounts": [],
          "direction": "ingress",
          "priority": null,
          "disabled": false
        }
      },
      {
        "address": "google_compute_instance.web",
        "provider": "gcp",
        "resource_type": "google_compute_instance",
        "name": "web",
        "category": "compute",
        "identifier": "tfstride-web",
        "arn": null,
        "vpc_id": "google_compute_network.main.id",
        "subnet_ids": [
          "google_compute_subnetwork.app.id"
        ],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": true,
        "public_exposure": true,
        "data_sensitivity": "standard",
        "metadata": {
          "name": "tfstride-web",
          "self_link": null,
          "project": null,
          "zone": "us-central1-a",
          "machine_type": "e2-medium",
          "network_tags": [
            "web"
          ],
          "network_interfaces": [
            {
              "subnetwork": "google_compute_subnetwork.app.id",
              "access_config": [
                {
                  "nat_ip": "35.1.2.3"
                }
              ]
            }
          ],
          "service_accounts": [
            {
              "email": "tfstride-web@example.iam.gserviceaccount.com",
              "scopes": [
                "cloud-platform"
              ]
            }
          ],
          "labels": {},
          "can_ip_forward": false,
          "public_access_reasons": [
            "compute instance has an external access config"
          ],
          "public_exposure_reasons": [
            "compute instance has an external access config and matching firewall rules allow internet ingress"
          ],
          "in_public_subnet": false,
          "has_nat_gateway_egress": false,
          "has_public_route": false,
          "internet_ingress_capable": true,
          "internet_ingress_reasons": [
            "google_compute_firewall.public_ssh ingress tcp 22 from 0.0.0.0/0"
          ],
          "internet_ingress_firewalls": [
            "google_compute_firewall.public_ssh"
          ],
          "direct_internet_reachable": true
        }
      },
      {
        "address": "google_compute_network.main",
        "provider": "gcp",
        "resource_type": "google_compute_network",
        "name": "main",
        "category": "network",
        "identifier": "tfstride-main",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "name": "tfstride-main",
          "self_link": null,
          "project": null,
          "auto_create_subnetworks": false,
          "routing_mode": "REGIONAL",
          "description": null
        }
      },
      {
        "address": "google_compute_subnetwork.app",
        "provider": "gcp",
        "resource_type": "google_compute_subnetwork",
        "name": "app",
        "category": "network",
        "identifier": "tfstride-app",
        "arn": null,
        "vpc_id": "google_compute_network.main.id",
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "name": "tfstride-app",
          "self_link": null,
          "project": null,
          "region": "us-central1",
          "network": "google_compute_network.main.id",
          "cidr_range": "10.10.1.0/24",
          "private_ip_google_access": false,
          "purpose": null,
          "stack_type": null,
          "secondary_ip_ranges": [],
          "has_public_route": false,
          "is_public_subnet": false,
          "has_nat_gateway_egress": false
        }
      },
      {
        "address": "google_kms_crypto_key.customer",
        "provider": "gcp",
        "resource_type": "google_kms_crypto_key",
        "name": "customer",
        "category": "data",
        "identifier": "projects/tfstride-demo/locations/global/keyRings/tfstride-app/cryptoKeys/tfstride-customer-key",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "sensitive",
        "metadata": {
          "name": "tfstride-customer-key",
          "self_link": null,
          "project": "tfstride-demo",
          "kms_crypto_key_reference": "projects/tfstride-demo/locations/global/keyRings/tfstride-app/cryptoKeys/tfstride-customer-key",
          "kms_key_ring": "projects/tfstride-demo/locations/global/keyRings/tfstride-app",
          "kms_purpose": "ENCRYPT_DECRYPT",
          "kms_rotation_period": "7776000s",
          "labels": {
            "app": "tfstride"
          },
          "destroy_scheduled_duration": null,
          "import_only": false,
          "skip_initial_version_creation": false,
          "storage_encrypted": true,
          "iam_bindings": [
            {
              "role": "roles/cloudkms.cryptoKeyDecrypter",
              "members": [
                "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com"
              ],
              "source": "google_kms_crypto_key_iam_member.partner_decrypter"
            }
          ],
          "gcp_resource_policy_source_addresses": [
            "google_kms_crypto_key_iam_member.partner_decrypter"
          ]
        }
      },
      {
        "address": "google_kms_crypto_key_iam_member.partner_decrypter",
        "provider": "gcp",
        "resource_type": "google_kms_crypto_key_iam_member",
        "name": "partner_decrypter",
        "category": "iam",
        "identifier": "google_kms_crypto_key.customer.id:roles/cloudkms.cryptoKeyDecrypter:serviceAccount:decryptor@partner-project.iam.gserviceaccount.com",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "kms_crypto_key_reference": "google_kms_crypto_key.customer.id",
          "project": null,
          "iam_role": "roles/cloudkms.cryptoKeyDecrypter",
          "iam_member": "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com",
          "iam_members": [
            "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com"
          ],
          "iam_bindings": [
            {
              "role": "roles/cloudkms.cryptoKeyDecrypter",
              "members": [
                "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com"
              ]
            }
          ],
          "condition": null
        }
      },
      {
        "address": "google_project_iam_member.web_viewer",
        "provider": "gcp",
        "resource_type": "google_project_iam_member",
        "name": "web_viewer",
        "category": "iam",
        "identifier": "roles/viewer:serviceAccount:tfstride-web@example.iam.gserviceaccount.com",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "project": "tfstride-demo",
          "iam_role": "roles/viewer",
          "iam_member": "serviceAccount:tfstride-web@example.iam.gserviceaccount.com",
          "condition": null
        }
      },
      {
        "address": "google_secret_manager_secret.api_key",
        "provider": "gcp",
        "resource_type": "google_secret_manager_secret",
        "name": "api_key",
        "category": "data",
        "identifier": "projects/tfstride-demo/secrets/tfstride-api-key",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "sensitive",
        "metadata": {
          "name": "projects/tfstride-demo/secrets/tfstride-api-key",
          "secret_id": "tfstride-api-key",
          "project": "tfstride-demo",
          "labels": {
            "app": "tfstride"
          },
          "annotations": {},
          "replication": [
            {
              "auto": [
                {}
              ]
            }
          ],
          "topics": [],
          "expire_time": null,
          "ttl": null,
          "version_destroy_ttl": null,
          "storage_encrypted": true,
          "iam_bindings": [
            {
              "role": "roles/secretmanager.secretAccessor",
              "members": [
                "allAuthenticatedUsers"
              ],
              "source": "google_secret_manager_secret_iam_member.public_accessor"
            }
          ],
          "gcp_resource_policy_source_addresses": [
            "google_secret_manager_secret_iam_member.public_accessor"
          ]
        }
      },
      {
        "address": "google_secret_manager_secret_iam_member.public_accessor",
        "provider": "gcp",
        "resource_type": "google_secret_manager_secret_iam_member",
        "name": "public_accessor",
        "category": "iam",
        "identifier": "google_secret_manager_secret.api_key.id:roles/secretmanager.secretAccessor:allAuthenticatedUsers",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "secret_reference": "google_secret_manager_secret.api_key.id",
          "project": "tfstride-demo",
          "iam_role": "roles/secretmanager.secretAccessor",
          "iam_member": "allAuthenticatedUsers",
          "iam_members": [
            "allAuthenticatedUsers"
          ],
          "iam_bindings": [
            {
              "role": "roles/secretmanager.secretAccessor",
              "members": [
                "allAuthenticatedUsers"
              ]
            }
          ],
          "condition": null
        }
      },
      {
        "address": "google_service_account.web",
        "provider": "gcp",
        "resource_type": "google_service_account",
        "name": "web",
        "category": "iam",
        "identifier": "tfstride-web@example.iam.gserviceaccount.com",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "name": "projects/tfstride-demo/serviceAccounts/tfstride-web@example.iam.gserviceaccount.com",
          "project": "tfstride-demo",
          "service_account_account_id": "tfstride-web",
          "service_account_email": "tfstride-web@example.iam.gserviceaccount.com",
          "service_account_member": "serviceAccount:tfstride-web@example.iam.gserviceaccount.com",
          "service_account_unique_id": "100000000000000000001",
          "service_account_disabled": false,
          "display_name": "tfSTRIDE web workload",
          "description": "Service account used by the sample web instance."
        }
      },
      {
        "address": "google_service_account_key.web",
        "provider": "gcp",
        "resource_type": "google_service_account_key",
        "name": "web",
        "category": "iam",
        "identifier": "projects/tfstride-demo/serviceAccounts/tfstride-web@example.iam.gserviceaccount.com/keys/sample-key",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "name": "projects/tfstride-demo/serviceAccounts/tfstride-web@example.iam.gserviceaccount.com/keys/sample-key",
          "project": null,
          "service_account_reference": "google_service_account.web.email",
          "service_account_key_algorithm": "KEY_ALG_RSA_2048",
          "service_account_public_key_type": "TYPE_X509_PEM_FILE",
          "valid_after": "2026-01-01T00:00:00Z",
          "valid_before": "2027-01-01T00:00:00Z",
          "keepers": {}
        }
      },
      {
        "address": "google_sql_database_instance.app",
        "provider": "gcp",
        "resource_type": "google_sql_database_instance",
        "name": "app",
        "category": "data",
        "identifier": "tfstride-app-db",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": true,
        "public_exposure": true,
        "data_sensitivity": "sensitive",
        "metadata": {
          "name": "tfstride-app-db",
          "self_link": null,
          "project": "tfstride-demo",
          "region": "us-central1",
          "database_version": "POSTGRES_15",
          "cloud_sql_private_network": null,
          "cloud_sql_ssl_mode": null,
          "cloud_sql_ipv4_enabled": true,
          "cloud_sql_backup_enabled": false,
          "cloud_sql_point_in_time_recovery_enabled": false,
          "cloud_sql_require_ssl": false,
          "cloud_sql_authorized_networks": [
            {
              "name": "anywhere",
              "value": "0.0.0.0/0"
            }
          ],
          "cloud_sql_backup_configuration": {
            "enabled": false,
            "point_in_time_recovery_enabled": false
          },
          "cloud_sql_ip_configuration": {
            "ipv4_enabled": true,
            "require_ssl": false,
            "authorized_networks": [
              {
                "name": "anywhere",
                "value": "0.0.0.0/0"
              }
            ]
          },
          "deletion_protection": false,
          "labels": {},
          "availability_type": "ZONAL",
          "tier": "db-f1-micro",
          "disk_type": "PD_SSD",
          "disk_size": 20,
          "public_access_reasons": [
            "Cloud SQL public IPv4 access is enabled"
          ],
          "public_exposure_reasons": [
            "authorized network `anywhere` allows 0.0.0.0/0"
          ],
          "publicly_accessible": true,
          "storage_encrypted": true,
          "direct_internet_reachable": true,
          "internet_ingress_capable": true,
          "internet_ingress_reasons": [
            "authorized network `anywhere` allows 0.0.0.0/0"
          ]
        }
      },
      {
        "address": "google_storage_bucket.logs",
        "provider": "gcp",
        "resource_type": "google_storage_bucket",
        "name": "logs",
        "category": "data",
        "identifier": "tfstride-logs",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": true,
        "public_exposure": true,
        "data_sensitivity": "sensitive",
        "metadata": {
          "name": "tfstride-logs",
          "bucket": "tfstride-logs",
          "self_link": null,
          "project": null,
          "labels": {},
          "uniform_bucket_level_access": true,
          "public_access_prevention": null,
          "gcs_versioning_enabled": false,
          "gcs_versioning_configuration": {},
          "gcs_default_kms_key_name": null,
          "gcs_encryption_configuration": {},
          "location": "US",
          "storage_class": null,
          "force_destroy": false,
          "customer_managed_encryption": false,
          "storage_encrypted": true,
          "iam_bindings": [
            {
              "role": "roles/storage.objectViewer",
              "members": [
                "allUsers"
              ],
              "source": "google_storage_bucket_iam_member.public_logs_reader"
            }
          ],
          "gcp_resource_policy_source_addresses": [
            "google_storage_bucket_iam_member.public_logs_reader"
          ],
          "public_access_reasons": [
            "google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers"
          ],
          "direct_internet_reachable": true,
          "public_exposure_reasons": [
            "google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers"
          ]
        }
      },
      {
        "address": "google_storage_bucket_iam_member.public_logs_reader",
        "provider": "gcp",
        "resource_type": "google_storage_bucket_iam_member",
        "name": "public_logs_reader",
        "category": "iam",
        "identifier": "google_storage_bucket.logs.name:roles/storage.objectViewer:allUsers",
        "arn": null,
        "vpc_id": null,
        "subnet_ids": [],
        "security_group_ids": [],
        "attached_role_arns": [],
        "network_rules": [],
        "policy_statements": [],
        "public_access_configured": false,
        "public_exposure": false,
        "data_sensitivity": "standard",
        "metadata": {
          "bucket": "google_storage_bucket.logs.name",
          "iam_role": "roles/storage.objectViewer",
          "iam_member": "allUsers",
          "iam_members": [
            "allUsers"
          ],
          "iam_bindings": [
            {
              "role": "roles/storage.objectViewer",
              "members": [
                "allUsers"
              ]
            }
          ],
          "condition": null
        }
      }
    ]
  },
  "trust_boundaries": [
    {
      "identifier": "internet-to-service:internet->google_compute_instance.web",
      "boundary_type": "internet-to-service",
      "source": "internet",
      "target": "google_compute_instance.web",
      "description": "Traffic can cross from the public internet to google_compute_instance.web.",
      "rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
    },
    {
      "identifier": "internet-to-service:internet->google_sql_database_instance.app",
      "boundary_type": "internet-to-service",
      "source": "internet",
      "target": "google_sql_database_instance.app",
      "description": "Traffic can cross from the public internet to google_sql_database_instance.app.",
      "rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
    },
    {
      "identifier": "internet-to-service:internet->google_storage_bucket.logs",
      "boundary_type": "internet-to-service",
      "source": "internet",
      "target": "google_storage_bucket.logs",
      "description": "Traffic can cross from the public internet to google_storage_bucket.logs.",
      "rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
    }
  ],
  "findings": [
    {
      "fingerprint": "sha256:ea244fab8b597f86d6033e9dd1a7a85fcd2582156da247f7cf41dc56ce1996aa",
      "title": "Cloud SQL instance accepts public authorized network access",
      "rule_id": "gcp-cloud-sql-public-authorized-network",
      "category": "Information Disclosure",
      "severity": "high",
      "affected_resources": [
        "google_sql_database_instance.app"
      ],
      "trust_boundary_id": "internet-to-service:internet->google_sql_database_instance.app",
      "rationale": "google_sql_database_instance.app has a public Cloud SQL IPv4 endpoint and an authorized network that allows internet-wide client sources. That weakens the database trust boundary even when database authentication is still required.",
      "recommended_mitigation": "Disable public IPv4 access where possible, use private IP connectivity or the Cloud SQL Auth Proxy, and restrict authorized networks to narrow CIDRs when public client access is required.",
      "evidence": [
        {
          "key": "authorized_networks",
          "values": [
            "anywhere (0.0.0.0/0)"
          ]
        },
        {
          "key": "public_exposure_reasons",
          "values": [
            "authorized network `anywhere` allows 0.0.0.0/0"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 1,
        "blast_radius": 1,
        "final_score": 6,
        "severity": "high",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:dcda21548d88813aa36e2cf734e63769e0d32d5bcc6bb38b1f39ca442702b607",
      "title": "Sensitive GCP resource IAM binding allows broad or external access",
      "rule_id": "gcp-sensitive-resource-iam-external-access",
      "category": "Information Disclosure",
      "severity": "high",
      "affected_resources": [
        "google_secret_manager_secret.api_key",
        "google_secret_manager_secret_iam_member.public_accessor"
      ],
      "trust_boundary_id": null,
      "rationale": "google_secret_manager_secret.api_key grants `roles/secretmanager.secretAccessor` to `allAuthenticatedUsers` through GCP IAM. Public, broad-domain, or foreign-project principals can access sensitive secrets or cryptographic key operations outside the expected project trust boundary.",
      "recommended_mitigation": "Grant Secret Manager and Cloud KMS IAM roles only to specific in-project service accounts or groups, remove public principals, and require explicit cross-project access reviews for partner identities.",
      "evidence": [
        {
          "key": "iam_binding",
          "values": [
            "source=google_secret_manager_secret_iam_member.public_accessor",
            "role=roles/secretmanager.secretAccessor",
            "member=allAuthenticatedUsers"
          ]
        },
        {
          "key": "trust_scope",
          "values": [
            "member is public GCP principal `allAuthenticatedUsers`"
          ]
        },
        {
          "key": "resource_policy_sources",
          "values": [
            "google_secret_manager_secret_iam_member.public_accessor"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 2,
        "data_sensitivity": 2,
        "lateral_movement": 1,
        "blast_radius": 2,
        "final_score": 9,
        "severity": "high",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:732031ebf10c1377662fe780b23c0062f4bd35fca0ff1594e027473c04ad58b3",
      "title": "Cloud SQL automated backups are disabled",
      "rule_id": "gcp-cloud-sql-backup-disabled",
      "category": "Denial of Service",
      "severity": "medium",
      "affected_resources": [
        "google_sql_database_instance.app"
      ],
      "trust_boundary_id": null,
      "rationale": "google_sql_database_instance.app does not have Cloud SQL automated backups enabled. A destructive change, operator error, or data corruption event would have fewer managed recovery points.",
      "recommended_mitigation": "Enable automated backups for Cloud SQL instances, configure retention appropriate to the workload, and enable point-in-time recovery where supported.",
      "evidence": [
        {
          "key": "backup_posture",
          "values": [
            "backup_configuration.enabled is false",
            "point_in_time_recovery_enabled is false",
            "engine is POSTGRES_15"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 0,
        "blast_radius": 1,
        "final_score": 3,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:45d6257e521b0a506b22d24effc4ea056c44258268d8daf7718eb88fa7d08ee0",
      "title": "Cloud SQL deletion protection is disabled",
      "rule_id": "gcp-cloud-sql-deletion-protection-disabled",
      "category": "Denial of Service",
      "severity": "medium",
      "affected_resources": [
        "google_sql_database_instance.app"
      ],
      "trust_boundary_id": null,
      "rationale": "google_sql_database_instance.app has Cloud SQL deletion protection disabled. Accidental or unauthorized infrastructure changes could destroy the managed database instance without this provider-level guardrail.",
      "recommended_mitigation": "Enable Cloud SQL deletion protection for persistent environments and require explicit review before disabling it during planned database retirement.",
      "evidence": [
        {
          "key": "lifecycle_posture",
          "values": [
            "deletion_protection is false"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 0,
        "blast_radius": 1,
        "final_score": 3,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:6d18157ff1cecde179c5827e348e0ea19bcb17e4fb3d3ecf1a2394d940215cb6",
      "title": "Cloud SQL public IPv4 is enabled without private network access",
      "rule_id": "gcp-cloud-sql-public-ip-without-private-network",
      "category": "Information Disclosure",
      "severity": "medium",
      "affected_resources": [
        "google_sql_database_instance.app"
      ],
      "trust_boundary_id": "internet-to-service:internet->google_sql_database_instance.app",
      "rationale": "google_sql_database_instance.app has Cloud SQL public IPv4 enabled without a private network attachment. That keeps database client access on a public endpoint instead of an internal VPC path.",
      "recommended_mitigation": "Disable public IPv4 where possible, attach the instance to a private network, and route clients through private IP, the Cloud SQL Auth Proxy, or tightly controlled connectivity paths.",
      "evidence": [
        {
          "key": "network_posture",
          "values": [
            "ipv4_enabled is true",
            "private_network is unset",
            "authorized_networks configured: 1"
          ]
        },
        {
          "key": "public_access_reasons",
          "values": [
            "Cloud SQL public IPv4 access is enabled"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 1,
        "blast_radius": 0,
        "final_score": 5,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:2f9a3d374af8b51e6e3aa80ad9da2145f6f078927c72b74c19ab52f0d3266d8c",
      "title": "Cloud SQL public client access does not require SSL",
      "rule_id": "gcp-cloud-sql-ssl-not-required",
      "category": "Information Disclosure",
      "severity": "medium",
      "affected_resources": [
        "google_sql_database_instance.app"
      ],
      "trust_boundary_id": "internet-to-service:internet->google_sql_database_instance.app",
      "rationale": "google_sql_database_instance.app allows Cloud SQL public IPv4 client access without requiring encrypted client connections. Credentials and database traffic should not depend on client-side optional TLS behavior.",
      "recommended_mitigation": "Require encrypted Cloud SQL client connections with `require_ssl` or an enforcing `ssl_mode`, and prefer private IP or the Cloud SQL Auth Proxy for application connectivity.",
      "evidence": [
        {
          "key": "ssl_posture",
          "values": [
            "require_ssl is false",
            "ssl_mode is unset",
            "ipv4_enabled is true"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 1,
        "blast_radius": 0,
        "final_score": 5,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:7f9b36a6593edd523470255de4c3c4dd97f9b9004e2fe64bc257be0bb37d1453",
      "title": "GCS bucket does not enforce Public Access Prevention",
      "rule_id": "gcp-gcs-public-access-prevention-not-enforced",
      "category": "Information Disclosure",
      "severity": "medium",
      "affected_resources": [
        "google_storage_bucket.logs"
      ],
      "trust_boundary_id": "internet-to-service:internet->google_storage_bucket.logs",
      "rationale": "google_storage_bucket.logs does not enforce GCS Public Access Prevention. Public principals can still be introduced through bucket IAM unless an organization-level policy blocks them.",
      "recommended_mitigation": "Set GCS Public Access Prevention to `enforced` on sensitive buckets and rely on explicit non-public identities or signed access patterns when objects must be shared.",
      "evidence": [
        {
          "key": "access_control_posture",
          "values": [
            "public_access_prevention is unset"
          ]
        },
        {
          "key": "public_exposure_reasons",
          "values": [
            "google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 0,
        "blast_radius": 1,
        "final_score": 5,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:c40cdeca64a1e9283e86c379c3ef9e8a37ce2983381579cf7ab47eab05f62be9",
      "title": "GCS bucket is publicly accessible",
      "rule_id": "gcp-gcs-public-access",
      "category": "Information Disclosure",
      "severity": "medium",
      "affected_resources": [
        "google_storage_bucket.logs"
      ],
      "trust_boundary_id": "internet-to-service:internet->google_storage_bucket.logs",
      "rationale": "google_storage_bucket.logs is publicly reachable through GCS IAM grants. Public bucket access is a common source of unintended object disclosure.",
      "recommended_mitigation": "Remove `allUsers` and `allAuthenticatedUsers` from bucket-level IAM grants, enforce GCS Public Access Prevention, and use signed URLs, CDN origins, or narrow identities when objects must be distributed.",
      "evidence": [
        {
          "key": "public_exposure_reasons",
          "values": [
            "google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 0,
        "blast_radius": 1,
        "final_score": 5,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:90b26f239387e86c12b711ddfccfd9c03f230b8db90b6d4f559178f63d5412d2",
      "title": "GCS sensitive bucket does not use customer-managed encryption",
      "rule_id": "gcp-gcs-customer-managed-encryption-missing",
      "category": "Information Disclosure",
      "severity": "medium",
      "affected_resources": [
        "google_storage_bucket.logs"
      ],
      "trust_boundary_id": null,
      "rationale": "google_storage_bucket.logs relies on default GCS encryption rather than a customer-managed KMS key. Sensitive buckets lose key ownership, rotation, and separation-of-duties controls that a CMEK can provide.",
      "recommended_mitigation": "Configure a Cloud KMS customer-managed key for sensitive GCS buckets, assign the GCS service agent only the key roles it needs, and manage key rotation separately from bucket IAM.",
      "evidence": [
        {
          "key": "encryption_posture",
          "values": [
            "default_kms_key_name is unset",
            "customer_managed_encryption is false"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 0,
        "blast_radius": 1,
        "final_score": 3,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:b581f92581ebad73170a679021871c1cdbef137bf69e170c5f0c4085af7665bc",
      "title": "GCS sensitive bucket versioning is disabled",
      "rule_id": "gcp-gcs-versioning-disabled",
      "category": "Denial of Service",
      "severity": "medium",
      "affected_resources": [
        "google_storage_bucket.logs"
      ],
      "trust_boundary_id": null,
      "rationale": "google_storage_bucket.logs stores sensitive GCS data without bucket versioning. Accidental overwrites, deletes, or destructive changes have fewer object-level recovery options.",
      "recommended_mitigation": "Enable bucket versioning for sensitive GCS buckets and pair it with lifecycle retention rules that match recovery objectives and storage cost constraints.",
      "evidence": [
        {
          "key": "data_protection_posture",
          "values": [
            "versioning.enabled is false",
            "data_sensitivity is sensitive"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 0,
        "data_sensitivity": 2,
        "lateral_movement": 0,
        "blast_radius": 1,
        "final_score": 3,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:2baea47d0ebc1d51fb6d07282f63d7a6b6594aa953b0c00989a28723377c6771",
      "title": "Internet-exposed GCP compute instance permits broad ingress",
      "rule_id": "gcp-public-compute-broad-ingress",
      "category": "Spoofing",
      "severity": "medium",
      "affected_resources": [
        "google_compute_instance.web",
        "google_compute_firewall.public_ssh"
      ],
      "trust_boundary_id": "internet-to-service:internet->google_compute_instance.web",
      "rationale": "google_compute_instance.web has an external access config and matching GCP firewall rules allow administrative access or all ports from the public internet. That broad ingress raises the chance of unauthenticated probing and credential attacks.",
      "recommended_mitigation": "Restrict GCP firewall source ranges and exposed ports, remove external IP access where possible, and use Identity-Aware Proxy, VPN, or a controlled bastion for administration.",
      "evidence": [
        {
          "key": "firewall_rules",
          "values": [
            "google_compute_firewall.public_ssh ingress tcp 22 from 0.0.0.0/0"
          ]
        },
        {
          "key": "network_tags",
          "values": [
            "web"
          ]
        },
        {
          "key": "public_exposure_reasons",
          "values": [
            "compute instance has an external access config and matching firewall rules allow internet ingress"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 2,
        "privilege_breadth": 0,
        "data_sensitivity": 0,
        "lateral_movement": 1,
        "blast_radius": 1,
        "final_score": 4,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:408c558dd93f32bfca75eea24d9787a2feaab97ff26e4a869e7984cda37b5bd3",
      "title": "Sensitive GCP resource IAM binding allows broad or external access",
      "rule_id": "gcp-sensitive-resource-iam-external-access",
      "category": "Information Disclosure",
      "severity": "medium",
      "affected_resources": [
        "google_kms_crypto_key.customer",
        "google_kms_crypto_key_iam_member.partner_decrypter"
      ],
      "trust_boundary_id": null,
      "rationale": "google_kms_crypto_key.customer grants `roles/cloudkms.cryptoKeyDecrypter` to `serviceAccount:decryptor@partner-project.iam.gserviceaccount.com` through GCP IAM. Public, broad-domain, or foreign-project principals can access sensitive secrets or cryptographic key operations outside the expected project trust boundary.",
      "recommended_mitigation": "Grant Secret Manager and Cloud KMS IAM roles only to specific in-project service accounts or groups, remove public principals, and require explicit cross-project access reviews for partner identities.",
      "evidence": [
        {
          "key": "iam_binding",
          "values": [
            "source=google_kms_crypto_key_iam_member.partner_decrypter",
            "role=roles/cloudkms.cryptoKeyDecrypter",
            "member=serviceAccount:decryptor@partner-project.iam.gserviceaccount.com"
          ]
        },
        {
          "key": "trust_scope",
          "values": [
            "service account belongs to project `partner-project`, outside resource project `tfstride-demo`"
          ]
        },
        {
          "key": "resource_policy_sources",
          "values": [
            "google_kms_crypto_key_iam_member.partner_decrypter"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 1,
        "data_sensitivity": 2,
        "lateral_movement": 1,
        "blast_radius": 1,
        "final_score": 5,
        "severity": "medium",
        "computed_severity": null
      }
    }
  ],
  "suppressed_findings": [],
  "baselined_findings": [],
  "observations": [],
  "limitations": [
    "GCP support currently provides initial inventory normalization, internet-to-service, route/NAT posture, and workload-to-sensitive-data trust-boundary detection, with limited GCP STRIDE rule coverage for compute, GCS posture, Cloud SQL posture, Secret Manager, Cloud KMS, and project IAM only; GCP control coverage is not implemented yet.",
    "The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity."
  ]
}
Markdown report
# GCP Inventory Demo

- Analyzed file: `sample_gcp_plan.json`
- Provider: `gcp`
- Normalized resources: `14`
- Unsupported resources: `0`

## Summary

This run identified **3 trust boundaries** and **12 findings** across **14 normalized resources**.

- High severity findings: `2`
- Medium severity findings: `10`
- Low severity findings: `0`

## Analysis Coverage

- Terraform resources seen: `14`
- Provider resources considered: `14`
- Normalized resources: `14`
- Unsupported resources: `0`
- Registered rules: `29`
- Enabled rules: `29`
- Disabled rules: `0`
- Severity overrides: `0`
- Unresolved in-plan references: `0`
- Findings by rule:
  - `gcp-sensitive-resource-iam-external-access`: `2`
  - `gcp-cloud-sql-public-authorized-network`: `1`
  - `gcp-cloud-sql-backup-disabled`: `1`
  - `gcp-cloud-sql-public-ip-without-private-network`: `1`
  - `gcp-cloud-sql-ssl-not-required`: `1`
  - `gcp-cloud-sql-deletion-protection-disabled`: `1`
  - `gcp-gcs-public-access`: `1`
  - `gcp-gcs-public-access-prevention-not-enforced`: `1`
  - `gcp-gcs-versioning-disabled`: `1`
  - `gcp-gcs-customer-managed-encryption-missing`: `1`
  - `gcp-public-compute-broad-ingress`: `1`

## Discovered Trust Boundaries

### `internet-to-service`

- Source: `internet`
- Target: `google_compute_instance.web`
- Description: Traffic can cross from the public internet to google_compute_instance.web.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.

### `internet-to-service`

- Source: `internet`
- Target: `google_sql_database_instance.app`
- Description: Traffic can cross from the public internet to google_sql_database_instance.app.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.

### `internet-to-service`

- Source: `internet`
- Target: `google_storage_bucket.logs`
- Description: Traffic can cross from the public internet to google_storage_bucket.logs.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.

## Findings

### High

#### Cloud SQL instance accepts public authorized network access

- STRIDE category: Information Disclosure
- Affected resources: `google_sql_database_instance.app`
- Trust boundary: `internet-to-service:internet->google_sql_database_instance.app`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +1, blast_radius +1, final_score 6 => high
- Rationale: google_sql_database_instance.app has a public Cloud SQL IPv4 endpoint and an authorized network that allows internet-wide client sources. That weakens the database trust boundary even when database authentication is still required.
- Recommended mitigation: Disable public IPv4 access where possible, use private IP connectivity or the Cloud SQL Auth Proxy, and restrict authorized networks to narrow CIDRs when public client access is required.
- Evidence:
  - authorized networks: anywhere (0.0.0.0/0)
  - public exposure reasons: authorized network `anywhere` allows 0.0.0.0/0

#### Sensitive GCP resource IAM binding allows broad or external access

- STRIDE category: Information Disclosure
- Affected resources: `google_secret_manager_secret.api_key`, `google_secret_manager_secret_iam_member.public_accessor`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +2, data_sensitivity +2, lateral_movement +1, blast_radius +2, final_score 9 => high
- Rationale: google_secret_manager_secret.api_key grants `roles/secretmanager.secretAccessor` to `allAuthenticatedUsers` through GCP IAM. Public, broad-domain, or foreign-project principals can access sensitive secrets or cryptographic key operations outside the expected project trust boundary.
- Recommended mitigation: Grant Secret Manager and Cloud KMS IAM roles only to specific in-project service accounts or groups, remove public principals, and require explicit cross-project access reviews for partner identities.
- Evidence:
  - iam binding: source=google_secret_manager_secret_iam_member.public_accessor; role=roles/secretmanager.secretAccessor; member=allAuthenticatedUsers
  - trust scope: member is public GCP principal `allAuthenticatedUsers`
  - resource policy sources: google_secret_manager_secret_iam_member.public_accessor

### Medium

#### Cloud SQL automated backups are disabled

- STRIDE category: Denial of Service
- Affected resources: `google_sql_database_instance.app`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 3 => medium
- Rationale: google_sql_database_instance.app does not have Cloud SQL automated backups enabled. A destructive change, operator error, or data corruption event would have fewer managed recovery points.
- Recommended mitigation: Enable automated backups for Cloud SQL instances, configure retention appropriate to the workload, and enable point-in-time recovery where supported.
- Evidence:
  - backup posture: backup_configuration.enabled is false; point_in_time_recovery_enabled is false; engine is POSTGRES_15

#### Cloud SQL deletion protection is disabled

- STRIDE category: Denial of Service
- Affected resources: `google_sql_database_instance.app`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 3 => medium
- Rationale: google_sql_database_instance.app has Cloud SQL deletion protection disabled. Accidental or unauthorized infrastructure changes could destroy the managed database instance without this provider-level guardrail.
- Recommended mitigation: Enable Cloud SQL deletion protection for persistent environments and require explicit review before disabling it during planned database retirement.
- Evidence:
  - lifecycle posture: deletion_protection is false

#### Cloud SQL public IPv4 is enabled without private network access

- STRIDE category: Information Disclosure
- Affected resources: `google_sql_database_instance.app`
- Trust boundary: `internet-to-service:internet->google_sql_database_instance.app`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +1, blast_radius +0, final_score 5 => medium
- Rationale: google_sql_database_instance.app has Cloud SQL public IPv4 enabled without a private network attachment. That keeps database client access on a public endpoint instead of an internal VPC path.
- Recommended mitigation: Disable public IPv4 where possible, attach the instance to a private network, and route clients through private IP, the Cloud SQL Auth Proxy, or tightly controlled connectivity paths.
- Evidence:
  - network posture: ipv4_enabled is true; private_network is unset; authorized_networks configured: 1
  - public access reasons: Cloud SQL public IPv4 access is enabled

#### Cloud SQL public client access does not require SSL

- STRIDE category: Information Disclosure
- Affected resources: `google_sql_database_instance.app`
- Trust boundary: `internet-to-service:internet->google_sql_database_instance.app`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +1, blast_radius +0, final_score 5 => medium
- Rationale: google_sql_database_instance.app allows Cloud SQL public IPv4 client access without requiring encrypted client connections. Credentials and database traffic should not depend on client-side optional TLS behavior.
- Recommended mitigation: Require encrypted Cloud SQL client connections with `require_ssl` or an enforcing `ssl_mode`, and prefer private IP or the Cloud SQL Auth Proxy for application connectivity.
- Evidence:
  - ssl posture: require_ssl is false; ssl_mode is unset; ipv4_enabled is true

#### GCS bucket does not enforce Public Access Prevention

- STRIDE category: Information Disclosure
- Affected resources: `google_storage_bucket.logs`
- Trust boundary: `internet-to-service:internet->google_storage_bucket.logs`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: google_storage_bucket.logs does not enforce GCS Public Access Prevention. Public principals can still be introduced through bucket IAM unless an organization-level policy blocks them.
- Recommended mitigation: Set GCS Public Access Prevention to `enforced` on sensitive buckets and rely on explicit non-public identities or signed access patterns when objects must be shared.
- Evidence:
  - access control posture: public_access_prevention is unset
  - public exposure reasons: google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers

#### GCS bucket is publicly accessible

- STRIDE category: Information Disclosure
- Affected resources: `google_storage_bucket.logs`
- Trust boundary: `internet-to-service:internet->google_storage_bucket.logs`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: google_storage_bucket.logs is publicly reachable through GCS IAM grants. Public bucket access is a common source of unintended object disclosure.
- Recommended mitigation: Remove `allUsers` and `allAuthenticatedUsers` from bucket-level IAM grants, enforce GCS Public Access Prevention, and use signed URLs, CDN origins, or narrow identities when objects must be distributed.
- Evidence:
  - public exposure reasons: google_storage_bucket_iam_member.public_logs_reader grants roles/storage.objectViewer to allUsers

#### GCS sensitive bucket does not use customer-managed encryption

- STRIDE category: Information Disclosure
- Affected resources: `google_storage_bucket.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 3 => medium
- Rationale: google_storage_bucket.logs relies on default GCS encryption rather than a customer-managed KMS key. Sensitive buckets lose key ownership, rotation, and separation-of-duties controls that a CMEK can provide.
- Recommended mitigation: Configure a Cloud KMS customer-managed key for sensitive GCS buckets, assign the GCS service agent only the key roles it needs, and manage key rotation separately from bucket IAM.
- Evidence:
  - encryption posture: default_kms_key_name is unset; customer_managed_encryption is false

#### GCS sensitive bucket versioning is disabled

- STRIDE category: Denial of Service
- Affected resources: `google_storage_bucket.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 3 => medium
- Rationale: google_storage_bucket.logs stores sensitive GCS data without bucket versioning. Accidental overwrites, deletes, or destructive changes have fewer object-level recovery options.
- Recommended mitigation: Enable bucket versioning for sensitive GCS buckets and pair it with lifecycle retention rules that match recovery objectives and storage cost constraints.
- Evidence:
  - data protection posture: versioning.enabled is false; data_sensitivity is sensitive

#### Internet-exposed GCP compute instance permits broad ingress

- STRIDE category: Spoofing
- Affected resources: `google_compute_instance.web`, `google_compute_firewall.public_ssh`
- Trust boundary: `internet-to-service:internet->google_compute_instance.web`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +0, lateral_movement +1, blast_radius +1, final_score 4 => medium
- Rationale: google_compute_instance.web has an external access config and matching GCP firewall rules allow administrative access or all ports from the public internet. That broad ingress raises the chance of unauthenticated probing and credential attacks.
- Recommended mitigation: Restrict GCP firewall source ranges and exposed ports, remove external IP access where possible, and use Identity-Aware Proxy, VPN, or a controlled bastion for administration.
- Evidence:
  - firewall rules: google_compute_firewall.public_ssh ingress tcp 22 from 0.0.0.0/0
  - network tags: web
  - public exposure reasons: compute instance has an external access config and matching firewall rules allow internet ingress

#### Sensitive GCP resource IAM binding allows broad or external access

- STRIDE category: Information Disclosure
- Affected resources: `google_kms_crypto_key.customer`, `google_kms_crypto_key_iam_member.partner_decrypter`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +1, data_sensitivity +2, lateral_movement +1, blast_radius +1, final_score 5 => medium
- Rationale: google_kms_crypto_key.customer grants `roles/cloudkms.cryptoKeyDecrypter` to `serviceAccount:decryptor@partner-project.iam.gserviceaccount.com` through GCP IAM. Public, broad-domain, or foreign-project principals can access sensitive secrets or cryptographic key operations outside the expected project trust boundary.
- Recommended mitigation: Grant Secret Manager and Cloud KMS IAM roles only to specific in-project service accounts or groups, remove public principals, and require explicit cross-project access reviews for partner identities.
- Evidence:
  - iam binding: source=google_kms_crypto_key_iam_member.partner_decrypter; role=roles/cloudkms.cryptoKeyDecrypter; member=serviceAccount:decryptor@partner-project.iam.gserviceaccount.com
  - trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`
  - resource policy sources: google_kms_crypto_key_iam_member.partner_decrypter

### Low

No findings in this severity band.

## Limitations / Unsupported Resources

- GCP support currently provides initial inventory normalization, internet-to-service, route/NAT posture, and workload-to-sensitive-data trust-boundary detection, with limited GCP STRIDE rule coverage for compute, GCS posture, Cloud SQL posture, Secret Manager, Cloud KMS, and project IAM only; GCP control coverage is not implemented yet.
- The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity.

Limits

Unsupported or intentionally scoped areas

  • GCP support currently provides initial inventory normalization, internet-to-service, route/NAT posture, and workload-to-sensitive-data trust-boundary detection, with limited GCP STRIDE rule coverage for compute, GCS posture, Cloud SQL posture, Secret Manager, Cloud KMS, and project IAM only; GCP control coverage is not implemented yet.
  • The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity.