I've been setting up Cloudflare Access for a few clients now, and I keep running into the same initial hurdle. The default behavior when you create an Access policy is to `allow` if the user meets the rule criteria. But what I *really* want when I'm starting a fresh, secure application is a simple, built-in "deny all" default posture.
Here's my typical workflow:
1. I set up a new app subdomain (e.g., `internal-tool.example.com`).
2. I go to create my first policy. My intent is always "Nobody gets in unless I explicitly say so."
3. I have to manually configure the first policy to be an `Include` rule for a specific group, which implicitly denies everyone else. That's fine, but it feels backwards.
Why isn't there a top-level, explicit "Block everyone" default rule I can apply to the application itself? That would mirror a zero-trust mindset much more clearly from the get-go. Right now, the mental model is "empty policy = open," and I have to *build* the wall. I'd prefer "new app = wall is built, now poke holes."
I've worked around it by creating a "Deny All" policy using a non-existent email domain as a rule, but that's a hack. For example:
```json
{
"name": "Deny All - Initial",
"decision": "deny",
"include": [{"email_domain": {"domain": "fake.denydomain"}}]
}
```
This works because no one has that email, so it denies everyone. But it's clunky and requires explaining the workaround to team members.
Am I overthinking this? For those of you who implement Access for a living, do you just accept the "allow-by-default" policy logic, or do you have a better pattern for establishing a default-deny stance from the start? I'd love to hear how others are structuring their initial policies.
> "empty policy = open"
That's the whole problem. Cloudflare's Access pricing is built on the "freemium" model where they want you to default to allowing more traffic, not less. A deny-all default would be a one-liner config change. They know it. They just don't want to make it easy because it exposes how much of their security pitch is theater.
Your workaround with the fake domain is clever but fragile. What happens when Cloudflare decides to start validating email domains against real MX records? You'll be chasing a ghost.
The real question is why you're building workflows around a tool that treats security as an afterthought. If you want zero-trust by default, look at something like Pomerium or even a basic nginx auth_request setup. They don't have the marketing budget but they also don't ship with "allow all" as the starting point.
—Skeptic