Introduction to Cloud Armor
Google Cloud Armor is the Layer 3/4 DDoS shield and Layer 7 Web Application Firewall (WAF) that sits in front of External Application Load Balancers, External Proxy Network Load Balancers, and (since 2023) the Global External Application Load Balancer with hybrid Network Endpoint Groups (NEGs) pointing at on-prem or other-cloud backends. It runs on the same edge infrastructure that protects Search, YouTube, and Gmail, which is why DDoS inspection happens at Google's Points of Presence (PoPs) before traffic ever reaches your VPC.
For the PCNE exam, Cloud Armor questions tend to cluster around five themes: which load balancer types it attaches to, the difference between backend security policies and edge security policies, when to choose Standard versus Managed Protection Plus, how Adaptive Protection's Bayesian ML model works, and which rule type (preconfigured OWASP CRS, custom CEL expression, IP/Geo, threat intel feed) solves a given scenario. This note walks through all of them with concrete gcloud commands, API field names, and pricing levers.
Plain-Language Explanation: (Plain English Explanation)
Before diving into security policy JSON, picture Cloud Armor as three different physical things. Each analogy maps to a different feature cluster — DDoS scrubbing, WAF inspection, and adaptive learning — because Cloud Armor is really three products glued together by one policy object.
Think of Cloud Armor as the Bouncer at a Nightclub Door
The Global External Application Load Balancer is the front door. Cloud Armor is the bouncer. IP allow/deny rules are the VIP list and the banned list pinned to the bouncer's clipboard. Geo rules are "no one from this country tonight." Preconfigured WAF rules are the bouncer patting people down for fake IDs (SQL Injection), graffiti spray cans (XSS), and lockpicks (Local File Inclusion). The bouncer never lets these items past the door, so the kitchen staff (your backend services) never even see them. Cloud Armor is the only PCNE security product that runs entirely outside your VPC — the bouncer stands on the sidewalk, not inside the building.
Think of Adaptive Protection as a Hotel Doorman Who Has Worked There for Ten Years
A new bouncer judges every guest individually. A doorman who has watched the lobby for a decade knows the normal tempo: thirty people per minute at 8 p.m., two per minute at 3 a.m., almost always wearing business attire. The moment a bus of two hundred identical-looking people pulls up at 2 a.m., he calls security before they touch the door. Adaptive Protection is that doorman: it builds a Bayesian baseline of your traffic over hours and days, and when an unusual fingerprint appears (same User-Agent, same JA3, same URL path, all 10× normal rate), it emits an alert with a suggested rule you can one-click apply.
Think of a Rate-Based Ban as a Coffee Shop Wi-Fi That Cuts You Off
Your local cafe lets anyone use the Wi-Fi for ninety minutes, then kicks you off for thirty before letting you back. Rate-based ban rules do the same to IPs: if a single source IP sends more than N requests in interval M, ban it from the policy for duration D. Unlike a hard deny, the ban auto-expires, so a legitimate user behind a NAT who briefly burst-clicked gets back in. This is the right tool for scraping, credential-stuffing, and accidental retry storms.
Core Concepts of Cloud Armor
Cloud Armor's data model is small enough to memorise on one page. The exam tests whether you can attach the right object to the right load balancer.
Security Policies, Rules, and Priorities
A security policy is a named container of up to 200 rules, each with a unique priority integer (0 is highest, 2,147,483,647 is lowest). Rules evaluate top-down by priority; first match wins. The default rule at priority 2147483647 is auto-created and you can flip it between allow and deny(403) — most production policies set the default to allow and rely on explicit deny rules above it (allow-list policies invert this).
Backend Security Policy versus Edge Security Policy
Two policy types attach to different layers:
- Backend security policy — attaches to a backend service or backend bucket. Sees the decrypted HTTP request including headers, body, and decoded URI. This is where WAF/OWASP CRS rules and CEL expressions live.
- Edge security policy — attaches to a backend bucket or Cloud CDN cache backend service. Evaluated at Google's edge before a cache lookup, which means it can block traffic from ever hitting the cache, never mind the origin. Edge policies are simpler — only IP/CIDR, Geo, and request method match; no body inspection.
Backend buckets can have both an edge policy and a backend policy. Edge policy runs first.
Match Conditions: Basic, Advanced, and Preconfigured
Each rule has a match block:
- Basic match — list of up to 10 IP ranges (
srcIpRanges). - Advanced match (CEL expression) — one Common Expression Language string up to 2048 characters referencing
request.headers[...],origin.region_code,request.path,request.query,request.method,inIpRange(origin.ip, '...'), etc. - Preconfigured expression set — a one-liner alias like
evaluatePreconfiguredExpr('sqli-v33-stable')that expands to the bundled OWASP ModSecurity Core Rule Set.
CEL is the rule expression language used by Cloud Armor's advanced match block. A single rule may contain one CEL expression up to 2048 characters; complex policies often split logic across multiple rules to stay under the limit. Reference: https://cloud.google.com/armor/docs/rules-language-reference
Preconfigured WAF Rules and the OWASP ModSecurity CRS
The preconfigured rules are Cloud Armor's WAF brain. They are a curated subset of the OWASP ModSecurity Core Rule Set (CRS), tuned by Google to reduce false positives at edge scale.
The Rule Families You Must Memorise
sqli-v33-stable— SQL Injection (~40 sub-rules).xss-v33-stable— Cross-Site Scripting.lfi-v33-stable— Local File Inclusion (../../etc/passwd).rfi-v33-stable— Remote File Inclusion.rce-v33-stable— Remote Code Execution.methodenforcement-v33-stable— block unusual HTTP verbs.scannerdetection-v33-stable— Nmap, Nikto, sqlmap fingerprints.protocolattack-v33-stable— HTTP request smuggling, response splitting.sessionfixation-v33-stable— cookie/session abuse.cve-canary— fast-track signatures for in-the-wild CVEs (Log4Shell, Spring4Shell).
Sensitivity Levels and Opt-In Signatures
Each preconfigured rule supports four sensitivity levels (1–4). Level 1 fires only on high-confidence matches; level 4 is paranoia mode and will block a lot of legitimate traffic. The default is 1. You can also opt_in_rule_ids=['owasp-crs-v030301-id942110-sqli'] to add specific signatures from a higher level without flipping the whole rule to that level — useful when you trust the family except for one over-eager subrule.
Preview Mode and Tuning
--preview on a rule causes matches to log to Cloud Logging with enforcedAction: "allow" and previewedAction: "deny", so you can measure false positives before flipping the switch. The exam loves to ask the canonical safe rollout: deploy in preview, watch cloudaudit.googleapis.com and requests logs for a week, tune opt_out_rule_ids for noisy signatures, then remove --preview.
A single backend security policy can hold at most 200 rules and each preconfigured WAF rule counts as 1 rule even though it expands to dozens of subrules under the hood. If you need more, split into multiple backend services or use Managed Protection Plus which raises the limit. Reference: https://cloud.google.com/armor/quotas
Custom Rules with Common Expression Language (CEL)
When preconfigured rules and IP/Geo blocks aren't enough, CEL gives you a tiny query language to write custom matchers.
Useful CEL Patterns
request.headers['user-agent'].contains('BadBot')— block by header substring.request.headers['user-agent'].matches('(?i)curl|wget|python-requests')— regex match, case-insensitive.origin.region_code == 'CN' || origin.region_code == 'RU'— geo-block by ISO 3166-1 alpha-2.inIpRange(origin.ip, '203.0.113.0/24')— CIDR membership.request.path.startsWith('/admin/') && !inIpRange(origin.ip, '10.0.0.0/8')— admin-only-from-office.int(request.headers['content-length']) > 8192— block oversized POST bodies.has(request.headers['x-forwarded-for'])— header presence.token.recaptcha_action.score < 0.5— reCAPTCHA Enterprise score gate.
CEL Limitations
One CEL expression per rule, max 2048 characters. No loops, no recursion, no calling external APIs. Body inspection requires JSON parsing rules to be enabled separately (jsonParsing: STANDARD) and adds latency — disable on hot paths.
Combining CEL with Preconfigured Sets
A common production pattern: priority 1000 = evaluatePreconfiguredExpr('sqli-v33-stable') action=deny(403); priority 1100 = custom CEL inIpRange(origin.ip, 'corp-cidr') action=allow to whitelist your office above the WAF for testing. Because rules are first-match, the office IP gets the allow before the WAF rule even evaluates.
Rate-Based Ban and Throttle Actions
Beyond allow/deny, Cloud Armor supports two rate-aware actions for layer 7 flood mitigation.
Throttle (rate_based_throttle)
Once a key exceeds N requests per interval, additional requests get deny(429) until the rate drops below the threshold. The key can be IP, header value, regional IP (/24), HTTP path, or X-Forwarded-For first IP — set with enforceOnKey. Throttling is reactive and per-request; it returns 429 immediately on excess.
Rate-Based Ban (rate_based_ban)
Same trigger, but once the threshold is crossed the key is banned for a fixed banDurationSec (typically 600). During the ban, every request from that key is dropped without re-evaluating the rate. This is more efficient at edge scale and works better against scrapers that ramp up over hours.
Picking a Key
enforceOnKey: ALL (single global counter) is rarely what you want — one rogue IP poisons the counter for everyone. IP is the default. XFF_IP is correct when you front Cloud Armor with another CDN that injects X-Forwarded-For. HTTP_HEADER keyed on a session cookie is the right answer for "rate-limit logged-in users to 5 requests/sec each."
For brute-force login protection on /login, combine a rate_based_ban keyed on XFF_IP (300 requests / 60 seconds / ban 600 seconds) with a CEL match request.path == '/login' && request.method == 'POST'. This bans the offending IP from /login only — other paths stay accessible. Reference: https://cloud.google.com/armor/docs/rate-limiting-overview
Adaptive Protection (Bayesian ML)
Adaptive Protection is the per-backend-service ML system that learns "normal" traffic shape and flags Layer 7 DDoS anomalies. It is enabled per security policy with --enable-layer7-ddos-defense and requires Managed Protection Plus on the project to actually emit suggested rules.
How the Bayesian Model Works
For each protected backend service, the model continuously samples request features (URL path, User-Agent, JA3 TLS fingerprint, source ASN, Accept-Language, geo, header counts) and builds a probability distribution of normal traffic. When live traffic deviates more than a threshold, Adaptive Protection emits an attack event to Cloud Logging containing:
- A confidence score 0.0–1.0 (Google recommends action at ≥ 0.7).
- An "attack signature" — a CEL-shaped expression that captures the malicious cohort.
- An "impacted baseline" — what fraction of legitimate traffic the signature would also block.
- A one-click "apply suggested rule" button.
The signature lands in your security policy as a preview rule by default so you can verify before enforcing.
Telemetry and Tuning
Adaptive events appear in networksecurity.googleapis.com/dos_attack_mitigations and stream to Pub/Sub via Security Command Center. The training window is hours-to-days, so a brand-new backend gets weak signatures until baseline data accumulates. The model is per-backend-service, not per-policy — attaching one policy to 10 backend services means 10 independent baselines.
Adaptive Protection requires the Managed Protection Plus tier on the project and the policy must be a backend security policy (not edge). Standard tier still gets Layer 3/4 DDoS protection for free but loses Adaptive Protection, preconfigured WAF, and the DDoS bill protection guarantee. Reference: https://cloud.google.com/armor/docs/managed-protection-overview
Managed Protection Tiers: Standard vs Plus
Cloud Armor has two tiers and the difference is on every PCNE exam.
Standard (free, pay-as-you-go)
Included with any External Application Load Balancer. Gets always-on Layer 3/4 DDoS protection at the edge. You pay $0.75 per policy per month and $0.75 per million requests evaluated. WAF preconfigured rules and custom CEL are available but billed per evaluation. No Adaptive Protection. No DDoS bill protection.
Managed Protection Plus (subscription)
Annual subscription, $3,000 USD/month for the first 100 protected resources (backend services + backend buckets) with included WAF and Adaptive Protection. Adds:
- Adaptive Protection — the Bayesian L7 model.
- DDoS bill protection — if a verified DDoS attack causes egress / LB cost spikes, Google credits the overage.
- DDoS response team access for active attack support.
- WAF rules and Adaptive Protection at no per-request cost (covered by the subscription).
- Curated threat intelligence feeds (Tor exit nodes, public-cloud egress IPs, known bad ASNs, search engine crawlers).
When to Recommend Plus
Plus pays for itself the moment you have >10 protected resources, run regulated workloads (PCI, HIPAA), or face credible DDoS risk. The exam scenario "the customer is worried about an unbudgeted DDoS-driven bill" is always Plus + bill protection.
Managed Protection Plus is project-scoped — once enabled, every Cloud Armor security policy and every protected backend service or backend bucket in that project inherits Plus features. Cross-project sharing requires Plus on each project separately. The minimum commitment is annual and DDoS bill protection only applies to attacks Google's Security Response team confirms as DDoS. Reference: https://cloud.google.com/armor/docs/managed-protection-overview
Cloud CDN Integration
Cloud CDN sits between the load balancer and the backend. Cloud Armor and Cloud CDN compose in a specific order that matters.
Order of Operations
For a CDN-enabled backend service, every request flows:
- Edge security policy (if attached) — IP/Geo deny at the PoP.
- Cloud CDN cache lookup — if HIT, serve from cache; backend security policy WAF is skipped for cache hits.
- Backend security policy — only runs on cache MISS (origin fetch).
The exam trap: a candidate assumes Cloud Armor inspects every request. With Cloud CDN, WAF only inspects cache misses, which is usually 5–20 % of requests. This is fine for performance but means you must use an edge policy for blanket IP / Geo blocks, otherwise a poisoned cache entry could be served to attackers from the wrong country.
Caching Authenticated Content
When using signedRequestMode: REQUIRE_SIGNATURES, the URL signature is validated by the LB before Cloud Armor evaluates. An attacker without a valid signature gets 403 from the signer, not from Cloud Armor.
IAP Layering and Defense in Depth
Cloud Armor is one layer; the PCNE blueprint expects you to combine it with Identity-Aware Proxy (IAP) and VPC Service Controls.
Cloud Armor + IAP
Both can attach to the same External Application LB. Order: Cloud Armor first (edge), then IAP (in front of backends). A request from a banned IP never reaches IAP, saving auth latency. A request that passes Armor but lacks a Google identity gets the IAP login challenge. Use Armor for "shape-based" filtering (rate, geo, bot) and IAP for "identity-based" filtering (who can access /admin).
Cloud Armor + reCAPTCHA Enterprise
Cloud Armor can ingest reCAPTCHA Enterprise tokens via the token.recaptcha_session.score and token.recaptcha_action.score CEL variables. Pattern: page issues reCAPTCHA token; client attaches it as a header; Cloud Armor rule token.recaptcha_action.score < 0.4 action=deny(403). This catches bots that solve image puzzles but fail behavioural scoring.
Cloud Armor + VPC Service Controls
Cloud Armor protects the public-facing LB. VPC-SC creates a service perimeter around BigQuery, Cloud Storage, etc., so even a compromised workload inside the VPC cannot exfiltrate data outside the perimeter. The two solve different problems but are usually deployed together for regulated workloads.
Cloud Armor does not attach to Internal Application Load Balancers, Internal Passthrough Network Load Balancers, or External Passthrough Network Load Balancers (TCP/UDP). For internal traffic protection, use VPC firewall rules + Cloud IDS. The PCNE exam exploits this — a question describing "internal microservice DDoS protection with Cloud Armor" is wrong by construction. Reference: https://cloud.google.com/armor/docs/cloud-armor-overview#deployment_options
Hybrid NEG and Multi-Cloud Backend Support
A 2023 capability that the PCNE exam now tests: Cloud Armor protects backends that are not on Google Cloud.
Hybrid Connectivity NEGs
A hybrid NEG points at an on-prem or other-cloud endpoint (IP:port reachable via Cloud Interconnect, Cloud VPN, or even public internet). Attach it to a backend service of a Global External Application LB, attach Cloud Armor, and you get Google-scale WAF + DDoS in front of your AWS or on-prem app without rehosting it.
Internet NEGs
Similar concept, but the endpoint is an arbitrary FQDN on the public internet (e.g., legacy.example.com). Cloud Armor sees the request, applies WAF, and proxies to the FQDN over HTTPS. Useful as a security shim in front of SaaS endpoints you don't control.
Caveats
Hybrid NEG traffic still pays egress to leave Google's network. The backend's TLS cert must be valid (or you set --insecure which the exam discourages). And Adaptive Protection works fine — it learns the request shape regardless of where the origin lives.
IP Allow/Deny Lists and Threat Intel Feeds
The simplest rule type, but the exam still asks about quotas and feed names.
IP/CIDR Lists
Each rule's srcIpRanges accepts up to 10 entries. For more, use multiple rules or upgrade to named IP lists (Managed Protection Plus) which support up to 10,000 entries per list. Named lists are referenced by name and updated independently of policy rules — useful for SOC-managed blocklists.
Geo Match
origin.region_code returns ISO 3166-1 alpha-2. You can also match by origin.asn for ASN-based blocks. Note: Cloud Armor uses MaxMind's GeoIP data, which is ~95–98 % accurate — VPN and mobile carrier IPs sometimes geolocate wrong.
Threat Intelligence Feeds (Plus only)
Curated lists Google maintains and you reference via evaluateThreatIntelligence('FEED_NAME'):
iplist-tor-exit-nodes— Tor exit nodes.iplist-known-malicious-ips— Google-curated bad IPs.iplist-public-clouds— AWS, Azure, OCI, etc. (block compute-originated scraping).iplist-vpn-providers— known VPN providers.iplist-search-engines— allow-list crawlers.
These update continuously and remove the burden of maintaining your own blocklists.
Logging, Telemetry, and Troubleshooting
When a legitimate user gets blocked, Cloud Logging is your only friend.
Where Logs Land
Cloud Armor logs are part of the Load Balancer's request logs in loadbalancing.googleapis.com/requests. Each log entry includes enforcedSecurityPolicy.name, enforcedSecurityPolicy.outcome (ACCEPT/DENY), enforcedSecurityPolicy.priority (matched rule), and previewedSecurityPolicy when running in preview. To get every match (not just blocks), enable verbose logging on the backend service.
Cloud Audit Logs
Policy mutations (create, update, delete rule) are recorded in cloudaudit.googleapis.com/activity. Required for SOC 2 / ISO 27001 evidence.
Useful gcloud Commands
# Create a backend security policy
gcloud compute security-policies create prod-waf \
--description="Prod WAF for App LB"
# Add a preconfigured SQLi rule in preview
gcloud compute security-policies rules create 1000 \
--security-policy=prod-waf \
--expression="evaluatePreconfiguredExpr('sqli-v33-stable')" \
--action=deny-403 \
--preview
# Attach to a backend service
gcloud compute backend-services update prod-bes \
--security-policy=prod-waf --global
# Enable Adaptive Protection
gcloud compute security-policies update prod-waf \
--enable-layer7-ddos-defense
Common Pitfalls and Trade-offs
The exam loves the edge cases. The big ones:
- WAF skips cache hits. Combine an edge policy with the backend policy for full coverage on Cloud CDN backends.
- Rule priority gaps matter. Leave space (use 1000, 2000, 3000 …) so you can insert without renumbering.
- CEL 2048-character cap. Long expressions get rejected at policy update time, not at rule creation — test in preview first.
enforceOnKey: ALLfor rate-based ban turns one rogue IP into a self-DDoS. Always pickIPorXFF_IP.- Adaptive Protection latency. Suggestions take hours of baseline data; do not expect protection on day 1.
- Plus tier minimum commitment is annual. Switching from Standard mid-attack does not retroactively grant bill protection.
Best Practices for Cloud Armor Deployments
A production-grade Cloud Armor rollout from a PCNE-aligned reference architecture:
Policy Layout
- One backend security policy per backend service (no shared mega-policy).
- One edge security policy per public Cloud CDN backend bucket.
- Reserved priority ranges: 0–999 allow-list (corp IPs, health checkers), 1000–1999 WAF preconfigured, 2000–2999 custom CEL, 3000–3999 rate-based ban, 9000–9999 geo and threat feeds, default rule allow.
Rollout Discipline
- Every new rule lands in
--previewmode. - Watch logs for 7 days minimum.
- Tune
opt_out_rule_idsfor false-positive signatures. - Remove
--preview, monitor 24 h, then proceed to the next rule.
Observability
- Stream LB request logs to BigQuery for SQL-driven incident review.
- Send Adaptive Protection alerts to Pub/Sub → PagerDuty.
- Dashboard the metrics
loadbalancing.googleapis.com/https/request_countfiltered byenforcedSecurityPolicy.outcome=DENY.
Real-World Use Case: Black Friday DDoS Defence
A retail customer faces a credential-stuffing attack mixed with a Layer 7 HTTP flood on Black Friday. The PCNE-correct architecture:
- Global External Application LB with Cloud CDN enabled on
/static/*, origin inus-central1andeurope-west1. - Edge security policy on the CDN backend bucket: deny all traffic from
origin.region_codenot in the retailer's shipping countries. - Backend security policy with Managed Protection Plus:
- Priority 1000:
evaluatePreconfiguredExpr('sqli-v33-stable')deny. - Priority 1100:
evaluatePreconfiguredExpr('xss-v33-stable')deny. - Priority 2000: rate-based ban on
/login(300 req/60 s, ban 600 s), keyed onXFF_IP. - Priority 3000:
evaluateThreatIntelligence('iplist-tor-exit-nodes')deny. - Priority 9000: Adaptive Protection auto-suggestions (preview → enforce on approval).
- Priority 1000:
- IAP in front of the
/adminpath for SSO + 2FA. - reCAPTCHA Enterprise on
/checkoutwith CEL gate at score < 0.4.
When the attack starts, Adaptive Protection flags a 0.92-confidence signature within minutes; the on-call applies it as enforce; Cloud Logging shows the deny rate spike; bill protection covers the legitimate-traffic egress overage caused by the LB serving 429s.
Exam Tips for Cloud Armor
Things that come up repeatedly on PCNE Cloud Armor questions:
- Cloud Armor attaches to External Application LB and External Proxy Network LB only. Internal LBs and Passthrough LBs are wrong answers.
- Preconfigured WAF rules are based on OWASP ModSecurity CRS v3.3, not OWASP Top 10 (the Top 10 is a category list, CRS is the actual signature pack).
- Edge security policies are restricted to IP, Geo, and HTTP method — no body inspection.
- Adaptive Protection requires Managed Protection Plus and a backend policy.
- DDoS bill protection is a Plus-tier feature; Standard tier still gets DDoS scrubbing but no cost guarantee.
- Cloud CDN cache hits bypass the backend security policy; use edge policy for blanket blocks.
- Rate-based ban keys default to
IP; for clients behind another CDN, switch toXFF_IP. - Hybrid NEGs let Cloud Armor protect on-prem and other-cloud backends, including AWS.
Frequently Asked Questions (FAQ)
What's the difference between a backend security policy and an edge security policy?
Backend policies attach to backend services or backend buckets and run after Cloud CDN cache lookup — they support full WAF, CEL, and rate-based ban. Edge policies attach to backend buckets or CDN-enabled backend services and run at Google's PoP before the cache, supporting only IP, Geo, and HTTP method matches. Use edge for blanket geo-blocks that should also stop poisoned cache hits; use backend for OWASP signatures.
When should I use Managed Protection Plus instead of Standard?
Switch to Plus when any of these apply: you face credible DDoS risk and need bill protection, you have more than ~10 protected backend services (the subscription floor pays for itself), you want Adaptive Protection's Bayesian ML, you need named IP lists with >10 entries, or you want curated threat intelligence feeds (Tor exit nodes, public clouds, known bad IPs).
Does Cloud Armor inspect request bodies?
Only with jsonParsing: STANDARD enabled on the policy, and only for JSON request bodies up to 8 KB by default (configurable). Inspection adds latency, so the recommended pattern is to enable JSON parsing only on routes that accept JSON POST/PUT (e.g., /api/) and not on static asset paths.
Can Cloud Armor protect a backend that lives on AWS or on-prem?
Yes, via hybrid NEGs (Cloud Interconnect or Cloud VPN) or Internet NEGs (public FQDN). Attach the NEG to a backend service of a Global External Application LB, attach Cloud Armor, and the same WAF + DDoS protection applies. Adaptive Protection works because it learns request shape regardless of origin location.
How does Cloud Armor compose with Cloud CDN?
Edge security policy runs first at the PoP. If the request matches the cache, Cloud CDN serves it directly — the backend security policy never sees cache hits. On cache miss, the request flows to the LB, the backend security policy runs (WAF, CEL, rate-based ban), then the origin fetch happens. This means WAF only protects ~5–20 % of cached-content requests; use an edge policy for blanket blocks.
What's the right rate-based ban configuration for login brute-force?
Common production setting: 300 requests per 60 seconds per XFF_IP, ban 600 seconds, scoped via CEL to request.path == '/login' && request.method == 'POST'. This bans only on the login endpoint, uses the X-Forwarded-For IP (correct when fronted by another CDN), and auto-expires so NAT-shared users recover.
Why didn't Adaptive Protection catch my attack on day 1?
Adaptive Protection's Bayesian model needs hours-to-days of baseline traffic per backend service to build a useful normal distribution. A brand-new backend has weak baselines and will under- or over-fire. Run Adaptive Protection in preview for the first few days of any new service to tune the threshold before relying on enforce mode.
How do I troubleshoot a legitimate user blocked by Cloud Armor?
Query Cloud Logging for loadbalancing.googleapis.com/requests filtered on the user's IP. The log entry includes enforcedSecurityPolicy.name, enforcedSecurityPolicy.priority (which rule matched), and enforcedSecurityPolicy.outcome=DENY. Match the priority back to your policy to find the offending rule. If it's a preconfigured WAF rule, use opt_out_rule_ids to exclude the specific signature; if it's a custom CEL rule, refine the match.
Related Topics
- pcne-cloud-cdn — caching strategy and how it composes with Cloud Armor.
- pcne-cloud-load-balancing — which LB types support Cloud Armor and which do not.
- pcne-network-security-best-practices — defence in depth across VPC, IAP, and Cloud Armor.
Further Reading
- Cloud Armor overview: https://cloud.google.com/armor/docs/cloud-armor-overview
- Security policy reference: https://cloud.google.com/armor/docs/security-policy-overview
- Adaptive Protection: https://cloud.google.com/armor/docs/adaptive-protection-overview
- Preconfigured WAF rules: https://cloud.google.com/armor/docs/waf-rules
- Rate limiting: https://cloud.google.com/armor/docs/rate-limiting-overview
- Managed Protection tiers: https://cloud.google.com/armor/docs/managed-protection-overview