Module 3b — Device Profiles Configuration
Goal: Apply different Cloudflare One Client settings to different groups of devices — so managed laptops, BYOD phones, servers, and contractors each get exactly the right mode, split-tunnel, and DNS behavior.
| 👤 Who does this | Endpoint / Desktop team |
| ⏱️ Time | ~30 minutes |
| 🎯 You'll finish with | One or more custom device profiles that automatically apply to the right devices, in the right order |
| ✋ Before you begin | Module 3 complete (at least one device enrolled and Connected) |
This is an optional deep-dive that expands Part B of Module 3. If every device in your org should behave identically, the single Default profile is enough — come back here when you need laptops, BYOD, servers, or contractors to differ.
What a device profile is
A device profile is a named bundle of Cloudflare One Client settings (mode, split tunnels, DNS behavior, switch lock, etc.) plus match rules that decide which devices it applies to. When a device connects, Cloudflare picks one profile for it based on those rules.
There are two layers of settings:
| Layer | Applies to | Examples |
|---|---|---|
| Global device client settings | Every enrolled device, always | Admin override codes, emergency disconnect, local-network-exclusion permission |
| Device profile settings | Only devices that match that profile's rules | Client mode, split tunnels, local domain fallback, auto-connect, switch lock |
📺 Where these live: Zero Trust → Team & Resources → Devices → Device profiles. Profiles are under General profiles. (Older dashboards put this under Settings → WARP Client — same feature.)
⏱️ Heads-up: changes can take up to 10 minutes to reach devices.
The five client modes (decide this per profile first)
The mode is the most important setting in a profile — it decides which Zero Trust features work on that device.
| Mode | What it sends to Cloudflare | Use it for |
|---|---|---|
| Gateway with WARP | DNS and all network traffic (tunnel) | ⭐ Standard for managed devices — full web filtering, DLP, ZTNA, posture |
| Gateway with DoH | DNS only (over HTTPS) | DNS filtering when you can't/don't want to tunnel all traffic |
| Secure Web Gateway (without DNS filtering) | Network traffic, but not DNS | When Cloudflare can't control DNS on the device |
| Proxy mode | HTTP traffic only (via a local proxy) | App/dev scenarios needing selective HTTP filtering |
| Device Information Only | Nothing is proxied — posture signals only | Clientless / Browser Isolation access where you still want device posture |
💡 Tip: Most organizations use Gateway with WARP for managed laptops and Device Information Only (or Include-mode Gateway with WARP) for BYOD.
Part A — Create a device profile
- 👉 Zero Trust → Team & Resources → Devices → Device profiles → General profiles.
- 👉 Click Create new profile.
- 📺 What you'll see: the new profile starts as a copy of your Default profile, so you only change what's different.
- ⌨️ Name the profile clearly, e.g.
BYOD phonesorLinux servers. - 👉 Create the match rules that define which devices get this profile — see Part B.
- 👉 Configure the client settings for these devices (mode, switch lock, auto-connect, etc.).
- 👉 Click Create profile.
- 👉 Back in the list, drag the profile into the right position — order matters (Part C).
✅ Checkpoint: Your new profile appears in the Profile settings list, above the Default profile.
Part B — Match rules (selectors)
Match rules decide which devices use the profile. You build them from selectors, operators, and values.
⚠️ Identity-based selectors (email, groups, SAML) only work if the user enrolled by logging in to your IdP. Service-token-enrolled devices can't match on identity — use OS, managed network, or service token instead.
| Selector | Matches on | Example expression |
|---|---|---|
| User email | A specific user's email | identity.email == "jane@acme.com" |
| User group emails | An IdP group's email address | identity.groups.email == "contractors@acme.com" |
| User group IDs | An IdP group ID | identity.groups.id == "12jf495bhjd..." |
| User group names | An IdP group name | identity.groups.name == "finance" |
| Operating system | OS type | os.name in {"windows" "mac"} |
| Operating system version | A specific OS version | os.version == "14.5.0" |
| Managed network | Whether the device is on a network you defined | (matches your configured managed network) |
| SAML attributes | A name/value from a SAML IdP | (attribute name + value) |
| Service token | Devices enrolled with a specific service token | (the token) |
Operators:
| Type | Operator | Meaning |
|---|---|---|
| Comparison | is | Equals the value |
| Comparison | in | Matches at least one of several values |
| Logical | And | Must match all conditions |
| Logical | Or | Must match any condition |
💡 Example — a "Contractors" profile: Selector User group names · operator is · value contractors. Now anyone in your IdP's contractors group automatically gets this profile's (tighter) settings.
Part C — Order of precedence (how a device gets matched)
This is the part people most often get wrong, so it's worth understanding clearly:
- When a device connects, Cloudflare reads the profile list top to bottom.
- It uses the first profile the device matches — then stops. No profile lower down can override it.
- The Default profile is always pinned at the bottom and applies only if the device matched nothing above it.
Profile list (evaluated top ↓ bottom) A Windows laptop in "finance" group…
┌─────────────────────────────────────┐
│ 1. Linux servers (os = linux) │ ✗ not linux
│ 2. Finance team (group finance)│ ✓ MATCH → gets this profile, stops here
│ 3. BYOD phones (os = ios/andr)│ (never evaluated)
│ 4. Default (always last) │ (never evaluated)
└─────────────────────────────────────┘
⚠️ Watch out: put your most specific profiles higher, and broader ones lower. If a broad profile (e.g. "all Windows") sits above a narrow one (e.g. "Windows in finance"), the narrow one will never match.
💡 Tip: If you promote a custom profile to be the Default, all of its settings are copied into the Default profile.
Part D — Split Tunnels (per profile)
Split Tunnels decide which IP traffic goes through Cloudflare vs. around it. Configure it after saving the profile (open the profile → Split Tunnels → Manage).
Common reasons to use it: run the Cloudflare One Client alongside a VPN (Exclude mode), or grant access to one specific private network (Include mode).
The two modes
| Mode | Behavior | Best for |
|---|---|---|
| Exclude (default) | Everything goes through Cloudflare except what you list | ⭐ Managed corporate devices |
| Include | Only what you list goes through Cloudflare; everything else stays local and is no longer filtered by your network/HTTP policies | ⭐ BYOD / personal devices (keeps personal traffic private) |
⚠️ Switching modes wipes your entries. When you change between Exclude and Include, the list reverts to Cloudflare's defaults. Copy your current entries first (Manage → note them down) so you can re-add them.
🔑 Split Tunnels only affect IP traffic — not DNS
This is the single most misunderstood point. Split Tunnels control where IP packets flow. DNS is separate: even if you exclude a site's IP, its DNS query is still resolved by Gateway (and subject to your DNS policies) unless you also add that domain to Local Domain Fallback (Part E). Split Tunnels and Local Domain Fallback are designed to work together for private resources.
Entry types — IP address vs domain
When you click Manage → add, you choose IP Address or Domain:
- IP address / CIDR (⭐ preferred) — e.g.
10.0.0.0/8. Fast and predictable. To carve a smaller range out of a larger one, use the built-in CIDR calculator in the UI. - Domain — e.g.
example.com. When a user visits it, the domain is resolved (by Gateway, or by your private DNS via Local Domain Fallback), and Split Tunnels then dynamically include/exclude the returned IP. If the domain has no public DNS record, you must add a Local Domain Fallback entry (Part E) so it can resolve.
💡 Prefer IPs over domains. Domains are slower — the client must do on-the-fly IP lookups and rewrite the routing table / local firewall each time. Keep the list short: every entry adds parsing time, and there are per-account limits.
Defaults to know
- Exclude mode already excludes RFC 1918 private ranges, the CGNAT range
100.64.0.0/10(used by Cloudflare One services), and multicast ranges. - ⚠️ If you need to reach private apps/hostnames via the client:
- Exclude mode: remove
100.64.0.0/10from the exclude list (and add back any non-Cloudflare CGNAT ranges you actually use locally, to avoid conflicts). - Include mode: add these so private hostnames resolve — IPv4
100.80.0.0/16and IPv62606:4700:0cf1:4000::/64, plus your private network's own CIDRs.
- Exclude mode: remove
Common Exclude-mode use cases
- Microsoft 365 / Teams / Zoom / VoIP — apps that need the user's real device IP, or are latency-sensitive, often perform better excluded. (There's a one-click Directly route Microsoft 365 traffic option in device settings.)
- Running beside an existing VPN during a phased migration.
⚠️ Trade-off: anything you exclude bypasses Gateway — you lose filtering, DLP, and logging for that traffic. Don't exclude a destination if you need visibility or policy on it.
💡 Tip: To route a private network (e.g. 10.50.0.0/16) to users, add that CIDR in Include mode, or make sure it isn't excluded in Exclude mode.
Part E — Local Domain Fallback
Local Domain Fallback (LDF) tells the client to resolve certain domains using a private/internal DNS resolver you manage, instead of sending those DNS queries to Cloudflare Gateway. The client proxies matching lookups directly to the DNS servers you specify.
Use it for: Active Directory, *.internal, and other private-only domains that public DNS (and Cloudflare) can't resolve — especially when the DNS server is reachable only from the user's device.
Built-in defaults (already handled for you)
Out of the box, Zero Trust keeps common local-resolution top-level domains off Gateway and lets the device's own resolver handle them. The default suffixes are:
corp · domain · home · home.arpa · host · internal · intranet · invalid · lan · local · localdomain · localhost · private · test
You only need to add entries for private domains outside that list (e.g. acme.internal, ad.acme.com).
How to add an entry
- 👉 Open the profile → Local Domain Fallback → Manage (editable only after the profile is saved).
- ⌨️ Domain — enter the apex domain, e.g.
example.com. It's treated as*.example.com, so all subdomains are covered. - ⌨️ DNS Servers — enter the IP(s) of the resolver(s) that should answer it (e.g.
10.0.0.25). Keep it to ≤ 8 servers for performance. The client queries all of them and uses the fastest response — even if that response is "no records found", so always specify at least one reliable server. (Leave blank and the client falls back to whatever DNS the device used before WARP started.) - ⌨️ Add an optional description → Save domain.
LDF is scoped per device profile. A profile with no LDF resource just uses the default suffixes above.
⚠️ Important limitation — no Gateway visibility
DNS queries handled by Local Domain Fallback bypass the Gateway resolver, so they are not subject to Gateway DNS policies and do not appear in DNS logs. If you need filtering or logging on private DNS, use resolver policies instead.
LDF vs. resolver policies — which to use?
| Local Domain Fallback | Resolver policies | |
|---|---|---|
| Where it runs | On the device (client-side) | In Cloudflare Gateway |
| Use when | DNS server is reachable only from the device | DNS server is reachable from Cloudflare's network (via Tunnel, IPsec/GRE, or public Internet) |
| Logging / DNS policy | ❌ No | ✅ Yes (more visibility) |
⭐ Recommendation: if your DNS server can reach a Cloudflare on-ramp, prefer resolver policies for the logging/visibility. If both are configured on the same device, Local Domain Fallback rules apply first.
⚠️ AWS gotcha: don't route all
*.amazonaws.comto an internal Route 53 resolver — public AWS endpoints (e.g.ssm.us-east-1.amazonaws.com) won't resolve and features break. Route only specific Route 53 zones or VPC endpoints (vpce.amazonaws.com).
Verify
- 👉 On a device, run
warp-cli settingsand check the fallback domains section to confirm your entries are applied.
Part F — Global device client settings (all devices)
These sit outside profiles and apply org-wide. Find them under Team & Resources → Devices → Device settings (global section):
| Setting | What it does | Recommendation |
|---|---|---|
| Allow admin override codes | Lets an admin generate a code so a user can temporarily disable the client | Enable for IT support, share codes carefully |
| Allow users to enable local network exclusion | Lets users exclude their local network — a workaround when a home network reuses your corporate IP ranges | Enable only if needed; requires Exclude mode |
| Global / emergency disconnect | Force-disconnect (or reconnect) all clients during an incident/outage — including via an external on-prem HTTPS signal | Set up before you need it |
Part G — Verify which profile a device got
Via the dashboard:
- 👉 Team & Resources → Devices → open a device → check its assigned profile.
Via the device (CLI):
warp-cli settings
- 📺 Look for the
Profile IDfield — it shows the UUID of the profile currently applied.
✅ Checkpoint: Your test device reports the profile you expect (e.g. the BYOD device shows the BYOD profile, not Default).
Worked examples (copy these patterns)
| Profile (order) | Match rule | Key settings |
|---|---|---|
| 1. Linux servers | os.name is linux |
Mode: Gateway with WARP · Switch locked · service-token enrolled |
| 2. Finance (strict) | identity.groups.name is finance |
Mode: Gateway with WARP · short auto-connect · stricter posture required downstream |
| 3. BYOD phones | os.name in {ios android} |
Mode: Gateway with WARP · Include split tunnel (corporate apps only) |
| 4. Contractors | identity.groups.name is contractors |
Mode: Device Information Only or Include split tunnel · switch locked |
| 5. Default | (always last) | Mode: Gateway with WARP · Exclude split tunnel |
✅ Module 3b complete!
You now have:
- ✅ An understanding of global vs. profile settings and the five client modes
- ✅ One or more custom device profiles with match rules
- ✅ Correct order of precedence (specific profiles above broad ones)
- ✅ Per-profile split tunnels and local domain fallback set as needed
- ✅ A way to verify which profile a device received
Quick troubleshooting
| Problem | Fix |
|---|---|
| A device got the wrong profile | Check order of precedence — a broader profile above yours matched first (Part C). Move the specific one up |
| Identity selector never matches | The device was enrolled with a service token, not IdP login — identity selectors don't apply; use OS/managed-network/service-token selectors (Part B) |
| Can't find Split Tunnels / Local Domain Fallback when creating | They're editable only after saving the profile — create it, then reopen (Parts D–E) |
| Private app unreachable on a device | Fix split tunnels: remove 100.64.0.0/10 (Exclude) or add 100.80.0.0/16 + IPv6 (Include) plus your CIDR (Part D) |
| Setting change didn't take effect | Allow up to 10 minutes to propagate; then reconnect the client |
| Home network breaks when connected | Enable local network exclusion (global setting; requires Exclude mode) (Part F) |
👉 Next: Module 4 — ZTNA / Access
Publish your first private application and replace VPN access to it.