# ADR 050: Cloudflare Access for Preview Environment Gates

- HTML version: https://robbiepalmer.me/projects/recipe-site/adrs/050-cloudflare-access-preview-gates
- Project: Recipe Site (https://robbiepalmer.me/projects/recipe-site.md)
- Status: Accepted
- Date: 2026-07-08

# Summary

Use **Cloudflare Access** to require an allowlisted identity before anyone can reach recipe-site
preview environments.

# Context

The recipe site lives in a public repository, but its backend hooks into real services: auth, Neon,
Cloudflare Workers, R2, PostHog, OAuth providers, OpenRouter, and future workflow infrastructure.
Even isolated previews still exercise real platform credentials, callback URLs, third-party APIs,
and cost-bearing services.

Public preview URLs create a review-time exploit path:

* an attacker can watch public pull requests and inspect the code before merge
* a reviewer can accidentally point out an exploitable issue in an inline comment
* the attacker can immediately try that issue against the preview URL from the same pull request
* preview branches may temporarily contain weaker validation, debug behaviour, or unfinished auth
  and migration code

Production still needs normal application security. This decision is narrower: short-lived review
deployments should not be anonymously internet-reachable while their risks are being discussed in
public.

# Decision

Gate all recipe-site preview frontend and API hostnames with Cloudflare Access.

Access is an edge reachability control, not product authentication. Production remains governed by
Better Auth, API authorization, CSRF protection, rate limiting, and the application security
baseline in [ADR 035](/projects/recipe-site/adrs/035-application-security-baseline). Preview
environments still need least-privilege credentials, isolated data where practical, preview-specific
OAuth configuration, and cost controls.

The intended policy is allowlist-based: the maintainer and expected reviewers can reach previews;
the general public cannot.

# Consequences

## Positive

* **Reduces review-time exploitability.** A public diff or review comment no longer gives every
  anonymous visitor a directly usable preview target.
* **Protects real integrations.** Preview environments still touch real Cloudflare, Neon, OAuth,
  analytics, and model-provider infrastructure, so an identity gate meaningfully reduces abuse risk.
* **Keeps previews usable.** Reviewers can still test live deployments once they are allowed through
  Access.
* **No app code required.** The gate runs before Pages or Workers, so it does not depend on the
  application auth code being correct on an in-review branch.
* **Consistent with the platform.** The site already uses Cloudflare Pages and Workers, so Access is
  a platform-native control rather than another proxy or bespoke service.

## Negative

* **Reviewer friction.** External reviewers need to be allowlisted and must complete an Access login
  before opening a preview.
* **Configuration drift risk.** Preview hostnames and API routes must stay covered as deployment
  patterns change.
* **Not a complete security boundary.** Anyone with Access can still exercise the preview, so
  least-privilege preview credentials and application-level protections remain required.
* **Automation needs exceptions.** Synthetic checks, webhook callbacks, and third-party preview
  consumers may need service tokens or separate bypass rules if they must reach previews.
* **Potential false confidence.** Access lowers exposure but does not make unsafe preview code safe
  to merge or safe to run with production-grade privileges.

# When To Revisit

* Preview deployments stop using real external services and become fully local, synthetic, or
  disposable.
* The repository becomes private, reducing the diff-to-preview exploit path.
* External contribution grows enough that allowlisting reviewers becomes a material bottleneck.
* Cloudflare Access cannot express the required hostname or service-token policy cleanly.
* A preview incident shows that Access alone is insufficient and stronger service isolation is
  needed.

---

Markdown index of this site: https://robbiepalmer.me/llms.txt
