Device posture and continuous verification: every request

Device posture deep dive for Zero Trust: WARP checks (OS, disk encryption, firewall), EDR integration, continuous verification in Access policy, and response to posture loss.

· 14 min read · Đọc bản tiếng Việt
Continuous device posture for Zero Trust: 4 signal layers — WARP built-in (OS, disk encryption, firewall), EDR (CrowdStrike/SentinelOne/Defender), MDM (Intune/Jamf), and custom posture providers — evaluated every request

TL;DR

Device posture is the signal about a device’s security state at every request, not just at login. It detects compromise, compliance drift, and stolen devices after the user has authenticated — the core of Zero Trust’s “never trust, always verify”.

Four layers of posture signal:

  • WARP built-in checks — OS version, disk encryption, firewall on, application running.
  • EDR integration — CrowdStrike Falcon, SentinelOne, Microsoft Defender: is the device actively protected in real time?
  • MDM integration — Intune/Jamf: does the device meet the compliance policy?
  • Custom service-to-service — webhook posture providers you define yourself.

This post covers:

  • Why login-time verification isn’t enough.
  • WARP client checks — the native posture signal list.
  • EDR integration setup + failure-mode considerations.
  • Continuous evaluation — Access re-verifying every N minutes.
  • Response playbook — device fails posture → kill session, alert SOC, remediate.
  • Layered posture policy — tiered access by posture level.

The thesis:

Authentication is “who are you?” asked once. Device posture is “what’s the state of your machine?” asked continuously. A user can log in clean at 9am and click malware at 10am — without continuous posture checks, the attacker holds a valid token and Access doesn’t notice. Posture-based continuous verification is the only way to close that loop.

This is Part 16 of the Cloudflare One Handbook, closing the Observability & Ops block and opening the Advanced Security block (Parts 17+).


Who this is for

  • Security engineers building Zero Trust policy with device-aware signals.
  • EDR administrators (CrowdStrike, SentinelOne, Defender) who want to feed telemetry into access decisions.
  • Compliance teams that need to prove “verify” happens continuously, not only at login.

Recommended prior reading:

After this post you will:

  • Know the list of native posture checks WARP provides.
  • Configure EDR integrations (CrowdStrike ZTA, SentinelOne, Defender).
  • Write Access policies that use posture conditions.
  • Design a response when a device fails posture mid-session.
  • Tier access by posture level (corporate-managed > BYOD managed > BYOD unmanaged).

What this post does not cover

  • Endpoint protection vendor comparison in depth — only the integration angle.
  • MDM (Intune/Jamf) policy design in detail — separate post.
  • Full SOC response playbooks — briefly mentioned.
  • Compliance framework detail (CIS, NIST 800-171) — mapping only.
  • UEBA (User Entity Behavior Analytics) — different dataset, briefly mentioned.

Concepts

  • Posture — the security state of a device at evaluation time: OS version, disk encrypted, firewall on, EDR agent running, compliance state.
  • Posture provider — the source that emits the signal. Native (WARP), SaaS (EDR vendor), or custom (webhook).
  • Posture check — a rule combined with a provider signal. E.g. “CrowdStrike ZTA score ≥ 50”.
  • Continuous evaluation — Access re-checking posture every N minutes or per request, not only at login.
  • Access policy — the rule that gates device access to an app, potentially including posture conditions.
  • EDR — Endpoint Detection and Response: CrowdStrike, SentinelOne, Defender for Endpoint, Carbon Black, Cortex XDR.
  • ZTA (Zero Trust Assessment) — CrowdStrike’s name for their posture score.
  • Session token — the JWT issued by Access after login + policy pass; valid 15min–24h.

Why login-time verification isn’t enough

Timeline attack scenario: 9:00 user logs in clean, posture check passes, token issued valid 8h. 10:30 user clicks a phishing email, malware installs. 11:00 the session is still active and the malware accesses the app with the valid token. Without continuous verification, Access is blind.

Scenario

  • 9:00: Alice logs into Salesforce through Access. Posture check passes (firewall on, OS updated, disk encrypted). Token valid 8 hours.
  • 9:30: Alice is working fine. No alerts.
  • 10:30: Alice clicks a phishing email. A dropper runs. A credential stealer calls C2.
  • 10:45: The malware dumps Chrome credentials → SSO token stolen.
  • 11:00: The attacker uses the token, accesses Salesforce from another IP.
  • Classic Access: the session is still valid (within the 8h window). Token verifies OK. The request passes.
  • Continuous posture: CrowdStrike raises an alert → ZTA score drops → Access re-evaluates → policy fails → session killed.

Login-time verify is a snapshot, not continuous

Traditional ZTNA gates at login. A token is issued after auth + checks. That token is reused for every request in its TTL. The token does not carry real-time signals — it only says “at 9am everything was OK”.

The “never trust, always verify” principle only holds if verification happens every request (or at least every N minutes).

Posture signal types

Static signals (checked once or rarely change):

  • OS version.
  • Disk encrypted (BitLocker, FileVault).
  • Serial number / machine ID.
  • Domain-joined.
  • Certificate presence.

Dynamic signals (can change every minute):

  • EDR agent running and healthy.
  • EDR threat score (CrowdStrike ZTA).
  • Firewall active.
  • Required app running (e.g. DLP agent).
  • Network health (secure wifi, not a public AP).

Continuous verification focuses on dynamic signals.


WARP built-in posture checks

List of WARP native posture checks: OS version, domain joined, disk encrypted, firewall on, application running, client certificate, file present, registry key value, serial number matches list.

Native check list

The Cloudflare WARP client collects around 15 signal types:

CheckPlatformExample
OS versionWin, Mac, Linux, iOS, Androidmacos_version >= 14.0
Domain joinedWindowsJoined to the corporate AD
Disk encryptionWin (BitLocker), Mac (FileVault)on/off
Firewallallon/off
Anti-virusWinDefender present
Application presentallChrome installed
Application runningallDLP agent active
File presentall/etc/corp-config.ini exists
File hashallSHA256 matches expected
Registry keyWinKey value matches
Serial numberallIn approved list
CertificateallCert issued by corp CA present
MDM compliantIntune, JamfCompliant flag
Client versionWARPMinimum version
Tamper-proofWARPWARP binary not modified

Example configuration

posture_check:
  name: "corp-required-baseline"
  platforms: ["windows", "macos"]
  checks:
    - type: os_version
      operator: ">="
      value: "windows 10 build 19045"  # or macos 14.0
    - type: disk_encryption
      value: "on"
    - type: firewall
      value: "on"
    - type: application_present
      application: "com.crowdstrike.falcon.agent"
    - type: serial_number
      list: "$corp-serial-approved"  # UUID list from MDM export

Evaluation frequency

  • The WARP client runs checks every 30 seconds (configurable 30s–30m).
  • Results push to the CF Access evaluator.
  • Access re-checks posture at each session refresh (configurable, 1h default).

For continuous verification, reduce the token TTL to 15–30 minutes → posture is re-checked on every refresh.


EDR integration

EDR integration diagram: CrowdStrike Falcon cloud, SentinelOne cloud, Microsoft Defender cloud push posture via API to Cloudflare Zero Trust. CF evaluates the score/status as a posture signal in Access policy.

Supported EDRs

  • CrowdStrike Falcon ZTA — native integration, posture score 0–100.
  • SentinelOne — device health status via API.
  • Microsoft Defender for Endpoint — compliance via the Graph API.
  • Tanium — agent compliance.
  • Carbon Black — custom via API.

CrowdStrike ZTA integration

  1. CrowdStrike dashboard → API Clients → create a client with scope ZTA:read.
  2. Cloudflare Zero Trust → Settings → Device posture → Add integration → CrowdStrike → enter the API credentials.
  3. CF pulls the ZTA score every 5 minutes per enrolled device.
  4. Use in policy:
posture_check:
  name: "CrowdStrike healthy"
  type: crowdstrike
  zta_score_minimum: 70
  overall_status: "pass"

ZTA score interpretation:

  • 70–100: Green — healthy, minimal risk.
  • 40–69: Yellow — some concern.
  • 0–39: Red — active threat detected.

Microsoft Defender integration

Requires Azure AD + Intune context. The Intune compliance signal is exposed via the Graph API.

posture_check:
  name: "Intune compliant"
  type: intune
  compliance_status: "compliant"

SentinelOne integration

posture_check:
  name: "SentinelOne active"
  type: sentinel_one
  threat_status: "resolved"
  agent_last_active_within: "5m"

Data-flow considerations

  • Latency: EDR cloud → CF polling — a typical 5-minute delay.
  • Availability: EDR cloud outage → CF can’t pull posture → what does the policy do?
    • Fail closed: deny access (strict, Zero Trust pure).
    • Fail open: allow with a warning (lenient).
  • Recommendation: fail closed for critical apps, fail open with elevated logging for general access.

API quota

  • EDR vendors rate-limit the API.
  • 10K devices → ~2K calls/hour for ZTA data.
  • Check the contract quota; upgrade if at scale.

Custom service-to-service posture

Use case

The EDR isn’t natively supported → build custom.

Webhook pattern

Custom posture provider (your service)
  ↓ push
POST https://posture.cloudflareaccess.com/webhook
  { "device_id": "d_xyz", "status": "pass", "score": 85, "timestamp": ... }

Cloudflare validates

Access policy evaluates with the custom signal

Setup

  1. Cloudflare Zero Trust → Device posture → Add integration → Service to service.
  2. Get the webhook URL + API key.
  3. Your service POSTs device state on a regular cadence.

When to use custom

  • Vendor not supported (Trellix, F-Secure, Sophos).
  • Need combined signals (EDR + vulnerability scanner + network hygiene).
  • In-house security tooling.

Continuous evaluation — Access policy

Access continuous evaluation: a token is issued at login; the policy is re-checked every 30 minutes. If posture fails during an active session, the token is revoked and the user is forced to re-auth against the current device state.

Policy pattern

application: "salesforce"
policies:
  - name: "Allow if posture OK"
    action: allow
    include:
      - email_domain: "company.com"
    require:
      - posture:
          name: "corp-required-baseline"
      - posture:
          name: "CrowdStrike healthy"
    session_duration: "30m"  # short TTL = frequent re-check

require = ALL must match. include = any matches.

Short session TTL

  • Default Access session: 24h.
  • Posture-aware: 15–30 minutes for sensitive apps.
  • Each refresh re-evaluates the entire policy, including posture.

Force re-auth on posture change

Cloudflare supports Purge tokens on posture failure (beta at time of writing).

Flow:

  1. Device fails a posture signal.
  2. CF posture evaluator marks the device non-compliant.
  3. The Access token is revoked immediately (not waiting for expiry).
  4. User’s next request → re-auth + re-posture check.
  5. If the device is still bad → deny.

Middleware pattern — Access Workers integration

For ultimate control, pair Access + Cloudflare Workers:

// Worker in front of a critical app
export default {
  async fetch(request, env) {
    const jwt = request.headers.get("cf-access-jwt-assertion");
    const identity = await verifyJWT(jwt, env.AUD);

    // Real-time posture check via API
    const posture = await fetch(
      `https://api.cloudflare.com/client/v4/accounts/${env.ACCOUNT}/devices/${identity.device_id}/posture`,
      { headers: { Authorization: `Bearer ${env.API_TOKEN}` } }
    ).then(r => r.json());

    if (posture.result.crowdstrike_score < 70) {
      return new Response("Posture insufficient", { status: 403 });
    }

    return fetch(`https://origin.corp.internal${new URL(request.url).pathname}`, request);
  }
};

Per-request verification. Expensive (an API call per request), reserve for the highest-risk apps.


Response playbook — posture fails

Response playbook: a device fails a posture signal. Step 1: revoke session tokens. Step 2: notify the user with remediation steps. Step 3: alert the SOC for investigation. Step 4: quarantine the device via MDM. Step 5: verify remediation and restore access.

Immediate actions (automated)

  1. Revoke session — Access token invalidated.
  2. Block new sessions — the user lands on the login page with a posture error.
  3. Log the eventaccess_requests + device_posture_results → SIEM.

Notifications

  1. User: email + WARP popup: “Your device failed a security check. Contact IT to restore access. Error: [specific reason]”.
  2. SOC/IT: PagerDuty alert, especially for EDR red scores (active threat).
  3. Manager: if the issue persists.

Investigation (manual or semi-automated)

  1. SOC: check EDR detail, identify the threat type.
  2. IT: verify the user isn’t compromised (fraud signal, impossible travel).
  3. Isolation: EDR isolates the device from the network if active malware is present.

Remediation

  1. User guided remediation: run AV scan, update OS, re-encrypt disk.
  2. IT verifies remediation: posture signals are re-evaluated.
  3. Access restored automatically once posture improves.

Quarantine via MDM

For confirmed compromise: the MDM wipes the device + re-provisions. Not just a posture block.

Documentation

  • Every posture failure is logged.
  • SOC triage ticket opened per red-score event.
  • Monthly review: false-positive rate, remediation time.

Layered posture — tiered access

Tiered posture access: Tier 1 corporate-managed devices with full posture pass get access to all apps, including high-risk ones. Tier 2 BYOD with baseline posture gets productivity apps. Tier 3 guests or failed posture get only public info.

Not every user needs full posture. Tier by risk:

Tier 1 — Fully managed corporate device

Posture: WARP + EDR + MDM compliant + disk encrypted + firewall + serial in list.

Access: all apps, including crown-jewel systems (production, finance, HR details).

Tier 2 — BYOD with partial posture

Posture: WARP + disk encrypted + firewall (no EDR/MDM).

Access: productivity apps (email, wiki, calendar). No production, no finance system.

Tier 3 — Guest / failed posture

Posture: WARP enrolled only, no deeper checks.

Access: public info only. A login page with remediation help.

Policy example

- application: "prod-admin"
  policies:
    - action: allow
      require:
        - posture: ["corp-baseline", "crowdstrike-green", "mdm-compliant"]

- application: "company-wiki"
  policies:
    - action: allow
      require:
        - posture: ["warp-enrolled", "firewall-on"]

- application: "public-info"
  policies:
    - action: allow
      include:
        - email_domain: "company.com"

A gradual ramp: a user who doesn’t meet high-tier posture can still access lower-tier apps → IT gradually improves the device.


Security considerations

Posture spoofing

A user with local admin can:

  • Fake the WARP posture state.
  • Silently disable the EDR.
  • Modify registry keys.

Mitigations:

  • WARP tamper-proof check: binary integrity verification.
  • EDR self-protection: the agent process can’t be terminated.
  • Combine signals — harder to spoof all at once.
  • Monitor: a device suddenly flipping all-green after prolonged red is suspicious.

EDR agent as an attack target

EDR runs privileged. Bypass = control of the device. A known APT playbook:

  • Disable the EDR service.
  • Uninstall the agent (if admin).
  • Kernel-level rootkit.

Mitigations:

  • EDR tamper protection + self-heal.
  • Alert on agent disconnects > 10 minutes.
  • Combine EDR with behaviour monitoring (make “suddenly healthy” impossible).

Privacy of posture data

Posture checks collect OS, disk state, and app lists — potentially privacy-sensitive, especially on BYOD.

Guidance:

  • Document what’s collected in the privacy notice.
  • BYOD: collect the minimum (OS version, disk encryption, firewall). Skip app inventory.
  • EDR: corporate devices only. EDR on BYOD crosses the privacy line.
  • Retention: posture results 30–90 days maximum.

Fail-open vs fail-closed

EDR cloud outage → CF can’t fetch posture. Decision:

  • Fail closed: deny everything that relies on the EDR signal. Secure but ops impact.
  • Fail open: allow with a warning. Less secure but maintains business continuity.
  • Hybrid: critical apps fail closed; general apps fail open with elevated logging.

Choose per app sensitivity, not globally.

Compliance mapping

  • NIST CSF: PR.AC-1 (identities managed), PR.DS-1 (data at rest protected), PR.IP-12 (vulnerability management).
  • ISO 27001: A.8.1 (asset inventory), A.8.9 (secure configuration), A.8.16 (monitoring).
  • CIS 18: Control 4 (secure configuration of enterprise assets), Control 10 (malware defences).
  • PCI DSS 4.0: 5.x (malware protection), 2.x (secure configuration).

Troubleshooting

”A user fails posture but says the device is OK”

  1. Dashboard → Device posture → per-device → see each check status.
  2. Identify the failing check — a specific signal.
  3. Common causes: EDR agent updating, WARP temporarily disconnected, firewall disabled by another app (Zoom, Teams in dev).
  4. User remediates per the guide → posture re-check in 1–5 minutes → access restored.

”EDR integration isn’t pulling data”

  • Verify the API credentials are still valid (an EDR admin may have rotated them).
  • Check the EDR API quota isn’t exceeded.
  • Cloudflare → integration status page — see the last successful pull.
  • EDR side: verify device enrollment (is the agent registered?).

”Continuous verification is too aggressive; users log out often”

  • Session TTL too short (5 minutes) for normal use.
  • Increase to 30–60 minutes with purge-on-posture-fail instead.
  • Balance: shorter = more secure; longer = less friction.

”Posture check is slow; the login page delays”

  • A synchronous check at login: every check runs serially → slow.
  • Cloudflare runs them in parallel; a slow check is likely a network path to the provider.
  • Reduce the number of login-time checks; do async posture eval post-login.

”EDR false-positive red score on a healthy device”

  • The EDR vendor may flag legitimate corporate software.
  • Add an EDR exclusion (talk to the EDR admin).
  • Temporary policy override: allow the device while investigating.
  • Track the false-positive metric monthly — > 5% = noise.

Trade-offs and design decisions

DecisionOption AOption BRecommendation
Session TTL24h (legacy)15 min (Zero Trust)30–60 min with posture re-check + purge on fail.
EDR fail modeFail openFail closedPer app tier: critical closed, general open + log.
BYOD posture depthFull (EDR)Minimal (firewall + disk)Minimal. EDR on BYOD is a privacy red flag.
Posture providerOne (EDR only)Combine multipleCombine — harder to spoof, more resilient to vendor outage.
RemediationManual ticketAutomated scriptAutomated for common issues (restart EDR), manual for novel.
Quarantine actionMDM lockMDM wipeLock + investigate; wipe only after confirmed compromise and accepted data loss.

Checklist — production continuous posture

Baseline:

  • WARP enrolled on all managed devices.
  • Native WARP checks defined (OS, disk, firewall, serial).
  • Serial list imported from MDM + rotation process.

EDR:

  • EDR integration configured (CrowdStrike, SentinelOne, Defender).
  • API-credential rotation schedule.
  • Fail mode defined per app tier.
  • API-quota monitoring.

Access policy:

  • Tier 1 (corporate) policy with full posture requirement.
  • Tier 2 (BYOD) policy with minimal posture.
  • Tier 3 (guest) policy minimal.
  • Session TTL 30–60 min for critical apps.
  • Purge-on-posture-fail enabled.

Response:

  • Revoke automation validated.
  • User notification template.
  • SOC runbook for red posture.
  • MDM integration for quarantine.
  • Remediation guide published.

Monitoring:

  • Posture results via Logpush → SIEM.
  • Dashboard: pass rate, top failure reasons.
  • Alert: EDR agent disconnect > 10 minutes per user.
  • Alert: posture-fail spike per group.
  • False-positive metric tracking.

Documentation:

  • Privacy notice updated.
  • Explicit BYOD policy.
  • User remediation FAQ.
  • Runbook: “posture fail” triage.

Lessons from practice

  • Start minimal, tighten gradually. Launch with 3–5 checks, add based on data. Overloading day one = user friction + helpdesk load.
  • EDR integration has the biggest ROI. Native checks are static; EDR is dynamic and catches real-time threats. Worth the investment.
  • Shortening session TTL triggers a strong user reaction. 24h → 30 minutes = a helpdesk wave in week one. Communication + phasing matter.
  • BYOD posture depth is thorny. Full checks cross the privacy line. Minimal checks give a weak signal. Tiered access is the sane compromise.
  • EDR vendor outages happen. Define the fail mode beforehand, not during the incident. Test fail open vs closed quarterly.
  • Posture logs contain PII-adjacent data. Retention + access control. Don’t share posture logs broadly.
  • Quarterly posture policy review. New EDR features, new OS versions, new threats → update rules. Stale posture = security theatre.
  • Measure false positives obsessively. Users blocked incorrectly more often than correctly = users find bypasses. 2–3% FP is acceptable; 10%+ means tuning is required.

Summary

Device posture is the “verify” in “never trust, always verify”. Authentication answers “who”; posture answers “what state is the machine in”. Combining them + continuous = real Zero Trust.

Production recipe:

  • WARP native checks as a cheap, broad baseline.
  • EDR integration for dynamic signals (CrowdStrike / SentinelOne / Defender).
  • Custom webhook when a vendor isn’t supported.
  • Short session TTL + purge-on-fail for continuous behaviour.
  • Tiered access by posture level — no one-size-fits-all.

One line to remember:

Authentication is “who?” asked once. Device posture is “are you still trustworthy?” asked every minute. Drop posture and Zero Trust is walking on one leg.

That closes the Observability & Ops block (Parts 14–16).

The series continues with the Advanced Security block: Browser Isolation, CASB, DLP, Email Security (Area 1) — each post digging into one capability.


References

In this series: