If you manage a WordPress site long enough, you’ve seen the same pain cycle: bots pound on wp-login.php, security rules get tightened, and then legitimate admins get blocked the moment they hop networks or their IP changes. A zero‑trust approach flips the model from “trust this IP” to “verify this person.” With Cloudflare Zero Trust (Access), you can put an authentication gate in front of WordPress admin so only approved users can even reach /wp-admin/ and wp-login.php.
This guide uses one‑time email codes (Cloudflare’s One‑time PIN / OTP), so you don’t have to integrate Google/Microsoft SSO. Admins authenticate with their email, receive a short code, and once verified Cloudflare allows the request to proceed to WordPress.
What you’ll build
- An Access gate in front of:
/wp-admin/*/wp-login.php
- Optional: less WAF friction by skipping specific security checks only on those admin paths (because they’re no longer publicly reachable).
- Optional but strongly recommended: origin hardening so the server can’t be accessed directly, bypassing Cloudflare.
Prerequisites
- Your site must be proxied through Cloudflare (orange cloud enabled on the DNS record). If traffic isn’t passing through Cloudflare, Access can’t protect it.
- A list of approved admin emails (start small; you can add more later).
- Confirm whether your public site depends on
wp-admin/admin-ajax.phpfor unauthenticated visitors (common with forms/plugins). If you’re unsure, assume it might and handle it carefully (see below).
Step 1 — Set up Cloudflare Zero Trust + One‑time PIN
- Open the Cloudflare Zero Trust dashboard.
- Enable/configure One‑time PIN (OTP) as an authentication method.
You’ll use this method in your Access policy so admins can authenticate with email codes.
Step 2 — Create Access applications for WordPress admin
Create a Self‑hosted Access application scoped to the admin entry points. You can do this as one app with multiple paths, or two separate apps (often easier to troubleshoot).
Recommended protected paths:
/wp-admin*/wp-login.php*
Protecting both matters: /wp-login.php is a direct entry point that can bypass /wp-admin protections if left open.
Step 3 — Add an Access policy (Allow) for your admins
Create an Allow policy that includes only the admins who should be able to reach these URLs.
Typical policy configuration:
- Action: Allow
- Include: specific email addresses (or a trusted email domain if appropriate)
- Authentication method: One‑time PIN
From here on, access management becomes “add/remove an email,” not “chase down an IP address.”
Step 4 — Don’t break the public site (the admin-ajax.php gotcha)
Some WordPress sites use wp-admin/admin-ajax.php for public features (forms, theme widgets, plugin features). If you blanket‑protect all of /wp-admin, you can accidentally break those features for regular visitors.
Safer approach:
- Exclude
/wp-admin/admin-ajax.phpfrom Access protection if it’s used publicly. - Protect
admin-ajax.phpseparately using rate limiting and/or bot protections, not identity.
If your site doesn’t use admin-ajax.php publicly, you can keep it behind Access like the rest of /wp-admin.
Step 5 (Optional) — Reduce WAF false positives on admin
If Cloudflare managed rules are blocking legitimate admin logins, Access gives you the freedom to reduce friction.
Once admin URLs are gated by Access, you can add a WAF Custom Rule with a Skip action that skips the specific security checks causing false positives on:
/wp-admin*/wp-login.php
Because these paths aren’t publicly reachable anymore (they require OTP), you’re not weakening security for the public site—you’re just removing unnecessary blocks for verified admins.
Step 6 (Strongly recommended) — Lock down the origin so Cloudflare can’t be bypassed
Zero‑trust only works if attackers can’t hit your origin directly.
On your origin (EC2, VPS, etc.):
- Restrict inbound HTTP/HTTPS to Cloudflare’s published IP ranges (or use another Cloudflare‑supported origin authentication approach).
- Keep SSH restricted to trusted management IPs/VPN only.
This prevents anyone from bypassing Access by visiting the server’s direct IP address.
Testing checklist
- From a non‑approved email/user:
- Confirm
/wp-admin/andwp-login.phpare blocked by Access.
- Confirm
- From an approved admin:
- Visit
/wp-admin/→ get the email prompt → receive OTP → enter OTP → proceed to WordPress login.
- Visit
- Browse the public site:
- Confirm forms and interactive features work (especially if you excluded
admin-ajax.php).
- Confirm forms and interactive features work (especially if you excluded
- Review Cloudflare logs:
- Access logs show successful/failed OTP auth attempts.
- WAF events for admin paths should drop if you added Skip rules.
Wrap‑up
This setup removes the day‑to‑day pain of IP allowlists and reduces friction caused by managed WAF rules, while improving security against brute‑force and bot traffic. Admin endpoints become identity‑gated at the edge, so your WordPress admin is no longer “publicly reachable” in the traditional sense—and admins can work reliably from anywhere.




