The junior pastes a screenshot. The coding agent shared a trycloudflare.com URL. The visitor typed an email, hit a Cloudflare Access page, and stalled. Chat files the ticket: “the visitor needs a Cloudflare account. Access is misconfigured.”
I stop the run there. An allowed-mail list is not a Cloudflare account. Cloudflare’s public notes that named this field are blunt: --allowed-mail on cloudflared restricts a Quick Tunnel to the email addresses and domains you list. Visitors authenticate with a one-time PIN. Nobody on either side needs a Cloudflare account. Access ends when you stop the process. That is email OTP on a Quick Tunnel. It is not production Access on a named Tunnel. It is not a dashboard login. [Source: https://blog.cloudflare.com/protected-quick-tunnels/] [Source: https://developers.cloudflare.com/changelog/post/2026-10-02-protected-quick-tunnels/]
I already refused to treat a nested deny as a mod approval in A Nested Deny Is Not a Mod Approval, a 40-character ghs_ check as a valid App token in A 40-Character ghs_ Check Is Not a Valid App Token, and a redirected dangerous rm as always-ask off in Print the Redirect Before You File Always-Ask Off. This post is the same desk rule for a shared preview URL. Print the guest list. Print whether a Cloudflare account exists. Name who owns the tunnel answers.
The question is not whether the Access page looked official. The question is whether the named owner can still tell an allowed-mail list from a Cloudflare account.

The ticket that looks like Access-is-broken
Juniors treat a Cloudflare Access page the way they treat a login wall. Yesterday anyone with the trycloudflare.com link opened the local Vue preview. Today the same kind of URL asks for an email and a PIN. They page the desk: “someone turned on Zero Trust” or “the visitor must create a Cloudflare account.”
Two jobs collide on that URL.
- Keep the guest list honest. Official changelog, 2 October 2026: use
--allowed-mailso visitors authenticate with a one-time PIN sent to their email before they reach the local service. You can allow one address, several addresses, or every address on a domain. Visitors do not need a Cloudflare account. Access ends for everyone when you stopcloudflared. [Source: https://developers.cloudflare.com/changelog/post/2026-10-02-protected-quick-tunnels/] - Keep the product named. Official Quick Tunnels docs: a Quick Tunnel is a temporary
trycloudflare.comURL for a local service. You do not need a Cloudflare account or a domain. A named Cloudflare Tunnel with Cloudflare Access is a different product: stable hostname, account, richer identity-provider rules. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/] [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
If you only screenshot “Cloudflare Access,” you will file Access-broken. You will not file the guest list.
I do not invent a fake overnight outage of every named Tunnel. I use the public contract. The guest-list field is the ticket, not a version pin in the title.
What Cloudflare actually named
Read the 2 October 2026 changelog, then the Quick Tunnels page, then the blog post that explains why the guest list lives on your machine. Do not trust a social recap. Do not trust this post without those pages.
The named field, published 2 October 2026:
Use the new
--allowed-mailflag incloudflaredto require visitors to authenticate with a one-time PIN sent to their email before they reach your local service.
That sentence has three parts. Print all three on the ticket.
| Part | What it is | What it is not |
|---|---|---|
| Allowed-mail list | Email addresses or a domain pattern you passed to --allowed-mail | Proof the visitor has a Cloudflare login |
| Email OTP | A one-time PIN sent to that mailbox through Cloudflare Access | Production Access on a named hostname |
| Quick Tunnel | A temporary trycloudflare.com URL that dies when the process exits | A named Tunnel in an account, with DNS and an SLA |
Official docs keep the flag shapes small. A single address: --allowed-mail [email protected]. Several addresses: repeat the flag, or pass a comma-separated list. A whole domain: --allowed-mail '*@example.com' with quotes so the shell does not expand the star. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/]
The blog is equally blunt on what this is not. If you leave out --allowed-mail, public Quick Tunnels behave as they always have: anyone with the link can open it. To change who can get in, stop cloudflared and start a new tunnel. For a stable hostname or richer rules such as identity-provider groups, use Cloudflare Tunnel with Cloudflare Access. [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
Where the pin sits after the decision, not in the title
cloudflared 2026.9.3. The public changelog that named the field is dated 2 October 2026. GitHub’s cloudflare/cloudflared tag 2026.9.3 is dated 2026-09-24. This desk’s GitHub read on 6 October 2026 also showed a later tag 2026.10.0 dated 2026-10-05. Do not put any of those tags in the title. Do not treat a checksum-only GitHub body as the feature notes. Neighbor products in the same week (named Tunnel plus Access, Cloudflare Mesh, workers.dev cutover) are other tickets. [Source: https://blog.cloudflare.com/protected-quick-tunnels/] [Source: https://github.com/cloudflare/cloudflared/releases/tag/2026.9.3] [Source: https://github.com/cloudflare/cloudflared/releases/tag/2026.10.0]Four checks before you file
A mid-senior screenshots this list. A junior who only has the agent log still has a ticket they can close.
- Print whether
--allowed-mailwas on the command. If the log is a barecloudflared tunnel --url http://localhost:5173, the field is a public Quick Tunnel. Anyone with the URL can open it. If the log holds--allowed-mail, the field is a guest list plus email OTP. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/] - Print Cloudflare account versus guest list. Official changelog: visitors do not need a Cloudflare account. The blog: nobody on either side needs a Cloudflare account. A named Tunnel with Access lives in an account. Those are different tickets. [Source: https://developers.cloudflare.com/changelog/post/2026-10-02-protected-quick-tunnels/] [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
- Print who owns the process. Access ends when you stop
cloudflared. The person who started the process owns the guest list. A Slack channel does not own it. A coding agent does not own it. - Write one human name.
TUNNEL_PREVIEW_OWNER. That name answers “is this allowed-mail, or did we file Access-broken on a Quick Tunnel.”

Those four lines are the whole post. Everything below is how you print them without turning this page into a tunnel-bypass recipe.
Print the guest list without printing the emails
Do not paste a live production app behind a public Quick Tunnel to “prove” the field. Do not write a recipe that strips --allowed-mail so a reviewer can skip the PIN. The public changelog already states the field. You need a classifier on a logged command string, plus synthetic fixtures.
Copy this probe. It classifies a string. It never starts cloudflared. It never prints the addresses.
1#!/usr/bin/env python3
2"""Classify a cloudflared argv line. Never execute. Never print emails."""
3from __future__ import annotations
4
5import shlex
6import sys
7
8
9def _is_mail_flag(token: str) -> bool:
10 return token in {"--allowed-mail", "-allowed-mail"}
11
12
13def classify(line: str) -> dict[str, object]:
14 try:
15 tokens = shlex.split(line, posix=True)
16 except ValueError:
17 return {
18 "ok": False,
19 "reason": "unparsed_argv",
20 "has_allowed_mail": False,
21 "rule_count": 0,
22 "has_url": False,
23 "looks_like_quick_tunnel": False,
24 }
25
26 has_url = "--url" in tokens or "quick-start" in tokens
27 looks_quick = "tunnel" in tokens and has_url and "create" not in tokens
28 rule_count = 0
29 i = 0
30 while i < len(tokens):
31 tok = tokens[i]
32 if _is_mail_flag(tok):
33 if i + 1 < len(tokens) and not tokens[i + 1].startswith("-"):
34 chunk = tokens[i + 1]
35 rule_count += max(1, len([p for p in chunk.split(",") if p.strip()]))
36 i += 2
37 continue
38 rule_count += 1
39 elif tok.startswith("--allowed-mail="):
40 chunk = tok.split("=", 1)[1]
41 rule_count += max(1, len([p for p in chunk.split(",") if p.strip()]))
42 i += 1
43
44 return {
45 "ok": True,
46 "has_allowed_mail": rule_count > 0,
47 "rule_count": rule_count,
48 "has_url": has_url,
49 "looks_like_quick_tunnel": looks_quick,
50 "this_field": bool(looks_quick and rule_count > 0),
51 "public_quick_tunnel": bool(looks_quick and rule_count == 0),
52 }
53
54
55def main() -> int:
56 line = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else sys.stdin.read()
57 row = classify(line.strip())
58 print(
59 "this_field={this_field} public_quick_tunnel={public_quick_tunnel} "
60 "rule_count={rule_count} looks_like_quick_tunnel={looks_like_quick_tunnel}".format(
61 **row
62 )
63 )
64 return 0
65
66
67if __name__ == "__main__":
68 raise SystemExit(main())
Run it against fixtures. Do not feed it a live token. Do not start a tunnel.
1python3 probe_allowed_mail.py 'cloudflared tunnel --url http://localhost:5173'
2python3 probe_allowed_mail.py "cloudflared tunnel --url http://localhost:8080 --allowed-mail [email protected]"
3python3 probe_allowed_mail.py "cloudflared tunnel --url http://localhost:8080 --allowed-mail '[email protected],[email protected]'"
4python3 probe_allowed_mail.py "npx wrangler tunnel quick-start http://localhost:8080 --allowed-mail [email protected]"
Expected shape on this desk:
| Fixture | this_field | public_quick_tunnel | rule_count |
|---|---|---|---|
Bare --url | False | True | 0 |
One --allowed-mail | True | False | 1 |
| Comma list | True | False | 2 |
| Wrangler quick-start with the flag | True | False | 1 |
The Wrangler line is in the public blog: npx wrangler tunnel quick-start http://localhost:8080 --allowed-mail [email protected]. Treat it as the same guest-list field, not a workers.dev cutover. [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
Then print the ticket. Still no emails.
1#!/usr/bin/env python3
2"""Print an allowed-mail ticket. Never start a tunnel. Never print addresses."""
3from __future__ import annotations
4
5import json
6import os
7
8from probe_allowed_mail import classify
9
10
11def ticket(command: str) -> dict[str, object]:
12 row = classify(command)
13 owner = os.environ.get("TUNNEL_PREVIEW_OWNER", "").strip()
14 account = os.environ.get("CLOUDFLARE_ACCOUNT_PRESENT", "unknown").strip()
15 return {
16 "owner": owner or "MISSING",
17 "cloudflare_account_present": account,
18 "this_field": row.get("this_field"),
19 "public_quick_tunnel": row.get("public_quick_tunnel"),
20 "rule_count": row.get("rule_count"),
21 "wrong_ticket": "visitor_needs_cloudflare_account",
22 "right_ticket": "allowed_mail_vs_account_vs_named_owner",
23 "file_access_broken": False,
24 }
25
26
27if __name__ == "__main__":
28 sample = (
29 "cloudflared tunnel --url http://localhost:5173 "
30 "--allowed-mail [email protected]"
31 )
32 print(json.dumps(ticket(sample), indent=2, sort_keys=True))
If owner is MISSING, the ticket is “owner missing,” not “Access is broken.” If this_field is true and cloudflare_account_present is no, the visitor does not need a Cloudflare account. Official changelog: visitors do not need one. [Source: https://developers.cloudflare.com/changelog/post/2026-10-02-protected-quick-tunnels/]

What the Access page is doing
Juniors see login.trycloudflare.com and file “we enabled Zero Trust on the zone.” The blog splits the two questions the page answers.
- Authentication. Cloudflare Access sends a one-time PIN and verifies the mailbox. That step answers only: does this person control this email address.
- Authorization.
cloudflaredon your machine compares the verified address with the rules you typed. There is no Cloudflare account holding the policy. The guest list lives in the process you started. [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
The same blog names the session bounds as evidence, not as a tuning guide: a single-use browser state valid for 10 minutes, then a local session for up to four hours or until you stop cloudflared. A protected tunnel does not fall back to public mode. cloudflared prints whether email authentication is on and how many rules it holds, without printing the addresses. [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
The Access screenshot is the OTP half. The guest list half is still on the laptop that ran the command.
Quick Tunnels also carry hard limits that do not belong on a production cutover ticket. Official docs: no uptime guarantee, at most 200 in-flight requests (extra requests return 429), and no Server-Sent Events. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/]
Scan the agent log, then stop
You do not need to open the preview. You need to know whether the agent started a public Quick Tunnel or an allowed-mail Quick Tunnel. Scan logs. Do not start cloudflared from the scanner.
1#!/usr/bin/env python3
2"""Scan text logs for Quick Tunnel commands. Never execute them."""
3from __future__ import annotations
4
5from pathlib import Path
6
7from probe_allowed_mail import classify
8
9ROOT = Path("logs")
10NEEDLES = ("cloudflared", "trycloudflare.com", "wrangler tunnel quick-start")
11
12
13def main() -> int:
14 hits = 0
15 for path in ROOT.rglob("*"):
16 if path.suffix.lower() not in {".log", ".md", ".txt"}:
17 continue
18 try:
19 text = path.read_text(encoding="utf-8", errors="replace")
20 except OSError:
21 continue
22 for i, line in enumerate(text.splitlines(), 1):
23 if not any(n in line.lower() for n in NEEDLES):
24 continue
25 row = classify(line)
26 print(
27 f"{path}:{i}:this_field={row.get('this_field')} "
28 f"public={row.get('public_quick_tunnel')} "
29 f"rules={row.get('rule_count')}"
30 )
31 hits += 1
32 print(f"hits={hits}")
33 return 0
34
35
36if __name__ == "__main__":
37 raise SystemExit(main())
If the scan prints public=True, the ticket is a public Quick Tunnel, not Access-misconfigured. If it prints this_field=True, the ticket is this post. If it prints nothing, file a missing owner, a missing log, or a named-Tunnel ticket.
What you must not do
Forbidden:
- File “the visitor needs a Cloudflare account” without printing
--allowed-mailversus public Quick Tunnel, account versus guest list, and one human name. - Put
2026.9.3,2026.10.0, or2 October 2026in the title as a version-style hook. The numbers are evidence after the decision. - Write a tunnel-bypass recipe: stripping
--allowed-mail, sharing the PIN, forging the Access assertion, or mapping a way aroundlogin.trycloudflare.com. - Recommend buying Access, a Zero Trust seat, or a plan because a Quick Tunnel showed an OTP page. Official blog: email protection for Quick Tunnels is free, like Quick Tunnels themselves. [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
- Treat a named Tunnel, Cloudflare Mesh, or a workers.dev deploy as this field.
- Mix this field with nested deny,
ghs_length, redirectedrm, lockfile, or sandbox-equals. Do not clone those shipped URLs. - Start a live public Quick Tunnel in front of production data to demo the classifier.
- Let a coding agent own
TUNNEL_PREVIEW_OWNER, or collapse allowed-mail and Cloudflare account into one ticket.
Allowed:
- Print whether the flag was present. Redact addresses if a log leaked them.
- Classify synthetic fixtures with
probe_allowed_mail.py. Do not execute them. - Scan logs for
cloudflared/trycloudflare.com/ Wrangler quick-start. - Name one human as
TUNNEL_PREVIEW_OWNER. - Keep Quick Tunnel, named Tunnel plus Access, and Mesh as separate tickets.
- After the owner prints the four lines, stop the process they started if the guest list is wrong. Start a new Quick Tunnel with a new list. Official docs: you cannot edit the list in place. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/]
- Put one line in the agent instructions file you already own: when the agent starts a Quick Tunnel, it adds
--allowed-mailfor the reviewer. The blog suggests that pattern. Check the printed rule count. Do not trust the agent to follow the line. [Source: https://blog.cloudflare.com/protected-quick-tunnels/]
If you need the broader habit, start at /ai-agent-operations/. Tooling notes live under /developer-tools/. Laravel plus Vue notes live under /laravel-vue-saas/. A first-week map is at /start-here/.
A changelog bullet about --allowed-mail is not permission to skip the four lines.
What you should do Monday morning
- Open the repo that actually shares local previews. Export
TUNNEL_PREVIEW_OWNERto a human name. ExportCLOUDFLARE_ACCOUNT_PRESENTtoyes,no, orunknown. Run the ticket printer against yesterday’s agent log. Writethis_field=TrueorFalseon the ticket next to that name. - For every
this_field=Truerow, answer in one sentence: the visitor hit email OTP on a Quick Tunnel, or they hit a named Tunnel Access policy, or they hit a public Quick Tunnel. If you cannot answer, the ticket is “owner missing,” not “Access is broken.” - Print public versus allowed-mail. If the command has no
--allowed-mail, official docs still say anyone with the URL can access the local service. That is a public-share ticket. If the command has the flag, official docs say the visitor does not need a Cloudflare account. Split those tickets. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/] - Confirm coding-agent instructions on this desk name the same owner and forbid “visitor needs a Cloudflare account” without the four lines. Forbid starting a live public tunnel in front of production data to demo. Forbid writing a hide path around the PIN page.
- Confirm the guest list still uses the documented shapes: one address, repeated flags, comma-separated list, or
'*@example.com'in quotes. Do not invent a dashboard to edit the list while the process runs. Stop and start. [Source: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/] - Leave nested deny,
ghs_length, redirectedrm, named Durable Object cutover, and workers.dev off this ticket. Those are neighbor fields. Do not steal them as a second heading.
The question is not whether the changelog demos well. The question is whether the named owner can still tell an allowed-mail list from a Cloudflare account after handoff.
Further reading
Source Cloudflare Blog — Protected Quick Tunnels
Source Cloudflare Changelog — Protect Quick Tunnels with email authentication
