Cloud Armor provides web application firewall (WAF) and DDoS protection for applications running behind Google Cloud load balancers. It protects against common web attacks like SQL injection and cross-site scripting, and provides adaptive protection against application-layer DDoS attacks.
This guide covers creating security policies, implementing WAF rules, configuring rate limiting, and enabling advanced protection features. This expands on Tip 13 from our 30 Cloud Security Tips for 2026 guide on implementing web application firewalls.
Prerequisites
Before configuring Cloud Armor, ensure you have:
- An external HTTP(S) Load Balancer (global or regional)
- Backend services configured behind the load balancer
- Security Admin or Compute Security Admin IAM role
Step 1: Create a Cloud Armor Security Policy
Security policies contain rules that evaluate incoming requests:
Via Google Cloud Console
-
- Navigate to [Network Security > Cloud Armor](https://console.cloud.google.com/net-security/securitypolicies)
- Click **Create Policy**
- Configure:
-
Name:
web-app-policy -
Type: Backend security policy
-
Default rule action: Allow (or Deny for allowlist approach)
-
Click Create Policy
Via gcloud CLI
# Create a security policy
gcloud compute security-policies create web-app-policy \
--description="Security policy for web application" \
--project=PROJECT_ID
# Verify creation
gcloud compute security-policies describe web-app-policy --project=PROJECT_IDVia Terraform
resource "google_compute_security_policy" "web_app_policy" {
name = "web-app-policy"
description = "Security policy for web application"
project = var.project_id
# Default rule - allow all traffic
rule {
action = "allow"
priority = 2147483647
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "Default rule - allow all"
}
}Step 2: Add OWASP Top 10 Protection Rules
Enable preconfigured WAF rules for common attack patterns:
Via gcloud CLI
# Block SQL injection attacks
gcloud compute security-policies rules create 1000 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('sqli-v33-stable')" \
--action=deny-403 \
--description="Block SQL injection" \
--project=PROJECT_ID
# Block cross-site scripting (XSS) attacks
gcloud compute security-policies rules create 1100 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('xss-v33-stable')" \
--action=deny-403 \
--description="Block XSS attacks" \
--project=PROJECT_ID
# Block local file inclusion (LFI) attacks
gcloud compute security-policies rules create 1200 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('lfi-v33-stable')" \
--action=deny-403 \
--description="Block LFI attacks" \
--project=PROJECT_ID
# Block remote file inclusion (RFI) attacks
gcloud compute security-policies rules create 1300 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('rfi-v33-stable')" \
--action=deny-403 \
--description="Block RFI attacks" \
--project=PROJECT_ID
# Block remote code execution (RCE) attacks
gcloud compute security-policies rules create 1400 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('rce-v33-stable')" \
--action=deny-403 \
--description="Block RCE attacks" \
--project=PROJECT_ID
# Block protocol attacks
gcloud compute security-policies rules create 1500 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('protocolattack-v33-stable')" \
--action=deny-403 \
--description="Block protocol attacks" \
--project=PROJECT_ID
# Block session fixation attacks
gcloud compute security-policies rules create 1600 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('sessionfixation-v33-stable')" \
--action=deny-403 \
--description="Block session fixation" \
--project=PROJECT_ID
# Block scanners and probes
gcloud compute security-policies rules create 1700 \
--security-policy=web-app-policy \
--expression="evaluatePreconfiguredExpr('scannerdetection-v33-stable')" \
--action=deny-403 \
--description="Block scanners and probes" \
--project=PROJECT_IDVia Terraform
resource "google_compute_security_policy" "web_app_policy" {
name = "web-app-policy"
description = "WAF policy with OWASP protections"
project = var.project_id
# SQL injection protection
rule {
action = "deny(403)"
priority = 1000
match {
expr {
expression = "evaluatePreconfiguredExpr('sqli-v33-stable')"
}
}
description = "Block SQL injection"
}
# XSS protection
rule {
action = "deny(403)"
priority = 1100
match {
expr {
expression = "evaluatePreconfiguredExpr('xss-v33-stable')"
}
}
description = "Block XSS attacks"
}
# LFI protection
rule {
action = "deny(403)"
priority = 1200
match {
expr {
expression = "evaluatePreconfiguredExpr('lfi-v33-stable')"
}
}
description = "Block LFI attacks"
}
# RFI protection
rule {
action = "deny(403)"
priority = 1300
match {
expr {
expression = "evaluatePreconfiguredExpr('rfi-v33-stable')"
}
}
description = "Block RFI attacks"
}
# RCE protection
rule {
action = "deny(403)"
priority = 1400
match {
expr {
expression = "evaluatePreconfiguredExpr('rce-v33-stable')"
}
}
description = "Block RCE attacks"
}
# Default allow
rule {
action = "allow"
priority = 2147483647
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "Default rule"
}
}Step 3: Configure Rate Limiting
Protect against DDoS and brute force attacks with rate limiting:
Via gcloud CLI
# Rate limit by IP address (100 requests per minute)
gcloud compute security-policies rules create 900 \
--security-policy=web-app-policy \
--expression="true" \
--action=rate-based-ban \
--rate-limit-threshold-count=100 \
--rate-limit-threshold-interval-sec=60 \
--ban-duration-sec=600 \
--conform-action=allow \
--exceed-action=deny-429 \
--enforce-on-key=IP \
--description="Rate limit by IP" \
--project=PROJECT_ID
# Rate limit login endpoint more strictly
gcloud compute security-policies rules create 800 \
--security-policy=web-app-policy \
--expression="request.path.matches('/login') || request.path.matches('/api/auth')" \
--action=rate-based-ban \
--rate-limit-threshold-count=10 \
--rate-limit-threshold-interval-sec=60 \
--ban-duration-sec=3600 \
--conform-action=allow \
--exceed-action=deny-429 \
--enforce-on-key=IP \
--description="Strict rate limit on login endpoints" \
--project=PROJECT_IDVia Terraform
resource "google_compute_security_policy" "web_app_policy" {
name = "web-app-policy"
# Global rate limiting
rule {
action = "rate_based_ban"
priority = 900
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
rate_limit_options {
conform_action = "allow"
exceed_action = "deny(429)"
enforce_on_key = "IP"
rate_limit_threshold {
count = 100
interval_sec = 60
}
ban_duration_sec = 600
}
description = "Rate limit by IP"
}
# Stricter rate limiting on auth endpoints
rule {
action = "rate_based_ban"
priority = 800
match {
expr {
expression = "request.path.matches('/login') || request.path.matches('/api/auth')"
}
}
rate_limit_options {
conform_action = "allow"
exceed_action = "deny(429)"
enforce_on_key = "IP"
rate_limit_threshold {
count = 10
interval_sec = 60
}
ban_duration_sec = 3600
}
description = "Strict rate limit on auth endpoints"
}
}Step 4: Enable Adaptive Protection
Adaptive Protection uses machine learning to detect and mitigate L7 DDoS attacks:
Via gcloud CLI
# Enable adaptive protection
gcloud compute security-policies update web-app-policy \
--enable-layer7-ddos-defense \
--layer7-ddos-defense-rule-visibility=STANDARD \
--project=PROJECT_IDVia Console
-
- Navigate to your security policy
- Click **Edit**
- Under **Adaptive Protection**, toggle **Enable**
- Set rule visibility to **Standard** or **Premium**
- Click **Update**
Via Terraform
resource "google_compute_security_policy" "web_app_policy" {
name = "web-app-policy"
adaptive_protection_config {
layer_7_ddos_defense_config {
enable = true
rule_visibility = "STANDARD"
}
}
}Step 5: Add Geographic Restrictions
Block or allow traffic based on geographic location:
Via gcloud CLI
# Block traffic from specific countries
gcloud compute security-policies rules create 500 \
--security-policy=web-app-policy \
--expression="origin.region_code == 'CN' || origin.region_code == 'RU' || origin.region_code == 'KP'" \
--action=deny-403 \
--description="Block traffic from high-risk countries" \
--project=PROJECT_ID
# Allow only specific countries (allowlist approach)
gcloud compute security-policies rules create 600 \
--security-policy=web-app-policy \
--expression="!(origin.region_code == 'US' || origin.region_code == 'CA' || origin.region_code == 'GB')" \
--action=deny-403 \
--description="Allow only US, Canada, UK" \
--project=PROJECT_IDStep 6: Configure Bot Management (reCAPTCHA Enterprise)
Integrate reCAPTCHA Enterprise for bot detection:
Via gcloud CLI
# Add reCAPTCHA action token rule
gcloud compute security-policies rules create 700 \
--security-policy=web-app-policy \
--expression="request.path.matches('/api/submit') && token.recaptcha_action.score < 0.5" \
--action=deny-403 \
--description="Block low-score reCAPTCHA requests" \
--project=PROJECT_IDStep 7: Attach Policy to Backend Service
Apply the security policy to your load balancer backend:
Via gcloud CLI
# Attach to backend service
gcloud compute backend-services update my-backend-service \
--security-policy=web-app-policy \
--global \
--project=PROJECT_IDVia Console
-
- Navigate to [Load Balancing](https://console.cloud.google.com/net-services/loadbalancing)
- Click on your load balancer
- Click **Edit**
- Select the backend service
- Under **Security**, select your Cloud Armor policy
- Click **Update**
Via Terraform
resource "google_compute_backend_service" "web_backend" {
name = "web-backend-service"
protocol = "HTTP"
timeout_sec = 30
load_balancing_scheme = "EXTERNAL"
security_policy = google_compute_security_policy.web_app_policy.self_link
backend {
group = google_compute_instance_group_manager.web_group.instance_group
}
health_checks = [google_compute_health_check.web_health.id]
}Step 8: Monitor and Review Logs
Set up logging and monitoring for Cloud Armor events:
View Logs in Cloud Logging
# View Cloud Armor logs
gcloud logging read "resource.type=http_load_balancer AND jsonPayload.enforcedSecurityPolicy.name=web-app-policy" \
--limit=50 \
--project=PROJECT_IDCreate Log-Based Metrics
-
- Navigate to [Logging > Log-based metrics](https://console.cloud.google.com/logs/metrics)
- Click **Create Metric**
- Configure:
-
Metric type: Counter
-
Name:
cloud_armor_blocked_requests -
Filter:
jsonPayload.enforcedSecurityPolicy.outcome="DENY" -
Click Create Metric
Create Alerting Policy
-
- Navigate to [Monitoring > Alerting](https://console.cloud.google.com/monitoring/alerting)
- Click **Create Policy**
- Use the log-based metric as condition
- Set threshold (e.g., >1000 blocked requests in 5 minutes)
- Configure notification channels
Best Practices Summary
- Enable OWASP rules first - Start with preconfigured rules for baseline protection
- Use preview mode for testing - Test rules before enforcing to avoid blocking legitimate traffic
- Implement layered rate limiting - Global limits plus stricter limits on sensitive endpoints
- Enable Adaptive Protection - ML-based detection for L7 DDoS attacks
- Monitor blocked requests - Regular review of what's being blocked
- Tune rules over time - Adjust thresholds based on traffic patterns
- Combine with VPC firewalls - Defense in depth at multiple layers
Related Resources
- 30 Cloud Security Tips for 2026 - Comprehensive cloud security guide
- GCP VPC Network Segmentation - Network security architecture
- Enable Cloud Audit Logs - Comprehensive logging
- Cloud Armor Documentation
- WAF Rule Tuning Guide
Need help implementing Cloud Armor policies for your applications? Contact InventiveHQ for expert guidance on web application security and DDoS protection.