Built-in scenario

gcp/sample_gcp_cross_project_iam_plan.json

GCP Cross-Project IAM Demo

Analyzed sample_gcp_cross_project_iam_plan.json with 8 normalized resources and 0 trust boundaries.

Analyze another plan

Active findings

6

Trust boundaries

0

Resources

8

Observations

0
High 3
Medium 3
Low 0

Analysis coverage

Audit trail for this run

Terraform resources 8
Unsupported 0
Enabled rules 78
Unresolved refs 0

Resource coverage

Provider resources considered
8
Normalized resources
8

No unsupported GCP resource types were encountered.

Rule coverage

Registered rules
78
Disabled rules
0
  • gcp-sensitive-resource-iam-external-access2
  • gcp-subnetwork-flow-logs-not-configured1
  • gcp-project-iam-privileged-role1
  • gcp-inherited-iam-sensitive-resource-access1
  • gcp-inherited-iam-blast-radius1

Findings

Severity bands

High

3

GCP project IAM binding grants a high-privilege role

gcp-project-iam-privileged-role

google_project_iam_member.partner_editor grants the high-impact GCP role `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope. That role enables broad write access across most project services and can materially expand control-plane blast radius if the principal is compromised or mis-scoped.

Category
Elevation of Privilege
Boundary
not-applicable
Resources
google_project_iam_member.partner_editor
Evidence
  • iam binding: member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com; role=roles/editor
  • role risk: broad write access across most project services

Inherited GCP IAM grant expands descendant blast radius

gcp-inherited-iam-blast-radius

google_project_iam_member.partner_editor grants `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope `tfstride-demo`, and that inherited grant applies to 5 concrete descendant resource(s). A high-level IAM grant with broad, external, or high-impact access increases control-plane blast radius because compromise or misuse can affect resources below the inherited scope.

Category
Elevation of Privilege
Boundary
not-applicable
Resources
google_project_iam_member.partner_editor, google_compute_network.main, google_compute_subnetwork.app, google_kms_crypto_key.customer, google_secret_manager_secret.api_key, google_service_account.web
Evidence
  • iam binding: source=google_project_iam_member.partner_editor; scope=project:tfstride-demo; member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com; role=roles/editor
  • role risk: broad write access across most project services
  • trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`
  • descendant scope: scope=project:tfstride-demo; descendant_count=5; resource_type_count=5; projects=tfstride-demo
  • descendant resource types: google_compute_network: 1; google_compute_subnetwork: 1; google_kms_crypto_key: 1; google_secret_manager_secret: 1; google_service_account: 1
  • descendant resources: google_compute_network.main; google_compute_subnetwork.app; google_kms_crypto_key.customer; google_secret_manager_secret.api_key; google_service_account.web

Inherited GCP IAM grant reaches sensitive resources

gcp-inherited-iam-sensitive-resource-access

google_project_iam_member.partner_editor grants `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope `tfstride-demo`, and that inherited grant reaches 2 sensitive GCP descendant resource(s). Project, folder, and organization IAM applies below the grant scope, so a single ancestor binding can expose data resources beyond their local IAM boundary.

Category
Information Disclosure
Boundary
not-applicable
Resources
google_project_iam_member.partner_editor, google_kms_crypto_key.customer, google_secret_manager_secret.api_key
Evidence
  • iam binding: source=google_project_iam_member.partner_editor; scope=project:tfstride-demo; member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com; role=roles/editor
  • sensitive descendants: resource=google_kms_crypto_key.customer; type=google_kms_crypto_key; risk=Cloud KMS cryptographic key access through roles/editor; resource=google_secret_manager_secret.api_key; type=google_secret_manager_secret; risk=Secret Manager secret access through roles/editor
  • trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`

Medium

3

GCP subnetwork Flow Logs are not configured

gcp-subnetwork-flow-logs-not-configured

google_compute_subnetwork.app does not configure VPC Flow Logs in this Terraform plan. Without subnetwork flow telemetry, network investigation, lateral-movement review, and egress analysis can lack packet-flow evidence for workloads attached to this subnet.

Category
Repudiation
Boundary
not-applicable
Resources
google_compute_subnetwork.app
Evidence
  • subnetwork flow log posture: address=google_compute_subnetwork.app; type=google_compute_subnetwork; name=app; identifier=tfstride-app; flow_log_state=not_configured; network=google_compute_network.main.id; project=tfstride-demo

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 `serviceAccount:reader@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_secret_manager_secret.api_key, google_secret_manager_secret_iam_member.partner_accessor
Evidence
  • iam binding: source=google_secret_manager_secret_iam_member.partner_accessor; role=roles/secretmanager.secretAccessor; member=serviceAccount:reader@partner-project.iam.gserviceaccount.com
  • trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`
  • resource policy sources: google_secret_manager_secret_iam_member.partner_accessor

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

No trust boundaries were discovered.

Raw outputs

Stable contract and markdown

JSON report
{
  "kind": "tfstride-report",
  "version": "1.1",
  "tool": {
    "name": "tfstride",
    "version": "0.4.23"
  },
  "title": "GCP Cross-Project IAM Demo",
  "analyzed_file": "sample_gcp_cross_project_iam_plan.json",
  "analyzed_path": "sample_gcp_cross_project_iam_plan.json",
  "summary": {
    "normalized_resources": 8,
    "unsupported_resources": 0,
    "trust_boundaries": 0,
    "active_findings": 6,
    "total_findings": 6,
    "suppressed_findings": 0,
    "baselined_findings": 0,
    "severity_counts": {
      "high": 3,
      "medium": 3,
      "low": 0
    }
  },
  "filtering": {
    "total_findings": 6,
    "active_findings": 6,
    "suppressed_findings": 0,
    "baselined_findings": 0,
    "suppressions_path": null,
    "baseline_path": null
  },
  "analysis_coverage": {
    "resources": {
      "total_resources": 8,
      "provider_resources": 8,
      "normalized_resources": 8,
      "unsupported_resources": 0,
      "unsupported_resource_types": {}
    },
    "rules": {
      "registered_rule_count": 78,
      "enabled_rules": [
        "gcp-sensitive-resource-iam-external-access",
        "gcp-pubsub-public-access",
        "gcp-pubsub-topic-customer-managed-encryption-missing",
        "gcp-pubsub-message-retention-insufficient",
        "gcp-pubsub-subscription-dead-letter-policy-missing",
        "gcp-bigquery-public-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-cloud-sql-zonal-availability",
        "gcp-cloud-sql-query-insights-disabled",
        "gcp-cloud-sql-connector-enforcement-not-required",
        "gcp-cloud-sql-private-connectivity-not-modeled",
        "gcp-private-workload-private-google-access-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-gcs-retention-policy-insufficient",
        "gcp-artifact-registry-docker-tags-mutable",
        "gcp-artifact-registry-customer-managed-encryption-missing",
        "gcp-artifact-registry-vulnerability-scanning-disabled",
        "gcp-secret-manager-customer-managed-encryption-missing",
        "gcp-secret-manager-lifecycle-posture-incomplete",
        "gcp-kms-key-rotation-not-configured-or-too-long",
        "gcp-kms-key-destroy-scheduled-duration-too-short",
        "gcp-public-compute-broad-ingress",
        "gcp-public-load-balanced-workload",
        "gcp-load-balancer-http-public-proxy",
        "gcp-load-balancer-ssl-policy-missing-or-weak",
        "gcp-public-load-balancer-cloud-armor-missing",
        "gcp-compute-os-login-disabled",
        "gcp-gke-public-control-plane",
        "gcp-gke-broad-authorized-networks",
        "gcp-gke-workload-identity-disabled",
        "gcp-gke-legacy-metadata-endpoints-enabled",
        "gcp-gke-broad-node-service-account",
        "gcp-gke-control-plane-logging-incomplete",
        "gcp-scc-asset-discovery-disabled",
        "gcp-logging-exclusion-drops-audit-security-logs",
        "gcp-logging-sink-audit-export-incomplete",
        "gcp-central-audit-sink-not-modeled",
        "gcp-subnetwork-flow-logs-not-configured",
        "gcp-subnetwork-flow-log-capture-incomplete",
        "gcp-gke-network-policy-disabled",
        "gcp-gke-secrets-encryption-not-configured",
        "gcp-gke-legacy-abac-enabled-or-unknown",
        "gcp-gke-client-certificate-auth-enabled-or-unknown",
        "gcp-gke-shielded-nodes-disabled-or-unknown",
        "gcp-gke-binary-authorization-not-enabled",
        "gcp-cloud-run-public-invoker",
        "gcp-cloud-functions-public-invoker",
        "gcp-cloud-run-image-not-digest-pinned",
        "gcp-cloud-run-artifact-registry-mutable-tag",
        "gcp-cloud-run-can-modify-image-repository",
        "gcp-cloud-run-sensitive-environment-value-inline",
        "gcp-cloud-run-secret-access-blast-radius",
        "gcp-public-cloud-run-gcs-mutation-access",
        "gcp-public-cloud-run-pubsub-mutation-access",
        "gcp-service-account-iam-broad-principal",
        "gcp-service-account-iam-privileged-role",
        "gcp-service-account-key-hygiene",
        "gcp-service-account-key-effective-access",
        "gcp-workload-identity-pool-wide-impersonation",
        "gcp-workload-identity-provider-unconditioned-broad-trust",
        "gcp-workload-identity-privileged-service-account-access",
        "gcp-org-folder-iam-broad-principal",
        "gcp-org-folder-iam-privileged-role",
        "gcp-project-iam-broad-principal",
        "gcp-project-iam-privileged-role",
        "gcp-iam-privileged-assignment",
        "gcp-inherited-iam-sensitive-resource-access",
        "gcp-inherited-iam-blast-radius",
        "gcp-public-workload-sensitive-data-access"
      ],
      "disabled_rules": [],
      "severity_overrides": {},
      "finding_counts_by_rule": {
        "gcp-sensitive-resource-iam-external-access": 2,
        "gcp-pubsub-public-access": 0,
        "gcp-pubsub-topic-customer-managed-encryption-missing": 0,
        "gcp-pubsub-message-retention-insufficient": 0,
        "gcp-pubsub-subscription-dead-letter-policy-missing": 0,
        "gcp-bigquery-public-access": 0,
        "gcp-cloud-sql-public-authorized-network": 0,
        "gcp-cloud-sql-backup-disabled": 0,
        "gcp-cloud-sql-public-ip-without-private-network": 0,
        "gcp-cloud-sql-ssl-not-required": 0,
        "gcp-cloud-sql-point-in-time-recovery-disabled": 0,
        "gcp-cloud-sql-deletion-protection-disabled": 0,
        "gcp-cloud-sql-zonal-availability": 0,
        "gcp-cloud-sql-query-insights-disabled": 0,
        "gcp-cloud-sql-connector-enforcement-not-required": 0,
        "gcp-cloud-sql-private-connectivity-not-modeled": 0,
        "gcp-private-workload-private-google-access-disabled": 0,
        "gcp-gcs-public-access": 0,
        "gcp-gcs-uniform-bucket-level-access-disabled": 0,
        "gcp-gcs-public-access-prevention-not-enforced": 0,
        "gcp-gcs-versioning-disabled": 0,
        "gcp-gcs-customer-managed-encryption-missing": 0,
        "gcp-gcs-retention-policy-insufficient": 0,
        "gcp-artifact-registry-docker-tags-mutable": 0,
        "gcp-artifact-registry-customer-managed-encryption-missing": 0,
        "gcp-artifact-registry-vulnerability-scanning-disabled": 0,
        "gcp-secret-manager-customer-managed-encryption-missing": 0,
        "gcp-secret-manager-lifecycle-posture-incomplete": 0,
        "gcp-kms-key-rotation-not-configured-or-too-long": 0,
        "gcp-kms-key-destroy-scheduled-duration-too-short": 0,
        "gcp-public-compute-broad-ingress": 0,
        "gcp-public-load-balanced-workload": 0,
        "gcp-load-balancer-http-public-proxy": 0,
        "gcp-load-balancer-ssl-policy-missing-or-weak": 0,
        "gcp-public-load-balancer-cloud-armor-missing": 0,
        "gcp-compute-os-login-disabled": 0,
        "gcp-gke-public-control-plane": 0,
        "gcp-gke-broad-authorized-networks": 0,
        "gcp-gke-workload-identity-disabled": 0,
        "gcp-gke-legacy-metadata-endpoints-enabled": 0,
        "gcp-gke-broad-node-service-account": 0,
        "gcp-gke-control-plane-logging-incomplete": 0,
        "gcp-scc-asset-discovery-disabled": 0,
        "gcp-logging-exclusion-drops-audit-security-logs": 0,
        "gcp-logging-sink-audit-export-incomplete": 0,
        "gcp-central-audit-sink-not-modeled": 0,
        "gcp-subnetwork-flow-logs-not-configured": 1,
        "gcp-subnetwork-flow-log-capture-incomplete": 0,
        "gcp-gke-network-policy-disabled": 0,
        "gcp-gke-secrets-encryption-not-configured": 0,
        "gcp-gke-legacy-abac-enabled-or-unknown": 0,
        "gcp-gke-client-certificate-auth-enabled-or-unknown": 0,
        "gcp-gke-shielded-nodes-disabled-or-unknown": 0,
        "gcp-gke-binary-authorization-not-enabled": 0,
        "gcp-cloud-run-public-invoker": 0,
        "gcp-cloud-functions-public-invoker": 0,
        "gcp-cloud-run-image-not-digest-pinned": 0,
        "gcp-cloud-run-artifact-registry-mutable-tag": 0,
        "gcp-cloud-run-can-modify-image-repository": 0,
        "gcp-cloud-run-sensitive-environment-value-inline": 0,
        "gcp-cloud-run-secret-access-blast-radius": 0,
        "gcp-public-cloud-run-gcs-mutation-access": 0,
        "gcp-public-cloud-run-pubsub-mutation-access": 0,
        "gcp-service-account-iam-broad-principal": 0,
        "gcp-service-account-iam-privileged-role": 0,
        "gcp-service-account-key-hygiene": 0,
        "gcp-service-account-key-effective-access": 0,
        "gcp-workload-identity-pool-wide-impersonation": 0,
        "gcp-workload-identity-provider-unconditioned-broad-trust": 0,
        "gcp-workload-identity-privileged-service-account-access": 0,
        "gcp-org-folder-iam-broad-principal": 0,
        "gcp-org-folder-iam-privileged-role": 0,
        "gcp-project-iam-broad-principal": 0,
        "gcp-project-iam-privileged-role": 1,
        "gcp-iam-privileged-assignment": 0,
        "gcp-inherited-iam-sensitive-resource-access": 1,
        "gcp-inherited-iam-blast-radius": 1,
        "gcp-public-workload-sensitive-data-access": 0
      }
    },
    "references": {
      "unresolved_reference_count": 0,
      "unresolved_references": []
    }
  },
  "inventory": {
    "provider": "gcp",
    "unsupported_resources": [],
    "metadata": {
      "supported_resource_types": [
        "google_artifact_registry_repository",
        "google_artifact_registry_repository_iam_binding",
        "google_artifact_registry_repository_iam_member",
        "google_artifact_registry_repository_iam_policy",
        "google_bigquery_dataset",
        "google_bigquery_dataset_iam_binding",
        "google_bigquery_dataset_iam_member",
        "google_bigquery_dataset_iam_policy",
        "google_bigquery_table",
        "google_bigquery_table_iam_binding",
        "google_bigquery_table_iam_member",
        "google_bigquery_table_iam_policy",
        "google_cloud_run_service",
        "google_cloud_run_service_iam_binding",
        "google_cloud_run_service_iam_member",
        "google_cloud_run_service_iam_policy",
        "google_cloud_run_v2_service",
        "google_cloud_run_v2_service_iam_binding",
        "google_cloud_run_v2_service_iam_member",
        "google_cloud_run_v2_service_iam_policy",
        "google_cloudfunctions2_function",
        "google_cloudfunctions2_function_iam_binding",
        "google_cloudfunctions2_function_iam_member",
        "google_cloudfunctions2_function_iam_policy",
        "google_cloudfunctions_function",
        "google_cloudfunctions_function_iam_binding",
        "google_cloudfunctions_function_iam_member",
        "google_cloudfunctions_function_iam_policy",
        "google_compute_backend_bucket",
        "google_compute_backend_service",
        "google_compute_firewall",
        "google_compute_firewall_policy",
        "google_compute_firewall_policy_association",
        "google_compute_firewall_policy_rule",
        "google_compute_forwarding_rule",
        "google_compute_global_address",
        "google_compute_global_forwarding_rule",
        "google_compute_instance",
        "google_compute_managed_ssl_certificate",
        "google_compute_network",
        "google_compute_network_endpoint_group",
        "google_compute_region_backend_service",
        "google_compute_region_network_endpoint_group",
        "google_compute_region_security_policy",
        "google_compute_region_target_http_proxy",
        "google_compute_region_target_https_proxy",
        "google_compute_region_url_map",
        "google_compute_route",
        "google_compute_router",
        "google_compute_router_nat",
        "google_compute_security_policy",
        "google_compute_service_attachment",
        "google_compute_ssl_policy",
        "google_compute_subnetwork",
        "google_compute_target_http_proxy",
        "google_compute_target_https_proxy",
        "google_compute_url_map",
        "google_container_cluster",
        "google_container_node_pool",
        "google_folder_iam_binding",
        "google_folder_iam_member",
        "google_folder_iam_policy",
        "google_folder_organization_policy",
        "google_iam_workload_identity_pool",
        "google_iam_workload_identity_pool_provider",
        "google_kms_crypto_key",
        "google_kms_crypto_key_iam_binding",
        "google_kms_crypto_key_iam_member",
        "google_kms_crypto_key_iam_policy",
        "google_kms_key_ring_iam_binding",
        "google_kms_key_ring_iam_member",
        "google_kms_key_ring_iam_policy",
        "google_logging_organization_exclusion",
        "google_logging_organization_sink",
        "google_logging_project_exclusion",
        "google_logging_project_sink",
        "google_network_connectivity_service_connection_policy",
        "google_org_policy_policy",
        "google_organization_iam_binding",
        "google_organization_iam_custom_role",
        "google_organization_iam_member",
        "google_organization_iam_policy",
        "google_organization_policy",
        "google_project_iam_binding",
        "google_project_iam_custom_role",
        "google_project_iam_member",
        "google_project_iam_policy",
        "google_project_organization_policy",
        "google_pubsub_subscription",
        "google_pubsub_subscription_iam_binding",
        "google_pubsub_subscription_iam_member",
        "google_pubsub_subscription_iam_policy",
        "google_pubsub_topic",
        "google_pubsub_topic_iam_binding",
        "google_pubsub_topic_iam_member",
        "google_pubsub_topic_iam_policy",
        "google_scc_organization_settings",
        "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_service_networking_connection",
        "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": 8,
      "provider_resource_count": 8,
      "normalized_resource_count": 8,
      "unsupported_resource_types": {}
    },
    "resources": [
      {
        "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",
          "project": "tfstride-demo",
          "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",
          "project": "tfstride-demo",
          "region": "us-central1",
          "network": "google_compute_network.main.id",
          "cidr_range": "10.10.1.0/24",
          "private_ip_google_access": true,
          "purpose": null,
          "stack_type": null,
          "secondary_ip_ranges": [],
          "subnetwork_flow_log_state": "not_configured",
          "subnetwork_flow_log_config": {},
          "subnetwork_flow_log_metadata_fields": [],
          "network_telemetry_posture_uncertainties": [],
          "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",
          "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",
          "kms_posture_uncertainties": [],
          "labels": {
            "app": "tfstride"
          },
          "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",
          "iam_role": "roles/cloudkms.cryptoKeyDecrypter",
          "iam_member": "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com",
          "iam_members": [
            "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com"
          ],
          "iam_condition": {},
          "iam_bindings": [
            {
              "role": "roles/cloudkms.cryptoKeyDecrypter",
              "members": [
                "serviceAccount:decryptor@partner-project.iam.gserviceaccount.com"
              ]
            }
          ],
          "privileged_access_grants": []
        }
      },
      {
        "address": "google_project_iam_member.partner_editor",
        "provider": "gcp",
        "resource_type": "google_project_iam_member",
        "name": "partner_editor",
        "category": "iam",
        "identifier": "roles/editor:serviceAccount:deployer@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": {
          "project": "tfstride-demo",
          "iam_role": "roles/editor",
          "iam_member": "serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
          "iam_members": [
            "serviceAccount:deployer@partner-project.iam.gserviceaccount.com"
          ],
          "iam_condition": {},
          "iam_bindings": [
            {
              "role": "roles/editor",
              "members": [
                "serviceAccount:deployer@partner-project.iam.gserviceaccount.com"
              ]
            }
          ],
          "privileged_access_grants": [
            {
              "provider": "gcp",
              "principal_type": "service-account",
              "principal_identifier": "serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
              "principal_display_name": "serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
              "principal_source_address": "google_project_iam_member.partner_editor",
              "scope_kind": "project",
              "scope_value": "tfstride-demo",
              "scope_source_address": null,
              "privilege_categories": [
                "compute-admin",
                "network-admin",
                "data-admin"
              ],
              "confidence": "high",
              "assignment_source_address": "google_project_iam_member.partner_editor",
              "role_name": "roles/editor",
              "role_id": "roles/editor",
              "permission_patterns": [
                "roles/editor"
              ],
              "evidence": [
                "source=google_project_iam_member.partner_editor",
                "role=roles/editor",
                "member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
                "scope_kind=project",
                "scope_value=tfstride-demo"
              ],
              "uncertainties": []
            }
          ]
        }
      },
      {
        "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"
          },
          "secret_manager_replication_mode": "automatic",
          "secret_manager_kms_key_names": [
            "projects/tfstride-demo/locations/global/keyRings/tfstride-app/cryptoKeys/tfstride-secret-manager"
          ],
          "secret_manager_replication": {
            "mode": "automatic",
            "kms_key_names": [
              "projects/tfstride-demo/locations/global/keyRings/tfstride-app/cryptoKeys/tfstride-secret-manager"
            ]
          },
          "secret_manager_posture_uncertainties": [],
          "secret_manager_ttl": "2592000s",
          "secret_manager_version_destroy_ttl": "604800s",
          "annotations": {},
          "topics": [],
          "customer_managed_encryption": true,
          "storage_encrypted": true,
          "iam_bindings": [
            {
              "role": "roles/secretmanager.secretAccessor",
              "members": [
                "serviceAccount:reader@partner-project.iam.gserviceaccount.com"
              ],
              "source": "google_secret_manager_secret_iam_member.partner_accessor"
            }
          ],
          "gcp_resource_policy_source_addresses": [
            "google_secret_manager_secret_iam_member.partner_accessor"
          ]
        }
      },
      {
        "address": "google_secret_manager_secret_iam_member.partner_accessor",
        "provider": "gcp",
        "resource_type": "google_secret_manager_secret_iam_member",
        "name": "partner_accessor",
        "category": "iam",
        "identifier": "google_secret_manager_secret.api_key.id:roles/secretmanager.secretAccessor:serviceAccount:reader@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": {
          "secret_reference": "google_secret_manager_secret.api_key.id",
          "project": "tfstride-demo",
          "iam_role": "roles/secretmanager.secretAccessor",
          "iam_member": "serviceAccount:reader@partner-project.iam.gserviceaccount.com",
          "iam_members": [
            "serviceAccount:reader@partner-project.iam.gserviceaccount.com"
          ],
          "iam_condition": {},
          "iam_bindings": [
            {
              "role": "roles/secretmanager.secretAccessor",
              "members": [
                "serviceAccount:reader@partner-project.iam.gserviceaccount.com"
              ]
            }
          ],
          "privileged_access_grants": []
        }
      },
      {
        "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 workload."
        }
      }
    ]
  },
  "trust_boundaries": [],
  "findings": [
    {
      "fingerprint": "sha256:40f826d84149dfdf70e920723966038a1bed894f51393878ab4d871a2882282a",
      "title": "GCP project IAM binding grants a high-privilege role",
      "rule_id": "gcp-project-iam-privileged-role",
      "category": "Elevation of Privilege",
      "severity": "high",
      "affected_resources": [
        "google_project_iam_member.partner_editor"
      ],
      "trust_boundary_id": null,
      "rationale": "google_project_iam_member.partner_editor grants the high-impact GCP role `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope. That role enables broad write access across most project services and can materially expand control-plane blast radius if the principal is compromised or mis-scoped.",
      "recommended_mitigation": "Replace Owner, Editor, IAM admin, service-account impersonation, and admin-class project roles with narrowly scoped predefined or custom roles assigned to specific groups or service accounts.",
      "evidence": [
        {
          "key": "iam_binding",
          "values": [
            "member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
            "role=roles/editor"
          ]
        },
        {
          "key": "role_risk",
          "values": [
            "broad write access across most project services"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 2,
        "data_sensitivity": 0,
        "lateral_movement": 2,
        "blast_radius": 2,
        "final_score": 6,
        "severity": "high",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:69b3180a4566117713435ac679c061d9b05b23d1cb98bf38d87fe19becae0753",
      "title": "Inherited GCP IAM grant expands descendant blast radius",
      "rule_id": "gcp-inherited-iam-blast-radius",
      "category": "Elevation of Privilege",
      "severity": "high",
      "affected_resources": [
        "google_project_iam_member.partner_editor",
        "google_compute_network.main",
        "google_compute_subnetwork.app",
        "google_kms_crypto_key.customer",
        "google_secret_manager_secret.api_key",
        "google_service_account.web"
      ],
      "trust_boundary_id": null,
      "rationale": "google_project_iam_member.partner_editor grants `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope `tfstride-demo`, and that inherited grant applies to 5 concrete descendant resource(s). A high-level IAM grant with broad, external, or high-impact access increases control-plane blast radius because compromise or misuse can affect resources below the inherited scope.",
      "recommended_mitigation": "Avoid broad or high-impact IAM grants at organization, folder, and project scope when narrower resource-level or workload-specific bindings are possible; split inherited roles by service and review descendant resources before assigning public, external, or administrator principals.",
      "evidence": [
        {
          "key": "iam_binding",
          "values": [
            "source=google_project_iam_member.partner_editor",
            "scope=project:tfstride-demo",
            "member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
            "role=roles/editor"
          ]
        },
        {
          "key": "role_risk",
          "values": [
            "broad write access across most project services"
          ]
        },
        {
          "key": "trust_scope",
          "values": [
            "service account belongs to project `partner-project`, outside resource project `tfstride-demo`"
          ]
        },
        {
          "key": "descendant_scope",
          "values": [
            "scope=project:tfstride-demo",
            "descendant_count=5",
            "resource_type_count=5",
            "projects=tfstride-demo"
          ]
        },
        {
          "key": "descendant_resource_types",
          "values": [
            "google_compute_network: 1",
            "google_compute_subnetwork: 1",
            "google_kms_crypto_key: 1",
            "google_secret_manager_secret: 1",
            "google_service_account: 1"
          ]
        },
        {
          "key": "descendant_resources",
          "values": [
            "google_compute_network.main",
            "google_compute_subnetwork.app",
            "google_kms_crypto_key.customer",
            "google_secret_manager_secret.api_key",
            "google_service_account.web"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 2,
        "data_sensitivity": 2,
        "lateral_movement": 2,
        "blast_radius": 2,
        "final_score": 8,
        "severity": "high",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:c6aeec8e3c6ffa7bea03d2dd40bf3dcb25eeb1d726a1a15197880a6399310861",
      "title": "Inherited GCP IAM grant reaches sensitive resources",
      "rule_id": "gcp-inherited-iam-sensitive-resource-access",
      "category": "Information Disclosure",
      "severity": "high",
      "affected_resources": [
        "google_project_iam_member.partner_editor",
        "google_kms_crypto_key.customer",
        "google_secret_manager_secret.api_key"
      ],
      "trust_boundary_id": null,
      "rationale": "google_project_iam_member.partner_editor grants `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope `tfstride-demo`, and that inherited grant reaches 2 sensitive GCP descendant resource(s). Project, folder, and organization IAM applies below the grant scope, so a single ancestor binding can expose data resources beyond their local IAM boundary.",
      "recommended_mitigation": "Move sensitive data access off organization, folder, and project-level IAM where possible; grant Secret Manager, KMS, GCS, Cloud SQL, BigQuery, and Pub/Sub permissions at the narrowest resource scope with reviewed principals and custom roles.",
      "evidence": [
        {
          "key": "iam_binding",
          "values": [
            "source=google_project_iam_member.partner_editor",
            "scope=project:tfstride-demo",
            "member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com",
            "role=roles/editor"
          ]
        },
        {
          "key": "sensitive_descendants",
          "values": [
            "resource=google_kms_crypto_key.customer; type=google_kms_crypto_key; risk=Cloud KMS cryptographic key access through roles/editor",
            "resource=google_secret_manager_secret.api_key; type=google_secret_manager_secret; risk=Secret Manager secret access through roles/editor"
          ]
        },
        {
          "key": "trust_scope",
          "values": [
            "service account belongs to project `partner-project`, outside resource project `tfstride-demo`"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 2,
        "data_sensitivity": 2,
        "lateral_movement": 1,
        "blast_radius": 2,
        "final_score": 7,
        "severity": "high",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:d7380b4b3e19c2f29c68019a1757075b9455a4465c9cf613a0fd4a3a2d8dc9e9",
      "title": "GCP subnetwork Flow Logs are not configured",
      "rule_id": "gcp-subnetwork-flow-logs-not-configured",
      "category": "Repudiation",
      "severity": "medium",
      "affected_resources": [
        "google_compute_subnetwork.app"
      ],
      "trust_boundary_id": null,
      "rationale": "google_compute_subnetwork.app does not configure VPC Flow Logs in this Terraform plan. Without subnetwork flow telemetry, network investigation, lateral-movement review, and egress analysis can lack packet-flow evidence for workloads attached to this subnet.",
      "recommended_mitigation": "Enable VPC Flow Logs on subnetworks that host workloads, keep the flow log configuration in Terraform, and export or retain those logs according to investigation and monitoring requirements.",
      "evidence": [
        {
          "key": "subnetwork_flow_log_posture",
          "values": [
            "address=google_compute_subnetwork.app",
            "type=google_compute_subnetwork",
            "name=app",
            "identifier=tfstride-app",
            "flow_log_state=not_configured",
            "network=google_compute_network.main.id",
            "project=tfstride-demo"
          ]
        }
      ],
      "severity_reasoning": {
        "internet_exposure": 0,
        "privilege_breadth": 0,
        "data_sensitivity": 0,
        "lateral_movement": 2,
        "blast_radius": 1,
        "final_score": 3,
        "severity": "medium",
        "computed_severity": null
      }
    },
    {
      "fingerprint": "sha256:0a66a1e14240c9ca054e874b2a2d0eaae2d063ac0048377a075d38a8d8c351a5",
      "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_secret_manager_secret.api_key",
        "google_secret_manager_secret_iam_member.partner_accessor"
      ],
      "trust_boundary_id": null,
      "rationale": "google_secret_manager_secret.api_key grants `roles/secretmanager.secretAccessor` to `serviceAccount:reader@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_secret_manager_secret_iam_member.partner_accessor",
            "role=roles/secretmanager.secretAccessor",
            "member=serviceAccount:reader@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_secret_manager_secret_iam_member.partner_accessor"
          ]
        }
      ],
      "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
      }
    },
    {
      "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 covers a curated set of compute, serverless, data, IAM, Kubernetes, networking, audit, private-connectivity, messaging, registry, and key-management resources. Analysis is plan-local and does not model every provider resource, runtime drift, or every organization-level control; provider-specific positive observations remain more limited than finding coverage.",
    "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 Cross-Project IAM Demo

- Analyzed file: `sample_gcp_cross_project_iam_plan.json`
- Provider: `gcp`
- Normalized resources: `8`
- Unsupported resources: `0`

## Summary

This run identified **0 trust boundaries** and **6 findings** across **8 normalized resources**.

- High severity findings: `3`
- Medium severity findings: `3`
- Low severity findings: `0`

## Analysis Coverage

- Terraform resources seen: `8`
- Provider resources considered: `8`
- Normalized resources: `8`
- Unsupported resources: `0`
- Registered provider rules (GCP): `78`
- Enabled provider rules (GCP): `78`
- Disabled rules: `0`
- Severity overrides: `0`
- Unresolved in-plan references: `0`
- Findings by rule:
  - `gcp-sensitive-resource-iam-external-access`: `2`
  - `gcp-subnetwork-flow-logs-not-configured`: `1`
  - `gcp-project-iam-privileged-role`: `1`
  - `gcp-inherited-iam-sensitive-resource-access`: `1`
  - `gcp-inherited-iam-blast-radius`: `1`

## Discovered Trust Boundaries

No trust boundaries were discovered.

## Findings

### High

#### GCP project IAM binding grants a high-privilege role

- STRIDE category: Elevation of Privilege
- Affected resources: `google_project_iam_member.partner_editor`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +2, data_sensitivity +0, lateral_movement +2, blast_radius +2, final_score 6 => high
- Rationale: google_project_iam_member.partner_editor grants the high-impact GCP role `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope. That role enables broad write access across most project services and can materially expand control-plane blast radius if the principal is compromised or mis-scoped.
- Recommended mitigation: Replace Owner, Editor, IAM admin, service-account impersonation, and admin-class project roles with narrowly scoped predefined or custom roles assigned to specific groups or service accounts.
- Evidence:
  - iam binding: member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com; role=roles/editor
  - role risk: broad write access across most project services

#### Inherited GCP IAM grant expands descendant blast radius

- STRIDE category: Elevation of Privilege
- Affected resources: `google_project_iam_member.partner_editor`, `google_compute_network.main`, `google_compute_subnetwork.app`, `google_kms_crypto_key.customer`, `google_secret_manager_secret.api_key`, `google_service_account.web`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +2, data_sensitivity +2, lateral_movement +2, blast_radius +2, final_score 8 => high
- Rationale: google_project_iam_member.partner_editor grants `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope `tfstride-demo`, and that inherited grant applies to 5 concrete descendant resource(s). A high-level IAM grant with broad, external, or high-impact access increases control-plane blast radius because compromise or misuse can affect resources below the inherited scope.
- Recommended mitigation: Avoid broad or high-impact IAM grants at organization, folder, and project scope when narrower resource-level or workload-specific bindings are possible; split inherited roles by service and review descendant resources before assigning public, external, or administrator principals.
- Evidence:
  - iam binding: source=google_project_iam_member.partner_editor; scope=project:tfstride-demo; member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com; role=roles/editor
  - role risk: broad write access across most project services
  - trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`
  - descendant scope: scope=project:tfstride-demo; descendant_count=5; resource_type_count=5; projects=tfstride-demo
  - descendant resource types: google_compute_network: 1; google_compute_subnetwork: 1; google_kms_crypto_key: 1; google_secret_manager_secret: 1; google_service_account: 1
  - descendant resources: google_compute_network.main; google_compute_subnetwork.app; google_kms_crypto_key.customer; google_secret_manager_secret.api_key; google_service_account.web

#### Inherited GCP IAM grant reaches sensitive resources

- STRIDE category: Information Disclosure
- Affected resources: `google_project_iam_member.partner_editor`, `google_kms_crypto_key.customer`, `google_secret_manager_secret.api_key`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +2, data_sensitivity +2, lateral_movement +1, blast_radius +2, final_score 7 => high
- Rationale: google_project_iam_member.partner_editor grants `roles/editor` to `serviceAccount:deployer@partner-project.iam.gserviceaccount.com` at project scope `tfstride-demo`, and that inherited grant reaches 2 sensitive GCP descendant resource(s). Project, folder, and organization IAM applies below the grant scope, so a single ancestor binding can expose data resources beyond their local IAM boundary.
- Recommended mitigation: Move sensitive data access off organization, folder, and project-level IAM where possible; grant Secret Manager, KMS, GCS, Cloud SQL, BigQuery, and Pub/Sub permissions at the narrowest resource scope with reviewed principals and custom roles.
- Evidence:
  - iam binding: source=google_project_iam_member.partner_editor; scope=project:tfstride-demo; member=serviceAccount:deployer@partner-project.iam.gserviceaccount.com; role=roles/editor
  - sensitive descendants: resource=google_kms_crypto_key.customer; type=google_kms_crypto_key; risk=Cloud KMS cryptographic key access through roles/editor; resource=google_secret_manager_secret.api_key; type=google_secret_manager_secret; risk=Secret Manager secret access through roles/editor
  - trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`

### Medium

#### GCP subnetwork Flow Logs are not configured

- STRIDE category: Repudiation
- Affected resources: `google_compute_subnetwork.app`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +2, blast_radius +1, final_score 3 => medium
- Rationale: google_compute_subnetwork.app does not configure VPC Flow Logs in this Terraform plan. Without subnetwork flow telemetry, network investigation, lateral-movement review, and egress analysis can lack packet-flow evidence for workloads attached to this subnet.
- Recommended mitigation: Enable VPC Flow Logs on subnetworks that host workloads, keep the flow log configuration in Terraform, and export or retain those logs according to investigation and monitoring requirements.
- Evidence:
  - subnetwork flow log posture: address=google_compute_subnetwork.app; type=google_compute_subnetwork; name=app; identifier=tfstride-app; flow_log_state=not_configured; network=google_compute_network.main.id; project=tfstride-demo

#### 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.partner_accessor`
- 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_secret_manager_secret.api_key grants `roles/secretmanager.secretAccessor` to `serviceAccount:reader@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_secret_manager_secret_iam_member.partner_accessor; role=roles/secretmanager.secretAccessor; member=serviceAccount:reader@partner-project.iam.gserviceaccount.com
  - trust scope: service account belongs to project `partner-project`, outside resource project `tfstride-demo`
  - resource policy sources: google_secret_manager_secret_iam_member.partner_accessor

#### 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 covers a curated set of compute, serverless, data, IAM, Kubernetes, networking, audit, private-connectivity, messaging, registry, and key-management resources. Analysis is plan-local and does not model every provider resource, runtime drift, or every organization-level control; provider-specific positive observations remain more limited than finding coverage.
- 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 covers a curated set of compute, serverless, data, IAM, Kubernetes, networking, audit, private-connectivity, messaging, registry, and key-management resources. Analysis is plan-local and does not model every provider resource, runtime drift, or every organization-level control; provider-specific positive observations remain more limited than finding coverage.
  • The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity.