Back to blog
Best PracticesCloud SecurityGCPMonitoring & LoggingNetworking

GCP Firewall Rule Logging Missing Metadata: Why It Matters and How to Fix It

Learn why GCP firewall rules with logging enabled but metadata excluded leave gaps in investigations, and how to fix and prevent it with gcloud, Terraform, and policy-as-code.

TL;DR

This check flags GCP firewall rules that have logging turned on but are configured to exclude metadata, which strips out the source, destination, and rule details you need during an investigation. Fix it by setting the log config metadata to INCLUDE_ALL_METADATA.

Firewall logging in Google Cloud is one of those settings that feels done once you flip it on. The toggle is green, logs are flowing, everyone moves on. But there is a second dial that quietly controls how useful those logs actually are, and it defaults in a way that can leave you with records that tell you a connection happened without telling you much else about it.

This check catches firewall rules where logging is enabled but metadata is excluded. The result is logs that exist but answer fewer questions than you would expect when you need them most.


What this check detects

Every GCP VPC firewall rule can have a logConfig block. That block has two relevant fields:

  • enable — whether the rule produces logs at all
  • metadata — how much context each log entry carries, either INCLUDE_ALL_METADATA or EXCLUDE_ALL_METADATA

The check fires when enable is true but metadata is set to EXCLUDE_ALL_METADATA. In that state, the rule writes log entries but drops the extra fields that describe the connection, things like the instance details, the VPC and subnet, the geographic location of the remote endpoint, and the specifics of which rule matched and why.

Note: Firewall rule logging in GCP records connections that are allowed or denied by a specific rule. It is not the same as VPC Flow Logs, which capture traffic at the subnet level regardless of which rule applied. The two complement each other, and both have their own metadata settings.

You can confirm the current state of a rule with gcloud:

gcloud compute firewall-rules describe RULE_NAME \
  --format="yaml(name, logConfig)"

A flagged rule looks like this:

name: allow-ssh-from-bastion
logConfig:
  enable: true
  metadata: EXCLUDE_ALL_METADATA

Why it matters

The whole point of firewall logging is to have answers ready when something looks off. Metadata is where most of those answers live.

Picture a typical incident. An alert fires for unexpected outbound traffic on a port you do not recognize. You pull the firewall logs for the rule that allowed it. With metadata included, each entry tells you the source and destination instances, the project, the VPC and subnet, the remote IP and its geographic location, and the exact rule priority that matched. You can reconstruct the path of the connection in minutes.

With metadata excluded, you get the timestamp, the connection tuple, and the action. That confirms a connection happened, but it leaves you guessing at the context. Was the remote IP in a region your business never operates in? Which subnet did the workload sit in? You end up cross-referencing other log sources to rebuild information you could have captured at the source.

Warning: The gap usually surfaces at the worst possible time. Logs are retroactive, so if metadata was excluded last month, you cannot recover it for last month's traffic. Turning it on today only helps from today forward, which makes this a fix worth making before you need it.

There is a compliance angle too. Frameworks like PCI DSS, SOC 2, and CIS benchmarks expect network access logs to be detailed enough to support forensic review. Logs without metadata often fail to meet that bar, and an auditor who asks to trace a specific connection will quickly notice what is missing.


How to fix it

The fix is to update the rule so logging includes all metadata. You are not changing what traffic the rule allows or denies, only how much detail the logs carry, so the blast radius is small.

Using gcloud

gcloud compute firewall-rules update RULE_NAME \
  --enable-logging \
  --logging-metadata=include-all

Verify the change took effect:

gcloud compute firewall-rules describe RULE_NAME \
  --format="yaml(name, logConfig)"

You should now see:

name: allow-ssh-from-bastion
logConfig:
  enable: true
  metadata: INCLUDE_ALL_METADATA

Using the Console

  1. Go to VPC network → Firewall.
  2. Click the rule name, then Edit.
  3. Under Logs, confirm logging is On.
  4. Expand the logging options and set metadata to Include metadata.
  5. Click Save.

Using Terraform

If your firewall rules are managed in Terraform, set the log_config block explicitly. Leaving it off does not mean metadata is included, so be deliberate:

resource "google_compute_firewall" "allow_ssh_from_bastion" {
  name    = "allow-ssh-from-bastion"
  network = google_compute_network.main.id

  allow {
    protocol = "tcp"
    ports    = ["22"]
  }

  source_ranges = ["10.0.1.0/24"]

  log_config {
    metadata = "INCLUDE_ALL_METADATA"
  }
}

Tip: In Terraform, the presence of a log_config block is what enables logging. To audit all your rules at once, list them and patch any that are missing the full metadata setting with a short loop rather than editing each by hand.

To find and fix every affected rule in a project:

gcloud compute firewall-rules list \
  --filter="logConfig.enable=true AND logConfig.metadata=EXCLUDE_ALL_METADATA" \
  --format="value(name)" | while read rule; do
    gcloud compute firewall-rules update "$rule" \
      --logging-metadata=include-all
done

Warning: Including all metadata produces larger and more frequent log entries, which increases what you send to Cloud Logging. On high-traffic rules this can raise ingestion costs. If budget is a concern, scope full metadata to sensitive rules and pair it with a log sink and retention policy that match your needs.


How to prevent it from happening again

Catching this once is easy. Keeping it from drifting back is the harder part, especially across many projects and teams. A few controls handle it.

Enforce it with Organization Policy and IaC review

Bake the correct log_config into the modules your teams use to create firewall rules. If the only sanctioned way to make a rule is through a module that always sets INCLUDE_ALL_METADATA, the bad state never gets created in the first place.

Add a policy-as-code gate in CI

Use a tool like Conftest with OPA to block any Terraform plan that creates a logging-enabled firewall rule without full metadata. Example Rego:

package firewall

deny[msg] {
  resource := input.resource_changes[_]
  resource.type == "google_compute_firewall"
  config := resource.change.after.log_config[_]
  config.metadata == "EXCLUDE_ALL_METADATA"
  msg := sprintf("firewall rule %q excludes log metadata", [resource.name])
}

deny[msg] {
  resource := input.resource_changes[_]
  resource.type == "google_compute_firewall"
  count(resource.change.after.log_config) == 0
  msg := sprintf("firewall rule %q has no log_config block", [resource.name])
}

Wire that into your pipeline so a plan with a non-compliant rule fails the build before it reaches production.

Run continuous detection

IaC gates only cover resources created through IaC. Manual changes in the console and emergency rules made under pressure slip past them. Continuous scanning with Lensix flags any firewall rule that drifts into the excluded-metadata state regardless of how it was created, so you find out within a scan cycle instead of during an incident.


Best practices

  • Treat logging and metadata as one decision. When you enable logging on a rule, set metadata in the same change so you never end up with logs that are half useful.
  • Prioritize sensitive rules. Rules governing SSH, RDP, database ports, and any internet-facing ingress are the ones you will most want full context for. Make sure those have complete metadata even if you trim it elsewhere for cost.
  • Pair firewall logs with VPC Flow Logs. Together they give you both rule-level and subnet-level visibility, which makes investigations far easier.
  • Route logs to a durable sink. Export firewall logs to a BigQuery dataset or a Cloud Storage bucket with retention that matches your compliance requirements, so the detail survives past the default Cloud Logging window.
  • Review on a schedule. Periodically list rules with logging enabled and confirm metadata settings, since defaults and ad hoc edits drift over time.

Logging without metadata is one of those configurations that looks fine on a dashboard and disappoints in an investigation. The fix costs one flag, and the payoff is logs that actually answer the question you are asking when it matters.