Protecting WordPress, cPanel and Internal Admin Panels with Cloudflare Zero Trust Access
How to put admin logins behind Cloudflare Access: connect Entra ID or Google Workspace, write deny-by-default policies, use service tokens, and stop attackers reaching the server directly.
Your WordPress login page, cPanel, WHM, router interface and internal dashboards don't need to be open to the whole internet. With Cloudflare Access, part of Cloudflare's Zero Trust platform (Cloudflare One), anyone who visits those pages must first sign in through Cloudflare with an identity you approve, such as a company Microsoft or Google account, before the request reaches your server. Cloudflare lists its Zero Trust Free plan for teams under 50 users. The setup comes down to four parts: add the application, connect an identity provider, write a strict policy, and make sure nobody can reach the server directly around Cloudflare. Most failed setups miss that last part.
Why put admin panels behind Access
Admin pages are a favorite target because one stolen password gives an attacker control of the whole website or server. Typical problems we see:
wp-login.phpand/wp-adminhit by automated password guessing around the clock.- cPanel (port 2083) and WHM (port 2087) exposed to every IP address on the internet.
- Internal tools such as a NAS, a backup console or a monitoring dashboard published "temporarily" years ago.
Access puts an identity check in front of all of them. Attackers don't get as far as the application's own login form, and you get one place to grant and revoke access. It does not replace good passwords and multi-factor authentication inside each application. It adds a second gate.
Step 1: Connect an identity provider
In the Cloudflare dashboard, open Zero Trust > Integrations > Identity providers and add the provider your team already uses:
- Microsoft Entra ID if you run Microsoft 365. You can then use Entra groups in policies.
- Google Workspace if your email is on Google. Cloudflare's Workspace integration can read group membership, which the generic Google login does not.
- One-time PIN, Cloudflare's built-in method, which emails a single-use code to an allowed address. It works without any identity provider and is useful for outside contractors.
You can enable several providers at once, for example Entra ID for staff and one-time PIN for a web developer.
Two details about one-time PIN from Cloudflare's docs: the code expires 10 minutes after it is requested, and email security tools that automatically follow links can use up the PIN before the person does. If that happens, ask your email administrator to exclude Cloudflare's login emails from link scanning.
Step 2: Add a self-hosted application
Go to Zero Trust > Access controls > Applications > Create new application and choose the self-hosted option, then add the public hostname you want to protect.
Real examples:
| What to protect | Hostname and path | Notes |
|---|---|---|
| WordPress admin | example.com/wp-admin and example.com/wp-login.php |
Test front-end features that call /wp-admin/admin-ajax.php |
| cPanel / WHM | A dedicated hostname such as cpanel.example.com |
Cloudflare proxies HTTPS on ports 2083 and 2087 |
| Internal dashboard | dashboard.example.com |
A good candidate for Cloudflare Tunnel |
The domain must be an active zone in your Cloudflare account. Cloudflare warns that until an Access application exists for a published hostname, that hostname is open to anyone on the internet, so create the Access application before you publish the route.
On the same screen you choose the login methods (the identity providers from Step 1) and the session duration, which sets how often users must sign in again. For admin tools, a working day or shorter is reasonable. A month is not.

Step 3: Write policies that actually restrict access
Access is deny by default: if no Allow policy matches, the user is blocked. Policies are built from three rule types:
- Include works like OR. At least one must match. Every policy needs one.
- Require works like AND. Every Require rule must match.
- Exclude works like NOT. Anyone matching it is denied.
A solid policy for a WordPress or cPanel admin area looks like this:
- Action: Allow.
- Include: Emails, listing the specific people who administer the site (not "Emails ending in @yourcompany.com" for a server panel).
- Require: Authentication method set to MFA, if your identity provider reports it. Cloudflare checks this at login.
- Require: Country set to United States, if all of your administrators work from here. Cloudflare determines country from the IP address, so a VPN can change the result.
For broader internal tools, an Identity provider group (for example an Entra ID group called "Office staff") is easier to maintain than a list of emails. When someone leaves, removing them from the group removes their access, which ties into your offboarding checklist.
Be careful with Bypass
The Bypass action turns off Access for matching requests. Cloudflare's documentation notes that Bypass requests are not logged, that Bypass cannot use identity rules, and that Cloudflare does not recommend Bypass for permanent access to internal applications. Use it only for narrow, tested cases, such as a public health-check URL. Don't use it as a shortcut for "the office IP can get in without logging in".
Step 4: Service tokens for automation
Scripts, uptime monitors and backup jobs can't type a password or a PIN. For them, create a service token under Zero Trust > Access controls > Service credentials > Service Tokens. Cloudflare issues a Client ID and a Client Secret, which the script sends as the CF-Access-Client-Id and CF-Access-Client-Secret headers.
Keep in mind:
- The policy that accepts the token must use the Service Auth action. Otherwise Access sends the request to a login page.
- The Client Secret is shown only once. Store it in your password manager or secrets vault right away.
- Tokens have an expiration date that you choose. Put renewal on the calendar, and use one token per system so you can revoke a single one.
The bypass pitfall: your origin is still reachable
This is the most important part. Access protects traffic that goes through Cloudflare. If your server's IP address is known, from old DNS records, a mail record on the same server, or simple scanning, an attacker can connect to https://<server-ip>/wp-login.php or port 2083 directly and never see Access.
Close that gap with one or more of these:
- Cloudflare Tunnel. The server makes an outbound-only connection to Cloudflare, and you close the inbound web and panel ports. With Protect with Access enabled in the tunnel settings,
cloudflaredchecks the Access token as well. This is the cleanest option for internal dashboards. - Firewall allow-listing. Allow ports 80, 443, 2083 and 2087 only from Cloudflare's published IP ranges (cloudflare.com/ips) and from any trusted fixed IPs. The Linux server hardening basics apply.
- Validate the Access token at the origin. Access adds a signed token in the
Cf-Access-Jwt-Assertionheader. Cloudflare recommends that your application validate it with Access's public key so it can tell requests that really came through Access.
Then test from outside: try the server IP directly, from a phone on cellular data. If you still reach a login page, the work isn't finished.
Quick checklist
- Identity provider connected (Entra ID or Google Workspace), with one-time PIN only where it is needed.
- Access application created before the hostname is published.
- Allow policy limited to named admins, with MFA and country requirements where they fit.
- Session duration of a working day or less for admin tools.
- No broad Bypass policies.
- Service tokens for automation, stored safely, with expiry dates tracked.
- Origin locked down with Tunnel, a firewall allow-list or token validation, and tested directly.
Our cybersecurity and managed IT support teams set up Cloudflare Access for businesses as an independent IT provider. Cloudflare doesn't endorse us; we configure its tools for our clients. If your admin panels are still open to the internet, request a free IT assessment. We work with businesses across Miami-Dade and South Florida, in English and Spanish.
Sources
- Add a self-hosted public application (Cloudflare Docs)
- Access policies (Cloudflare Docs)
- Identity providers (Cloudflare Docs)
- Google Workspace identity provider (Cloudflare Docs)
- One-time PIN login (Cloudflare Docs)
- Service tokens (Cloudflare Docs)
- Validate JWTs (Cloudflare Docs)
- Network ports (Cloudflare Docs)
- Cloudflare One plans


