☁Zero Trust Onboarding
English
Telegram Cloudflare Docs ↗

Module 3c — Device Posture Checks

Goal: Verify that a device is healthy and trusted — disk encrypted, firewall on, latest OS, running your EDR, company-owned — and use those signals in Access and Gateway policies so only compliant devices reach sensitive resources.

👤 Who does this Security / endpoint team
⏱️ Time ~40 minutes
🎯 You'll finish with Reusable posture checks that gate access, re-evaluated continuously on every request
✋ Before you begin Module 3 done (devices enrolled in Gateway with WARP). Advanced/third-party checks need Enterprise.

🧭 Why posture matters. Identity answers "who is this user?" Posture answers "is the device they're on safe to trust?" Zero Trust needs both. A posture check is a reusable signal you define once and reference across many Access and Gateway policies — and because Cloudflare evaluates it on every request, the moment a device falls out of compliance (firewall off, disk decrypted, OS out of date), its access is cut automatically.

💡 This expands Part E of Module 3. Module 3 added one simple check; here's the full toolkit.


Two kinds of posture check

Type Signal comes from Examples Plan
WARP client checks The Cloudflare One Client on the device Disk encryption, firewall, OS version, file/app present, serial number, client certificate, antivirus Free tier has basics; more on paid
Service provider checks (service-to-service, S2S) A third-party security platform via API CrowdStrike, SentinelOne, Microsoft Intune, Tanium, Carbon Black, Kolide… Enterprise

You build both in the same place and reference them the same way in policies.


Part A — The built-in WARP client checks

These come straight from the Cloudflare One Client — no third-party tools needed.

Check What it verifies Typical OS
Disk encryption Some/all disks are encrypted (BitLocker, FileVault…) Win / macOS / Linux
Firewall A firewall is running Win / macOS
OS version OS is at/above a version (with build/revision granularity) Win / macOS / Linux / iOS / Android
Antivirus (newer, Windows) An antivirus program is present — optionally up to date Win
Application check A specific process is running (e.g. your EDR agent) Win / macOS / Linux
File check A specific file exists (e.g. a compliance marker) Win / macOS / Linux
Domain joined Device is joined to your Microsoft AD domain Win
Device serial number Serial matches your list of company devices Win / macOS / Linux
Unique Client ID Matches an MDM-assigned UUID iOS / Android / ChromeOS / desktop
Client certificate A valid client cert is installed (pins device identity) Win / macOS / Linux / iOS / Android
Require WARP Device is connected via the Cloudflare One Client All
Require Gateway Traffic is flowing through Gateway All

💡 Client certificate power tip: the cert check supports template variables — ${serial_number} and ${device_uuid} — in both the Common Name and the Subject Alternative Name, so you can pin a certificate to a specific device identity.


Part B — Create a WARP client check

Let's build a "disk encrypted" check (repeat the pattern for any check above).

  1. 👉 In the dashboard, go to Settings → WARP Client → Device posture (or Reusable components → Posture checks).
  2. 👉 Click Add new → choose Disk encryption.
  3. ⌨️ Give it a clear name, e.g. Disk encrypted.
  4. 👉 Select the operating systems it applies to.
  5. 👉 Set the check frequency (how often the client re-evaluates it, e.g. every 5 minutes).
  6. 👉 Configure the specifics (for Disk encryption: which disks must be encrypted).
  7. 👉 Click Save.

📺 What you'll see: the check listed under Device posture, evaluating your enrolled devices, each showing compliant / non-compliant.

✅ Checkpoint: your pilot device reports compliant for the check (assuming its disk is actually encrypted).

⭐ Best practice — OS version checks: require the latest version you've already tested, not the absolute newest. A same-day OS release could otherwise lock your whole fleet out the moment it ships.


Part C — Add a third-party (service provider) check (Enterprise)

Feed signals from an EDR/MDM you already run into Cloudflare's access decisions.

  1. 👉 Go to Settings → WARP Client → Device posture → Add new.
  2. 👉 Choose your provider — e.g. CrowdStrike, SentinelOne, Microsoft Intune (Endpoint Manager), Tanium, Carbon Black, Kolide.
  3. 👉 Follow the provider-specific prompts: paste the API credentials / client ID + secret from that platform's admin console so Cloudflare can query device state.
  4. ⌨️ Set the evaluation criteria — e.g. CrowdStrike Zero Trust Assessment (ZTA) score ≥ 50, or Intune compliant = true.
  5. 👉 Save and confirm the integration connects.

💡 How it works: Cloudflare matches the device (by serial, ID, or email) against the provider's API and pulls its risk score / compliance state — so "device is free of threats per CrowdStrike" becomes a condition you can require.

⚠️ Gateway caveat: most service-provider checks work in both Access and Gateway policies, but Tanium is not supported in Gateway policies — only in Access. Plan around that if Tanium is your source of truth.


Part D — Use posture in a policy

A posture check does nothing until a policy references it. Two places:

In an Access policy (per-application) — Module 4

  1. 👉 Access → Applications → your app → Policies → edit/add.
  2. 👉 Add a Require rule → Selector Device Posture → choose your check(s), e.g. Disk encrypted + CrowdStrike ZTA ≥ 50.

In a Gateway network policy (broad) — Module 5

  1. 👉 Gateway → Firewall Policies → Network → Add a policy.
  2. 👉 Selector Device Posture → your check → Action (e.g. Block if non-compliant).

Worked example — "engineers reach production only from a healthy device":

Rule Selector Value
Include IdP Groups Engineering
Require Device Posture Disk encrypted
Require Device Posture Firewall on
Require Device Posture CrowdStrike ZTA ≥ 50

💡 Reusable by design: define Disk encrypted once and add it to as many apps/policies as you like. Update the check, and every policy referencing it updates too — bundle common checks into an Access Group for one-click reuse.


Part E — Continuous re-evaluation (the Zero Trust payoff)

Posture isn't a one-time gate at login. Cloudflare re-checks it on every request, so:

  • If a user disables their firewall or an EDR flags the device mid-session, its access to protected apps is revoked automatically — no waiting for the next login.
  • When they fix it, access is restored on the next successful check.

This is what makes "never trust, always verify" real: trust is re-earned continuously, not granted once.


Part F — Verify

  1. 👉 Dashboard: My Team → Devices → open a device → review its posture signals (compliant / non-compliant per check).
  2. 👉 On the device (CLI):
    warp-cli posture         # lists each posture check and current pass/fail
    
  3. 👉 Test enforcement: on a compliant device, reach a posture-gated app — it works. Then break a signal (e.g. turn off the firewall on a test box) and retry — access should be denied within the re-evaluation window.

✅ Checkpoint: compliant devices pass; a device failing a required check is blocked, and you can see the decision in Logs → Access (or Gateway logs).


✅ Module 3c complete!

You now have:

  • ✅ An understanding of WARP client checks vs service-provider checks
  • ✅ One or more reusable posture checks defined
  • ✅ (Enterprise) A third-party EDR/MDM signal feeding access decisions
  • ✅ Posture required in Access and/or Gateway policies
  • ✅ Confidence that non-compliant devices are cut off continuously, not just at login

Quick troubleshooting

Problem Fix
Device Posture selector missing in a policy Create at least one posture check first (Part B) — the selector only appears afterward
Device shows non-compliant unexpectedly Check the OS scope + criteria (e.g. which disks must be encrypted); confirm the client is a recent version
Third-party check never matches Re-check the API credentials and that Cloudflare can match the device (serial/ID/email) in that platform
Tanium check works in Access but not Gateway Expected — Tanium isn't supported in Gateway policies; use it in Access (Part C)
OS-version check locked everyone out You required a too-new version — set it to the latest you've qualified, not the absolute newest (Part B)
Posture change not reflected Wait for the re-evaluation interval, or toggle the client off/on; verify with warp-cli posture

👉 Next: Module 4 — ZTNA / Access

Put a private app behind Access and require these posture checks for entry.