Skip to content

CLOUDFLARE

Read original ↗

From all-or-nothing to task-based OAuth consent

Summary

Cloudflare added OAuth scope customization to its third-party OAuth platform: client owners can mark specific scopes as optional, and at authorization time users can deselect those optional scopes to grant a narrower subset of an app's requested access. Previously the consent screen was all-or-nothing — the user could only approve the full requested set or deny outright — even though the OAuth spec already lets an authorization server issue a narrower grant than requested. The feature is scoped strictly to the current authorization request (not the client's full configured scope set), defaults to granting everything (so existing clients are unchanged), and shifts responsibility onto developers to check the granted scope set after the code exchange rather than assuming the full request was approved. The motivating case is MCP servers, which often request broad permissions an agent could use but most users would not want to grant in full.

Key Takeaways

  1. All-or-nothing consent doesn't fit granular permission models. As Cloudflare's permission surface grew more fine-grained (SaaS integrations, CLIs, internal tools, agents), a single approve/deny consent screen became hard to justify: an over-asking app left the user with only "grant everything" or "walk away." (Source: sources/2026-08-20-cloudflare-from-all-or-nothing-to-task-based-oauth-consent)

  2. Built on existing spec flexibility, not a protocol change. The OAuth spec already permits an authorization server to grant fewer scopes than requested. Cloudflare exposed that latitude at the consent UI rather than inventing new protocol machinery — so it works cleanly for every existing app. This is the partial grant path that most implementations leave unused.

  3. Required vs optional, marked by the client owner. When configuring an OAuth client, the owner passes an optional_scopes array alongside the full scopes array. Scopes not listed as optional are required; the user can deselect only the optional ones at consent time. See optional-oauth-scopes.

  4. Optional/required is evaluated against the authorization request, not the client's full configured set. A client configured with four scopes (two optional) that only requests two of them has just those two evaluated — scopes that weren't requested are never shown or enforced. This keeps the consent screen focused on the task at hand rather than every capability the app could ever ask for. (Source: sources/2026-08-20-cloudflare-from-all-or-nothing-to-task-based-oauth-consent)

  5. Safe-by-default for existing clients. If a client requests no optional scopes, the consent experience is unchanged; by default the consent screen still grants the full requested set. Opting into narrowing is explicit — nothing breaks for apps that never adopt it.

  6. Developers must check the granted scope set, not assume the request. When a user deselects optional scopes, the issued access token contains only the consented scopes. Apps must inspect the granted scope set after exchanging the authorization code and degrade gracefully within whatever subset they receive — the core discipline of partial-grant-handling.

  7. Graceful partial-grant handling is a trust signal. Cloudflare frames an app that "operates within whatever subset of permissions it receives" (e.g. an agent) as one users feel comfortable authorizing. Requesting only what's needed and marking the rest optional signals that the app respects the user's access decisions — least privilege as a UX and trust property, not just a security control.

  8. MCP servers are the driving use case. An MCP server may request a broad permission set because an agent could use all of it, but most users would not want an agent to hold that much access. Before this feature the only workaround was for the app developer to build a custom scope-selection screen before handing off to Cloudflare's consent flow; optional scopes fold that into the standard consent step. Cloudflare's Workers OAuth Provider is the implementation surface for MCP servers on Workers.

Systems & Concepts Extracted

Configuration example

Client registration marks a subset of the configured scopes as optional:

{
  "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"
  ]
}

If the client requests all four scopes, user-details.read and workers-scripts.write remain required while the user may deselect workers-kv-storage.write and zone.read. If the client later requests only workers-scripts.write and zone.read, only those two are evaluated for that flow — the un-requested scopes are neither shown nor enforced.

Operational Numbers

Metric Value
Third-party OAuth apps created since June thousands
Authorizations since June > 1 million
Default consent behavior grants full requested scope set

Caveats

  • Feature-launch post with limited internals. This is a product announcement; it describes the consent-model design but carries no latency, throughput, or storage numbers and no engine-internal detail (that lives in the OAuth for all Ory-Hydra upgrade post). Included as in-scope because it documents a concrete authorization / consent design decision and its rationale.
  • Grant narrowing is user-side only. Users can deselect optional scopes; they cannot narrow required scopes or add scopes beyond what the client requested.
  • Broader role/scope rollout pending. Cloudflare states it will expand account- and zone-level roles to cover nearly every product "over the next few weeks" — the scope surface referenced here is not yet complete at publication.

Source

Last updated · 766 distilled / 2,225 read