Markdown source

JA4 in WAF Rules — Cloudflare and Google Cloud Armor Markdown source

Readable source view for humans. The raw Markdown endpoint remains available for crawlers and agent readers.

---
title: "JA4 in WAF Rules — Cloudflare and Google Cloud Armor"
description: "JA4 in WAF rules explained: Cloudflare exposes JA4 to Bot Management, Google Cloud Armor matches origin.tls_ja4_fingerprint, and rules need null-safe handling."
kind: article
maturity: budding
confidence: high
origin: ai-drafted
author: "Agent"
directedBy: "krow"
tags: [security, fingerprinting, bot-detection, ja4, cloudflare]
published: 2026-06-24
modified: 2026-06-25
wordCount: 1254
readingTime: 6
prerequisites: [ja4-vs-ja3]
related: [ja4-vs-ja3, ja4-plus-fingerprint-suite, cloudflare-ja3-ja4-bot-detection, bot-detection-2026, ja4t-tcp-fingerprinting]
url: https://krowdev.com/article/ja4-waf-rules-cloudflare-google-cloud-armor/
---
## Agent Context

- Canonical: https://krowdev.com/article/ja4-waf-rules-cloudflare-google-cloud-armor/
- Markdown: https://krowdev.com/article/ja4-waf-rules-cloudflare-google-cloud-armor.md
- Full corpus: https://krowdev.com/llms-full.txt
- Kind: article
- Maturity: budding
- Confidence: high
- Origin: ai-drafted
- Author: Agent
- Directed by: krow
- Published: 2026-06-24
- Modified: 2026-06-25
- Words: 1254 (6 min read)
- Tags: security, fingerprinting, bot-detection, ja4, cloudflare
- Prerequisites: ja4-vs-ja3
- Related: ja4-vs-ja3, ja4-plus-fingerprint-suite, cloudflare-ja3-ja4-bot-detection, bot-detection-2026, ja4t-tcp-fingerprinting
- Content map:
  - h2: Quick Reference
  - h2: What JA4 gives a WAF rule
  - h2: Cloudflare JA4 rules need null-safe handling
  - h2: Google Cloud Armor matches explicit JA4 values
  - h2: JA4 vs JA4T and HTTP/2 in WAF decisions
  - h2: Safe rule patterns
  - h2: Sources
- Crawl policy: same canonical content is exposed through HTML, Markdown, and llms-full; no crawler-specific content gate.

JA4 in WAF rules means using the TLS ClientHello fingerprint as a match key, not treating it as a complete bot verdict. Cloudflare exposes JA4 inside Bot Management, while Google Cloud Armor lets a custom rule compare `origin.tls_ja4_fingerprint` against a known value such as `t13d1516h2_8daaf6152771_b186095e22b6`. The wider [JA4+ fingerprint suite](/article/ja4-plus-fingerprint-suite/) explains where JA4S, JA4H, JA4X, JA4L, JA4SSH, and JA4T fit around that TLS signal.

Last verified: 2026-06-25 against Cloudflare Bot Management documentation, Google Cloud Armor custom rules documentation, and the FoxIO JA4 technical details.

## Quick Reference

| Platform | Field or surface | Example | Operational takeaway |
|---|---|---|---|
| Cloudflare Bot Management | JA3 / JA4 fingerprint plus `ja4Signals` | `ja4Signals.browser_ratio_1h`, `reqs_quantile_1h` | Treat JA4 as one bot signal; handle missing fields and empty signal arrays |
| Google Cloud Armor | `origin.tls_ja4_fingerprint` | `origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'` | Match a single known JA4 or a small explicit list in custom rules |
| FoxIO JA4 | Three-part TLS fingerprint | `t13d1516h2_8daaf6152771_b186095e22b6` | Decode protocol, TLS version, SNI, cipher count, extension count, ALPN, cipher hash, and extension hash |
| Detection policy | Cross-layer score | JA4 + JA4T + HTTP/2 + headers + behavior | Avoid blocking on JA4 alone unless the fingerprint is already known-bad in local telemetry |

The search-intent trap is simple: a JA4 value looks exact enough to block, but the fingerprint only describes the TLS handshake. A good WAF rule asks whether that handshake is consistent with the request, reputation, account state, and [bot-detection stack](/article/bot-detection-2026/).

## What JA4 gives a WAF rule

[JA4 TLS fingerprinting](/article/ja4-vs-ja3/) summarizes a TLS or QUIC client hello into a stable, shareable string. The first segment keeps human-readable metadata: transport (`t`, `q`, or `d`), TLS version, SNI presence, cipher count, extension count, and ALPN. The second and third segments are truncated SHA-256 hashes of sorted cipher and extension material.

That sorted design is the difference from JA3. JA3 hashes the ClientHello mostly as observed, so extension-order randomization can explode one browser family into many fingerprints. JA4 sorts the cipher and extension lists before hashing, which makes the signal easier to group across modern browsers that deliberately randomize order.

A WAF rule can use JA4 for three jobs:

- **Known-bad blocking:** deny traffic from a JA4 already tied to abuse in local logs.
- **Allow-list precision:** let a trusted integration through only when the TLS fingerprint also matches the expected client stack.
- **Risk scoring:** add weight when JA4 conflicts with the claimed browser, HTTP/2 fingerprint, ASN, IP reputation, or session behavior.

The third pattern is usually safest. A real browser, headless browser, mobile app, and bot framework can share parts of a network path. JA4 narrows the candidate set; it does not prove intent.

## Cloudflare JA4 rules need null-safe handling

Cloudflare documents JA3 and JA4 as SSL/TLS-based identifiers available to Enterprise customers with Bot Management. The same page notes that JA4 improves on JA3 by sorting ClientHello extensions, reducing unique fingerprints for modern browsers and making grouping easier.

Cloudflare also documents absence conditions. JA3 or JA4 can be null or empty for non-encrypted HTTP traffic, some Worker-routed flows, requests where Bot Management is skipped, and TLS session resumption cases where the initial handshake has already completed. Cloudflare's sample Workers object shows `ja4Signals` as a structured set of ratios, ranks, and quantiles, but the documentation warns that the JA4 fingerprint and the `ja4Signals` array can both be missing.

That changes rule design. A rule or Worker that assumes every request has `cf.botManagement.ja4` and populated signals will fail open, fail closed, or throw on exactly the edge cases that need careful handling. Null-safe logic should separate three states:

1. JA4 present and matched a local policy value.
2. JA4 absent for a documented transport or routing reason.
3. JA4 absent where the route normally should have one.

Only the third state is suspicious by itself. The first state is a positive match. The second state is an observability limitation that needs another signal.

## Google Cloud Armor matches explicit JA4 values

Google Cloud Armor exposes JA4 in custom rules as `origin.tls_ja4_fingerprint`. The documented single-value example is:

```text
origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
```

The documented list pattern repeats the comparison with `||` for each fingerprint. That shape is intentionally explicit: Cloud Armor rules match known JA4 values, not broad fuzzy families. It works well when the source of truth is a threat-intel list, an incident response query, or a known partner client whose TLS stack is stable.

A useful Cloud Armor deployment flow is:

1. Log candidate fingerprints without blocking.
2. Confirm the JA4 value appears with the same abuse pattern across enough requests.
3. Add a custom rule that denies or rate-limits only the confirmed value.
4. Keep a rollback path because browser and library releases can change TLS behavior.

The same `t13d1516h2_8daaf6152771_b186095e22b6` value appears in FoxIO's JA4 technical details as a representative TLS 1.3, SNI-present, HTTP/2-capable fingerprint. The value is useful in docs because it is recognizable; it should not be copied into a production deny rule unless local telemetry says that exact client is abusive.

## JA4 vs JA4T and HTTP/2 in WAF decisions

JA4 sits at the TLS layer. [JA4T TCP fingerprinting](/article/ja4t-tcp-fingerprinting/) observes the TCP SYN before TLS. [HTTP/2 fingerprinting](/article/http2-fingerprinting-akamai/) observes the SETTINGS frame, WINDOW_UPDATE behavior, PRIORITY behavior, and pseudo-header order after TLS.

Layer mismatch is the practical signal. A request can claim Chrome in `User-Agent`, replay a Chrome-like JA4, but still expose a non-browser TCP stack or HTTP/2 pseudo-header order. The inverse also matters: an enterprise mobile app may have a stable non-browser JA4 while still being legitimate for one API route.

Use JA4 in WAF rules as a join key:

- JA4 groups TLS clients.
- JA4T groups TCP stacks and network paths.
- HTTP/2 fingerprinting groups protocol implementations.
- Header order and Sec-Fetch headers check browser consistency.
- Behavior decides whether the grouped client is abusive.

A rule that combines those layers is harder to evade than a single hash check and less likely to block a legitimate shared fingerprint.

## Safe rule patterns

Start with monitoring rules. Export the JA4 value alongside path, method, status, ASN, country, account state, bot score, and rate-limit decision. Pivot by fingerprint only after the logs show whether one JA4 maps to one actor or a broad client population.

Prefer narrow actions first:

```text
if known_bad_ja4 and login_path then challenge or rate-limit
if known_bad_ja4 and credential_stuffing_score_high then block
if trusted_partner_path and ja4_not_expected then alert
```

Avoid global rules like "block all traffic with this unfamiliar JA4." Unfamiliar means the telemetry set is incomplete. A new browser release, TLS library update, mobile OS change, or CDN path can create fingerprints that look strange for a few days.

JA4 is strongest when it turns a noisy request stream into named clusters. The WAF should still make the final decision from context: endpoint sensitivity, request rate, account history, bot score, and whether the lower and higher protocol layers tell the same story.

## Sources

- [Cloudflare — JA3/JA4 fingerprint](https://developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint/) — Bot Management docs for JA4 availability, extension sorting, `ja4Signals`, and documented missing-field cases.
- [Google Cloud Armor — custom rules language attributes](https://cloud.google.com/armor/docs/rules-language-reference#allow_or_deny_traffic_based_on_a_known_ja4_fingerprint) — `origin.tls_ja4_fingerprint` examples for single JA4 and multi-JA4 matching.
- [FoxIO JA4 technical details](https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md) — canonical JA4 format, sorted cipher/extension hashes, ALPN handling, and representative example fingerprints.
- [JA4 vs JA3: Why TLS Fingerprinting Migrated](/article/ja4-vs-ja3/) — local companion entry explaining the JA4 format and why extension sorting matters.
- [How Websites Detect Bots in 2026](/article/bot-detection-2026/) — local companion entry for cross-layer bot detection context.