The daily 'pdb.zorc.app verification failed (302)' is Cloudflare Access working as designed against a curl that never learned to knock. Service tokens are the knock.
Every morning the deploy verify leg reports the live page failed because an unauthenticated request gets a 302 to the Access login. Meanwhile the pages.dev preview URL from the same deploy serves identical content to anyone holding the link — the alarm points at the locked front door while the side gate stands open.
Cloudflare Access is a zero-trust gate: every request to pdb.zorc.app must present identity — normally a browser login session. Zero-trust means no request is trusted by network position alone; a curl from your own Mac is as anonymous as one from anywhere. The 302 isn't an outage — it's the policy answering 'who are you?' to a client with no answer.
Service tokens are how automation answers. You mint a Client ID + Client Secret pair in the Cloudflare dashboard, add an Access policy that accepts it, and your script sends both as headers (CF-Access-Client-Id / CF-Access-Client-Secret). The verify leg then sees the real 200 from the real domain — no browser, no cookie jar.
Two sharp edges worth knowing this month. First: your preview deployments (the 2a28f6c6.pdb-eev.pages.dev-style URLs logged every morning) are NOT behind Access — anyone with a URL reads your daily plan. Second: Cloudflare just shipped Access-policy-attach for Workers with private-by-default previews, which is designed to close exactly that gap — it's the adopt question on this week's review card.
Watch the gate answer, then see what an authenticated knock looks like.
curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' https://pdb.zorc.app/plan-day/today.html
curl -s -o /dev/null -w '%{http_code}\n' \
-H "CF-Access-Client-Id: <token-id>.access" \
-H "CF-Access-Client-Secret: <secret>" \
https://pdb.zorc.app/plan-day/today.html
A 302 from a zero-trust gate is a question, not a failure — give your automation an identity and the question goes away.