On this page · 12 sections
- What Cloudflare actually shipped
- The spec has allowed this since 2012, which is exactly the problem
- Google walked this path first, and documented the failure mode
- Where the two platforms differ
- The documentation is behind the feature
- This is an agent problem more than a dashboard problem
- What to change
- What is still unknown
- India-specific considerations
- FAQ
- How eCorpIT can help
- References
Summary. On 20 August 2026 Cloudflare added an optional_scopes array to its OAuth client configuration, letting a user deselect individual permissions on the consent screen. The consequence sits in one sentence of the announcement: "you need to check the granted scope set after exchanging the authorization code, rather than assuming the full requested set of scopes was approved." That is not a new rule. RFC 6749, published in October 2012, already says the authorization server "MAY fully or partially ignore the scope requested by the client" and MUST return a scope response parameter when the granted scope differs. What changed on 20 August is that a platform carrying more than a million authorizations since its 24 June 2026 launch will now actually exercise that clause. Cloudflare's own create-client documentation, last updated 3 June 2026, still does not mention optional_scopes. Adoption costs $0 - Cloudflare lists OAuth availability as Yes on Free, Pro, Business and Enterprise. The cost is the audit of every client that assumed a full grant.
What Cloudflare actually shipped
The announcement, published 20 August 2026 by Miller Vargas, Adam Bouhmad and José Enrique Rodríguez, adds one field. Scopes are still configured as before; a client now additionally marks which of them are optional:
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",
"redirect_uris": ["https://acme.org/oauth/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "client_secret_basic",
"scopes": [
"user-details.read",
"workers-scripts.write",
"workers-kv-storage.write",
"zone.read"
],
"optional_scopes": ["workers-kv-storage.write", "zone.read"]
}'
Four behaviours are worth pinning down, all stated in the post.
Required and optional scopes are evaluated per authorization request, not per client. Cloudflare is explicit that this matters: "OAuth clients do not always request their full configured scope set." In the example above, if the client later requests only workers-scripts.write and zone.read, then only those two are considered for that flow.
Existing clients are unaffected by default. "If a client does not opt into optional scopes, the consent flow remains unchanged", and "By default, the consent screen still grants the full requested scope set."
The token reflects what the user approved, not what the client asked for. "When a user deselects any optional scopes and completes the authorization flow, the generated access token will only contain the scopes they consented to."
And there is no deadline. No deprecation date, no forced migration, nothing to schedule.
The spec has allowed this since 2012, which is exactly the problem
Cloudflare grounds the change in a single unattributed sentence: "The OAuth spec already allows authorization servers to grant a narrower set of scopes than what was requested." It names no document and cites no section.
The section is RFC 6749 §3.3, Access Token Scope, and its wording is stronger than Cloudflare's paraphrase:
The authorization server MAY fully or partially ignore the scope requested by the client, based on the authorization server policy or the resource owner's instructions. If the issued access token scope is different from the one requested by the client, the authorization server MUST include the "scope" response parameter to inform the client of the actual scope granted.
Two things follow. First, a conforming client has never been entitled to assume it got what it asked for - this has been true for the entire life of OAuth 2.0. Second, the mechanism for finding out is the scope response parameter, and Cloudflare's post never names it. A developer reading only the blog post is told to "check the granted scope set" without being told which field carries it.
That gap is where the bugs live. Code that assumed a full grant does not throw on 20 August 2026; it keeps calling an API it no longer has permission for and fails at the resource server, in production, on whatever call happens to touch the deselected scope first.
Google walked this path first, and documented the failure mode
Google's granular permissions rollout is the closest precedent, and its guidance - last updated 26 May 2026 - is blunter than Cloudflare's. It labels the assume-everything pattern "Incorrect Approach: All or nothing", and describes the bug precisely: "It neglects to check which scopes users granted and assumes users granted all scopes."
Google also publishes the trigger conditions in a table, which Cloudflare does not.
| Sign-In scopes requested | Non-Sign-In scopes requested | Granular consent screen |
|---|---|---|
| 1-3 | 0 | Not applicable |
| 1-3 | 1 or more | Applicable |
| 0 | 1 | Not applicable |
| 0 | 2 or more | Applicable |
| Workspace app, domain-wide delegation or Trusted | Any | Not affected at this time |
And Google ships first-class API surface for the check. The Google Account Authorization JavaScript reference documents hasGrantedAllScopes() and hasGrantedAnyScope(), both returning booleans against a TokenResponse whose scope property is "a space-delimited list of scopes that are approved by the user". Google's own parameters for opting out of this behaviour, enable_granular_consent and enable_serial_consent, are now marked "Deprecated, no effect if set" - the escape hatch is closed.
Cloudflare ships no equivalent helper. The check is yours to write.
Where the two platforms differ
| Behaviour | Cloudflare, from 20 Aug 2026 | Google granular permissions |
|---|---|---|
| Who decides a scope is skippable | Developer, via optional_scopes |
Google, by scope count and type |
| Opt-in required by the developer | Yes | No, applied automatically |
| Helper to test granted scopes | None documented | hasGrantedAllScopes, hasGrantedAnyScope |
| Way to disable the behaviour | Do not set optional_scopes |
Deprecated, no effect |
| Documented failure guidance | One sentence in the blog post | A full guide with correct and incorrect code |
The design difference is real and defensible. Cloudflare's model puts the decision with the developer, so nothing changes until you choose it. Google's is imposed, so every multi-scope app had to be fixed. Cloudflare's is safer on day one and riskier over time, because the day a product manager marks a scope optional to improve consent conversion is the day the client-side assumption breaks, and nobody will connect the two changes.
The documentation is behind the feature
Cloudflare's create-an-oauth-client guide is the page a developer lands on to configure scopes. As of this writing it carries a last-updated date of 3 June 2026 and its worked curl example lists only scopes - optional_scopes does not appear on it at all. The OAuth overview page was refreshed on 14 August 2026, six days before the feature shipped, and does not mention it either.
There is also a small inconsistency inside the announcement itself. The JSON example uses user-details.read with a dot, and the prose two paragraphs later writes user-details:read with a colon. Scope strings are case-sensitive and exact under RFC 6749 §3.3, so if you are copying from the post, copy from the JSON.
This is an agent problem more than a dashboard problem
Cloudflare frames the value in agent terms: "an agent that operates within whatever subset of permissions it receives, is one that users feel comfortable authorizing."
That framing is right, and it raises the stakes. A human-driven integration that loses zone.read shows a broken page and a support ticket. An autonomous agent that loses workers-kv-storage.write mid-task will keep planning as though it still has the capability, and its failure surfaces as a partial write or an incoherent retry loop rather than a clean permission error. Teams building on the Cloudflare Agents SDK with Durable Objects need the granted scope set in the agent's own state, not just in the token exchange handler, or the planner cannot reason about what it is allowed to do.
Cloudflare has already been bitten by a related class of failure in this exact subsystem. Its OAuth for all post of 24 June 2026 describes an unexpected outcome after upgrading its Hydra OAuth engine: "if a refresh token was reused, Hydra would invalidate the whole access and refresh token chain. This is problematic for Wrangler and MCP clients. These clients both have a high request volume, and a single reused refresh token would invalidate the entire session." High-volume agent clients are the ones that find the sharp edges in authorization plumbing.
What to change
Four items, none of which need a maintenance window.
- Read the
scoperesponse parameter on every token exchange and store it alongside the access token. RFC 6749 §3.3 guarantees it is present when the grant differs from the request.
- Gate each feature on the specific scope it needs, not on the presence of a token. Google's guidance is to "handle any denial of scopes by disabling relevant features" rather than failing the whole session.
- Re-request narrowly and only on intent. Google's rule is to "only prompt the user for consent again once they have clearly indicated an intent to use the specific feature that requires the scope."
- Decide deliberately which of your scopes are optional before anyone else does. Cloudflare's advice - "Requesting only the permissions needed and marking the rest as optional is a good sign to users that your app respects their access decisions" - is sound, but the marking must follow the client-side handling, not precede it.
The engineering judgement here is simple: a permission model is only as good as the client's willingness to be told no. Most OAuth clients written in the last decade were never asked that question, because most authorization servers never said no partially.
What is still unknown
Cloudflare has not documented whether an app can detect a deselection before the token exchange, whether optional scopes appear in token introspection differently from required ones, or what happens on refresh when a user later revokes an optional scope from the Connected Applications page added in the 14 April 2026 changelog. The post promises that "over the next few weeks, we will be expanding our account and zone-level role surface to cover nearly every Cloudflare product", which means the scope catalogue itself is about to grow - and a larger catalogue makes partial consent more likely, not less.
India-specific considerations
For Indian teams building SaaS integrations, the Digital Personal Data Protection Act 2023 principle of collecting only what is necessary maps cleanly onto marking scopes optional: a permission the user declined is data you never process. The practical work is the same audit either way - enumerate the scopes each feature genuinely needs, then handle the case where one is missing. Public Cloudflare OAuth clients also require DNS-based domain verification, and Cloudflare polls the TXT record "until it is found or until the request times out after two days", so build that window into any launch plan that depends on a public client.
FAQ
How eCorpIT can help
eCorpIT's senior engineering teams build and audit OAuth integrations as part of API and platform work, including the per-scope feature gating that partial consent now requires. We are an ISO 27001:2022 certified, CMMI Level 5 organisation and design authorization flows aligned with Digital Personal Data Protection Act 2023 requirements. If you run integrations or agents against Cloudflare, Google or any provider that can narrow a grant, talk to us about the audit.
References
- From all-or-nothing to task-based OAuth consent - Cloudflare Blog, 20 August 2026
- Unlocking the Cloudflare app ecosystem with OAuth for all - Cloudflare Blog, 24 June 2026
- Introducing self-managed OAuth clients - Cloudflare Changelog, 3 June 2026
- Improved publisher verification details on OAuth consent screens - Cloudflare Changelog, 5 August 2026
- Improved OAuth experience for consent and management - Cloudflare Changelog, 14 April 2026
- OAuth Applications on Cloudflare - Cloudflare Fundamentals docs
- Create your OAuth client - Cloudflare Fundamentals docs
- RFC 6749: The OAuth 2.0 Authorization Framework - IETF, October 2012
- How to handle granular permissions - Google for Developers
- Google Account Authorization JavaScript API reference - Google for Developers
Last updated: 21 August 2026.