Does OAuth consent really have to be all-or-nothing?
Hey everyone, it's me! I found a Cloudflare blog post that made me go "ohh, that makes sense" about OAuth consent, so let's dig in!
Cloudflare BlogWhat was announced?
Cloudflare's Engineering blog published a piece explaining how they're moving OAuth consent from an all-or-nothing model to a task-based one. It landed alongside the Cloudflare Changelog announcement of the "Optional OAuth Scopes" feature that makes this possible, and this blog post digs into the reasoning and context behind it.
Why it matters
Until now, users could only approve everything an app requested or reject everything. The post uses MCP servers as an example: MCP servers tend to request a broad set of permissions because an agent could theoretically use any of them, but most users don't actually want to hand an agent that much access. Even when there's a real gap between what a user wants to grant and what an app asks for, there was no middle ground before.
What changes
Developers building an OAuth client can now register scopes in two groups: scopes (required) and optional_scopes (optional). The post includes an example API call like this.
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/oauth_clients" \
--request POST \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"client_name": "ACME Corp",
"scopes": [
"user-details.read",
"workers-scripts.write",
"workers-kv-storage.write",
"zone.read"
],
"optional_scopes": [
"workers-kv-storage.write",
"zone.read"
]
}'
Only the scopes listed in optional_scopes become individually toggleable on the user's consent screen. If a user unchecks an optional scope and completes authorization, the resulting access token only contains the scopes they actually agreed to. That means an app can't assume it always gets every scope it asked for — it needs to be built to work with whatever subset the user actually grants.
Dive Deep
The task-based approach is designed so the consent screen doesn't get overwhelming: required scopes are still approved together as a bundle, and only optional scopes get individual toggles. Turning every single scope into its own checkbox tends to make users click through without really reading, so keeping required scopes bundled while making optional ones selectable seems to be the sweet spot between security and usability.
The post shows what the consent screen actually looks like through screenshots, though the written detail on the UI itself is fairly light — worth checking the original if you're curious.
Wrap-up
- Cloudflare explains why it's moving OAuth consent from all-or-nothing to task-based
- MCP servers are cited as a case where AI agents tend to request broad permissions
- Developers register scopes as
scopesandoptional_scopes; users can decline optional ones individually - The resulting access token only contains the scopes the user actually agreed to
If you're building AI agents or MCP servers and thinking about permission design, this one's worth a read!