Skip to content

[REVIEW] gcp-review: add VPC Service Controls dry-run and bridge evidence gates #1169

@stmr

Description

@stmr

Skill Being Reviewed

Skill name: gcp-review
Skill path: skills/cloud/gcp-review/

False Positive Analysis

Benign code that triggers a false positive:

resource "google_access_context_manager_service_perimeter" "analytics" {
  name           = "accessPolicies/${var.policy}/servicePerimeters/analytics"
  parent         = "accessPolicies/${var.policy}"
  title          = "analytics"
  perimeter_type = "PERIMETER_TYPE_REGULAR"

  status {
    restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"]
    resources           = ["projects/${var.analytics_project_number}"]

    egress_policies {
      egress_from {
        identities = ["serviceAccount:etl@${var.analytics_project_id}.iam.gserviceaccount.com"]
      }
      egress_to {
        resources = ["projects/${var.reporting_project_number}"]
        operations {
          service_name = "bigquery.googleapis.com"
        }
      }
    }
  }

  spec {
    restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"]
    resources           = ["projects/${var.analytics_project_number}"]
  }
  use_explicit_dry_run_spec = true
}

Why this is a false positive:

The skill is scoped to CIS GCP v2.0.0 sections 1-7 and has strong checks for IAM, logging, networking, storage, Cloud SQL, and BigQuery, but it does not model VPC Service Controls state. A reviewer following only the current output can mark the BigQuery/storage controls as pass or not applicable while treating a dry-run perimeter as equivalent context evidence. Dry-run mode is useful for evaluating impact, but it is not enforcement. If the report does not distinguish status enforcement from spec dry-run configuration, it can overstate protection around restricted services.

The benign case above is safe only if the reviewer records that enforcement is in status, dry-run is advisory, and the egress policy is scoped to a named service account, service, and project. Without those fields, the skill can produce a false assurance instead of a precise pass.

Coverage Gaps

Missed variant 1: perimeter bridge gives bidirectional broad access

resource "google_access_context_manager_service_perimeter" "bridge" {
  name           = "accessPolicies/${var.policy}/servicePerimeters/analytics_reporting_bridge"
  parent         = "accessPolicies/${var.policy}"
  title          = "analytics-reporting-bridge"
  perimeter_type = "PERIMETER_TYPE_BRIDGE"

  status {
    resources = [
      "projects/${var.analytics_project_number}",
      "projects/${var.reporting_project_number}"
    ]
  }
}

Why it should be caught:

Perimeter bridges are intentionally broad and bidirectional. They can be valid, but they should not be scored like narrow ingress/egress rules. The skill should require bridge justification, data-classification scope, project inventory, compensating IAM, and a review of whether targeted ingress/egress rules would be safer.

Missed variant 2: dry-run findings are not promoted before go-live

name: accessPolicies/123/servicePerimeters/payments
title: payments
useExplicitDryRunSpec: true
status:
  restrictedServices:
    - storage.googleapis.com
  resources:
    - projects/111111111111
spec:
  restrictedServices:
    - storage.googleapis.com
    - bigquery.googleapis.com
  resources:
    - projects/111111111111
    - projects/222222222222

Why it should be caught:

This configuration has a materially different dry-run perimeter than the enforced perimeter. A review that only checks for a perimeter definition will miss that BigQuery and the second project are not enforced yet. The report should require explicit separation of enforced and dry-run scope, access-denied dry-run findings, proposed changes, and a promotion or rollback decision.

Edge Cases

  • Some Google-managed resources are allowed regardless of ingress or egress policy restrictions. The review should call these out when a finding claims that VPC Service Controls blocks all service access paths.
  • Shared VPC host and service projects need perimeter membership and access path review. A service project can be protected incorrectly if only the application project is listed.
  • Access levels and ingress rules both affect incoming access. The skill should require identity, device, IP range, and source project evidence rather than treating the perimeter as a single boolean.
  • A perimeter can restrict Google APIs but still leave internet egress, private service access, or workload IAM paths under-reviewed.
  • Terraform module outputs can hide the actual status, spec, perimeter_type, and egress policy resources. The review should mark these as Not Evaluable unless rendered config or gcloud access-context-manager perimeters describe output is available.

Remediation Quality

  • Fix resolves the vulnerability
  • Fix doesn't introduce new security issues
  • Fix doesn't break functionality
  • Issues found:

Add a VPC Service Controls evidence subsection to the GCP posture report. For each perimeter, require: policy name, perimeter name, type, enforced resources/services, dry-run resources/services, bridge membership, ingress/egress rules, access levels, Shared VPC host/service project coverage, restricted/private VIP routing assumptions, and Not Evaluable reasons.

Severity should be based on effective service-perimeter enforcement:

  • Critical or High: sensitive data projects rely only on dry-run, bridges connect unrelated data domains, broad egress to all projects/services, or service projects are outside the intended perimeter.
  • Medium: missing promotion evidence from dry-run to enforced state, missing bridge justification, or incomplete access-level evidence.
  • Low: documentation gaps where enforcement is present but reviewer evidence is incomplete.

Comparison to Other Tools

Tool Catches this? Notes
Security Command Center Partial Can surface VPC Service Controls findings, but repository review still needs rendered perimeter and dry-run evidence.
Terraform plan review Partial Shows intended resources but can hide module-expanded status/spec differences unless rendered output is inspected.
Policy Controller / Config Validator Partial Can enforce policy-as-code constraints if VPC-SC constraints are authored, but the skill should not assume they exist.
Manual GCP review Yes A cloud security review should inspect enforced perimeters, dry-run deltas, bridge scope, and ingress/egress rules together.

Overall Assessment

Strengths:

  • Strong CIS GCP posture structure across IAM, logging, networking, storage, Cloud SQL, and BigQuery.
  • Useful output format with control IDs, severities, evidence, and remediation.
  • Good prompt-injection safety note for infrastructure-as-code comments and descriptions.

Needs improvement:

  • VPC Service Controls are absent from the evidence model, even though they are a common control for BigQuery, Cloud Storage, and service-to-service data exfiltration boundaries.
  • Dry-run and enforced perimeter states are not separated, which can produce false assurance before go-live.
  • Perimeter bridges are not treated as a special broad-access case that needs justification and compensating control review.

Priority recommendations:

  1. Add a VPC Service Controls section to the GCP assessment report with enforced-vs-dry-run fields.
  2. Add specific checks for PERIMETER_TYPE_BRIDGE, broad ingress/egress rules, and Shared VPC host/service project coverage.
  3. Mark VPC-SC claims as Not Evaluable when only Terraform module inputs are available and no rendered perimeter state or gcloud export is present.
  4. Update the framework note to state that CIS coverage is not the full GCP data-boundary review when VPC-SC is in scope.

Official references used:

Bounty Info

  • I have read and agree to the CONTRIBUTING.md bounty terms
  • Preferred payment method: PayPal samik4184@gmail.com

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions