# GCP Firewall Rule on Default VPC Network

> Every firewall rule attached to a network named default gets flagged high severity by ZopNight rule RC-1252. The auto-created default VPC ships with permissive pre-created rules and a subnet in every region, so production traffic there inherits decisions nobody reviewed. Detection reads the rule's network reference from provider config.

Source: https://zop.dev/integrations/gcp/recommendations/gcp-firewall-rule-on-default-vpc-network
Updated: 2026-08-19

---

## Inherited network decisions

The default VPC is the network nobody chose. Google auto-creates it in new projects with a
subnet in every region and a starter set of firewall rules (including a rule allowing all
internal traffic between instances and rules opening SSH, RDP, and ICMP to the world)
sized for a first tutorial, not a production posture. A firewall rule attached to it is a
signal that real workloads have taken root on that unchosen network, inheriting its
pre-created permissiveness and its everywhere-at-once subnet sprawl as silent defaults.

## Why the default network stays around

Nobody plans to run production on the default VPC; it happens by accretion. The first test
VM lands there because it is the default in every console dropdown, a service grows around
the VM, and by the time anyone notices, migration means re-plumbing addresses and peering.
Each custom firewall rule added to the network is another root the eventual migration must
dig out, which is why the rule flags the rules themselves, one finding per rule, rather
than one abstract finding per project.

## Name matching and its edge cases

The discoverer resolves each firewall rule's network reference to its final path segment
and stamps it into the rule's metadata; RC-1252 fires when that segment is exactly
`default`. Two honest caveats follow. A custom-mode VPC that someone deliberately named
`default` would be flagged even though it is not the auto-created network; the rule
matches the name, not the provenance. And a rule whose network metadata is absent abstains
rather than firing. Reads come from Cloud Asset Inventory under `roles/cloudasset.viewer`;
nothing in the finding path modifies networks.

## Audit rules on the default network

```bash
gcloud compute firewall-rules list \
  --filter="network:default" \
  --format="table(name,direction,sourceRanges.list(),allowed[].map().firewall_rule().list())"
```

The pre-created `default-allow-ssh` and `default-allow-rdp` entries with `0.0.0.0/0`
sources are usually the first surprise.

## Moving off, in the order that works

Create the custom-mode VPC first, with only the subnets and regions you actually use.
Recreate the firewall rules there as least-privilege equivalents. This is the natural
moment to drop the allow-everything-internal pattern. Migrate workloads, then delete the
default network so the next quarter's test VM cannot resurrect the problem. Projects
created through an organization policy can skip default network creation entirely, which
prevents this whole class at birth.
