Restrict a Website to Specific People with Cloudflare Access
Cloudflare Access puts a login wall in front of a site and lets in only the people on a list you control — free, for up to 50 users. It’s not a plugin or server code: Cloudflare checks who’s knocking before the request reaches your site, so it works the same for WordPress, a static site, or a single HTML page — and an unapproved visitor never even loads it. Nobody shares a password; each person signs in with their own email, and you add or remove someone in seconds.
The classic case: gate a staging site or self-hosted app to a couple of collaborators by their email addresses, and nobody else — not even someone who guessed the URL.
What you’ll need: a site already served through Cloudflare (easiest is a free Cloudflare Pages site — see the companion guide, Host a Free Website with Cloudflare Pages and GitHub), a free Cloudflare account, and the email addresses you want to let in. About 15 minutes, mostly one-time setup.
1. Turn on Zero Trust (one time)
Cloudflare Access lives in Zero Trust (sometimes labeled Cloudflare One) — a
separate section of the dashboard from DNS and caching. Open it from the sidebar.
First time through, you pick a team domain (any name — it becomes
yourname.cloudflareaccess.com, your login page’s address) and a plan. Pick
Free: up to 50 users, far more than a homelab or small team needs. It may ask for a
card to activate; it isn’t charged.
2. Add your site as an Access application
An application is one site (or one path) you protect. Go to Access controls → Applications → Create new application and choose Self-hosted and private, then give it:
- A name (e.g. “Staging” or “Homelab Dashboard”).
- The destination to protect — your site’s hostname (
dashboard.example.com), a whole subdomain, or just a path (example.com/internal).
Close the back door. A Cloudflare Pages site also answers at its
*.pages.devaddress. Add that hostname as a second destination on the same application, or someone can bypass the wall by visiting the pages.dev URL.
Leave the session duration at its default (24 hours) — how long someone stays signed in before re-authenticating.
3. Write the allow-list — the one step that matters
The rule that decides who gets in. On the application, add a policy:
- Action: Allow
- Include: the selector that fits —
| Selector | Admits | Use when |
|---|---|---|
| Emails | the exact addresses you type | you want specific people |
| Emails ending in | everyone at a whole domain | it’s a company and you want all @company.com staff |
For “just these people,” choose Emails and list them: you@example.com,
teammate@example.com, and so on. Save — the policy is live within seconds.
The one trap: don’t use “Emails ending in” with
@gmail.comto admit a few Gmail users — that admits every Gmail account on Earth. For a named list, always use Emails.
4. How people sign in
By default, Access uses a one-time PIN — no setup, works for any email:
- A visitor opens the site and is asked for their email.
- Cloudflare emails them a 6-digit code.
- They enter it, and Cloudflare checks the address against your allow-list.
The PIN only proves someone controls that inbox; your allow-list decides who’s actually let in. A stranger who enters their own Gmail gets a code, enters it, and is still denied — their address isn’t on the list.
(Optional: add a “Sign in with Google” button instead of the emailed code — handy if everyone’s on Google, but it’s more setup (a Google OAuth client) and rarely worth it for a handful of people. The PIN is simplest.)
5. Test it
Open your site in a private/incognito window (so you’re not already signed in). You should hit the Cloudflare login page, not your site. Enter an allowed email, get the code, land on the site. Then try a non-allowed email — you should be denied. That one test confirms both that the wall is up and that the list is doing its job.
6. Add or remove people later
It’s all under Access controls → Applications → your app → Policies (or edit the reusable policy under Access controls → Policies). Edit the Emails list to add or remove someone; it takes effect on their next sign-in. To lock someone out immediately, remove them and revoke their active session.
It’s not just for static sites
Access sits in front of anything Cloudflare proxies — a WordPress site, a web app, even a service running on a computer at home (exposed with a Cloudflare Tunnel). The login wall and allow-list behave identically; all that changes is how the site got behind Cloudflare in the first place.