Skip to content

chore(deps): bump @cloudflare/workers-oauth-provider from 0.10.4 to 1.1.0 in /cod-server - #135

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/cod-server/cloudflare/workers-oauth-provider-1.1.0
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/cod-server/cloudflare/workers-oauth-provider-1.1.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Sep 28, 2026

Copy link
Copy Markdown
Contributor

Bumps @cloudflare/workers-oauth-provider from 0.10.4 to 1.1.0.

Release notes

Sourced from @​cloudflare/workers-oauth-provider's releases.

v1.1.0

Minor Changes

  • #335 c1a8a40 Thanks @​mattzcarey! - Add helpers for authorization servers that sign users in through another OAuth provider, implementing the MCP security best practices' confused-deputy protections.

    • beginConsent() / approveConsent() / denyConsent() run a consent page whose handle is bound to the browser by a __Host- cookie, single-use and valid for ten minutes, with frame-ancestors 'none' and X-Frame-Options: DENY. approveConsent({ scope }) takes the scopes the user chose on the page, fewer or more than requested, each in scopesSupported.
    • approveConsent(…, { remember: { secret } }) and isConsentRemembered() remember an approval per call in a signed cookie bound to the client, redirect URI and resource, covering only the approved scopes. Without remember, consent is asked every time.
    • beginUpstream() / finishUpstream() store the approved request server-side, create the third party's state only after consent, bind it to the browser, and return it once at the callback with your data (such as a PKCE verifier).
    • cookiePrefix renames the cookies; it must start with __Host-.
    • An OAuthError('invalid_grant') thrown from tokenExchangeCallback now revokes the grant the callback ran for, with its access tokens, before answering. invalid_grant can never recover (RFC 6749 §5.2), so the client re-authorizes instead of retrying, and outstanding access tokens stop working immediately. Throw temporarily_unavailable for transient upstream failures to keep the grant.

    Transactions are stored in OAUTH_KV under transaction:{sha256(handle)}, encrypted with a key derived from the handle, with a ten-minute TTL; each has its own binding cookie, so concurrent authorizations in one browser don't collide. remember.subject binds a remembered approval to the signed-in user. denyConsent() returns the access_denied redirect back to the client with its state and iss. See docs/consent-page.md and docs/upstream-sign-in.md.

Patch Changes

  • #323 a1225a7 Thanks @​chiliec! - updateClient() no longer applies clientRegistrationTTL to clients created through createClient().

    It re-applied the TTL to every client it wrote, so updating a pre-registered client silently gave it an expiry. The TTL is now preserved only for records stamped with registrationExpiresAt; other records are written permanently. Dynamic registrations written before that stamp existed therefore become permanent when updated.

v1.0.0

Major Changes

  • #289 a6c2e4a Thanks @​mattzcarey! - Split the authorization server and resource server roles, and bind every token to one canonical resource. Migration guide: docs/migration-1.0.md — for most 0.x deployments the diff is adding resourceMetadata: { resource }.
    • OAuthAuthorizationServer declares its resources at construction and validates its access tokens for any of them with validateToken(resource, token, env). Metadata advertises the registry as RFC 9728 protected_resources. Every resource is hosted by OAuthResourceServer, in the same Worker or another: its validateToken option returns the validator for a request, the host calls it with its own canonical resource and the bearer token, and the two topologies differ only in what that points at, (env) => (resource, token) => authorizationServer.validateToken(resource, token, env) locally or (env) => env.AUTH_SERVER.validateToken over a Service Binding to a WorkerEntrypoint (AuthorizationServerBinding types it). resolveExternalToken stays on the combined OAuthProvider only; a role-based resource that must accept another issuer's tokens does so in its own validateToken.
    • OAuthResourceServer publishes RFC 9728 metadata (a cache-busting query does not hide it; a resource's own query must be present), issues Bearer challenges, and enforces audience and expiry on whatever the validator returns.
    • Handlers on both hosts receive ctx.auth (token, audience, expiresAt, scope, userId, clientId) beside ctx.props; the initial 401 names scopes_supported; insufficientScope(ctx.auth, scopes) builds the MCP 403 insufficient_scope challenge with every required scope and the resource's metadata URL. A validator may report scope, userId and clientId; malformed values fail closed.
    • Every new grant and access token is bound to exactly one registered resource. A multi-resource server requires resource unless defaultResource is set; code exchange and refresh inherit the grant's resource and reject retargeting; a new grant replaces only same-resource grants.
    • Stored 0.x state keeps working. A sole resource, or legacyGrantResource, is the migration target for grants and tokens without one; an array audience resolves to the registered resource it contains; a grant that cannot be bound fails refresh with invalid_grant, which conformant clients answer with a new authorization.
    • Breaking: resourceMetadata.resource is required and canonical (http only on loopback hosts). Construction rejects routes the resource does not cover, absolute routes on another origin or with a conflicting query, hosted resources whose queries nest, and resources inside the metadata namespace. Removed: resourceMatchOriginOnly, registerResource(), the three-argument validateToken(), the originOnly parameter of resourceMatches(), and EmaValidationInput.matchOriginOnly. ResolveExternalTokenResult.audience is required and a single string; ExchangeTokenOptions.aud, AuthRequest.resource, and TokenExchangeCallbackOptions.resource are single strings.
    • Protocol: redirect_uri on a code exchange must equal the authorization request's (OAuth 2.1 §4.1.3); registered grant_types are enforced with unauthorized_client; token exchange is bound to the grant's client unless tokenExchangeCallback returns allowCrossClientExchange: true, and subject-token failures return invalid_request; an empty resource path equals /; a repeated identical resource is accepted; challenges carry resource_metadata on the resource and its path descendants; discovery answers HEAD and OPTIONS, every 405 carries Allow, and a query-bearing resource accepts extra request parameters.

Minor Changes

  • #317 1e0aa19 Thanks @​mattzcarey! - Bound the KV work completeAuthorization() does to revoke a user's earlier grants for the same client.

    Every grant key now carries its clientId, resource and redirectUri as KV key metadata, so the grants a new authorization replaces are found from list() alone. The cost is one list() per thousand grants the user has instead of one get() per grant, which exceeded a Worker's subrequest limit for a user with more than a few hundred grants on the paid plan, or a few dozen on the free plan.

    Grants written before this version have no key metadata and are still read individually; revokeExistingGrantsBatchSize now bounds how many of those are read at once (default 50, maximum 1000) rather than the list() page size. A refresh rewrites its grant with metadata, so that share shrinks on its own. Nothing about tokens, refresh tokens or grant records changes, and no migration is needed.

  • #327 6e03aaa Thanks @​mattzcarey! - onError.internal is now set on every error the library originates, not only the EMA path: { category, reason, detail? } names the exact check that failed (refresh_token_mismatch vs refresh_token_expired vs grant_not_found, code_replayed, client_secret_mismatch, resource_not_configured, …) while the wire response stays exactly as before (RFC 6749 §5.2). The shape is exported as OAuthErrorInternal; category slugs are kebab-case subsystems, reason slugs snake_case checks, and both are stable. OAuthError accepts options.internal so a tokenExchangeCallback can tag its own errors; one thrown without it reaches onError as { category: 'token-exchange-callback', reason: 'callback_error', detail: error }.

  • #318 2181402 Thanks @​mattzcarey! - Add opt-in sliding expiry for refresh tokens.

    A grant's lifetime is fixed at the code exchange by default: it expires refreshTokenTTL seconds later however often it is refreshed. The new refreshTokenIdleTTL option makes that lifetime slide, moving the grant's expiry, and the KV expiration of its record, to that many seconds after every successful refresh. tokenExchangeCallback can return refreshTokenIdleTTL during a refresh to set the lifetime for that refresh alone, so a Worker that proxies an upstream OAuth service can give the grant exactly the lifetime of the upstream refresh token it just rotated.

    The slide happens only when a refresh succeeds: a throwing callback, an expired grant, or a grant that expires while the callback runs leaves the old expiry in place. Returning refreshTokenIdleTTL for any other grant type, or a value that is not an integer of at least 60 seconds, is rejected with invalid_request. Nothing changes for deployments that do not set it.

  • #319 2c902a7 Thanks @​mattzcarey! - Keep dynamically registered clients alive while they are in use.

    A DCR registration expired clientRegistrationTTL after it was created, whatever the client was doing. A grant that outlived its registration, which any never-expiring or long-lived grant does, then failed every refresh with invalid_client although nothing had been revoked. Registrations written under the TTL now record when they expire, and a successful client-authenticated token endpoint request made in the second half of that lifetime rewrites the registration for the full TTL, at most once per half TTL per client.

... (truncated)

Changelog

Sourced from @​cloudflare/workers-oauth-provider's changelog.

1.1.0

Minor Changes

  • #335 c1a8a40 Thanks @​mattzcarey! - Add helpers for authorization servers that sign users in through another OAuth provider, implementing the MCP security best practices' confused-deputy protections.

    • beginConsent() / approveConsent() / denyConsent() run a consent page whose handle is bound to the browser by a __Host- cookie, single-use and valid for ten minutes, with frame-ancestors 'none' and X-Frame-Options: DENY. approveConsent({ scope }) takes the scopes the user chose on the page, fewer or more than requested, each in scopesSupported.
    • approveConsent(…, { remember: { secret } }) and isConsentRemembered() remember an approval per call in a signed cookie bound to the client, redirect URI and resource, covering only the approved scopes. Without remember, consent is asked every time.
    • beginUpstream() / finishUpstream() store the approved request server-side, create the third party's state only after consent, bind it to the browser, and return it once at the callback with your data (such as a PKCE verifier).
    • cookiePrefix renames the cookies; it must start with __Host-.
    • An OAuthError('invalid_grant') thrown from tokenExchangeCallback now revokes the grant the callback ran for, with its access tokens, before answering. invalid_grant can never recover (RFC 6749 §5.2), so the client re-authorizes instead of retrying, and outstanding access tokens stop working immediately. Throw temporarily_unavailable for transient upstream failures to keep the grant.

    Transactions are stored in OAUTH_KV under transaction:{sha256(handle)}, encrypted with a key derived from the handle, with a ten-minute TTL; each has its own binding cookie, so concurrent authorizations in one browser don't collide. remember.subject binds a remembered approval to the signed-in user. denyConsent() returns the access_denied redirect back to the client with its state and iss. See docs/consent-page.md and docs/upstream-sign-in.md.

Patch Changes

  • #323 a1225a7 Thanks @​chiliec! - updateClient() no longer applies clientRegistrationTTL to clients created through createClient().

    It re-applied the TTL to every client it wrote, so updating a pre-registered client silently gave it an expiry. The TTL is now preserved only for records stamped with registrationExpiresAt; other records are written permanently. Dynamic registrations written before that stamp existed therefore become permanent when updated.

1.0.0

Major Changes

  • #289 a6c2e4a Thanks @​mattzcarey! - Split the authorization server and resource server roles, and bind every token to one canonical resource. Migration guide: docs/migration-1.0.md — for most 0.x deployments the diff is adding resourceMetadata: { resource }.
    • OAuthAuthorizationServer declares its resources at construction and validates its access tokens for any of them with validateToken(resource, token, env). Metadata advertises the registry as RFC 9728 protected_resources. Every resource is hosted by OAuthResourceServer, in the same Worker or another: its validateToken option returns the validator for a request, the host calls it with its own canonical resource and the bearer token, and the two topologies differ only in what that points at, (env) => (resource, token) => authorizationServer.validateToken(resource, token, env) locally or (env) => env.AUTH_SERVER.validateToken over a Service Binding to a WorkerEntrypoint (AuthorizationServerBinding types it). resolveExternalToken stays on the combined OAuthProvider only; a role-based resource that must accept another issuer's tokens does so in its own validateToken.
    • OAuthResourceServer publishes RFC 9728 metadata (a cache-busting query does not hide it; a resource's own query must be present), issues Bearer challenges, and enforces audience and expiry on whatever the validator returns.
    • Handlers on both hosts receive ctx.auth (token, audience, expiresAt, scope, userId, clientId) beside ctx.props; the initial 401 names scopes_supported; insufficientScope(ctx.auth, scopes) builds the MCP 403 insufficient_scope challenge with every required scope and the resource's metadata URL. A validator may report scope, userId and clientId; malformed values fail closed.
    • Every new grant and access token is bound to exactly one registered resource. A multi-resource server requires resource unless defaultResource is set; code exchange and refresh inherit the grant's resource and reject retargeting; a new grant replaces only same-resource grants.
    • Stored 0.x state keeps working. A sole resource, or legacyGrantResource, is the migration target for grants and tokens without one; an array audience resolves to the registered resource it contains; a grant that cannot be bound fails refresh with invalid_grant, which conformant clients answer with a new authorization.
    • Breaking: resourceMetadata.resource is required and canonical (http only on loopback hosts). Construction rejects routes the resource does not cover, absolute routes on another origin or with a conflicting query, hosted resources whose queries nest, and resources inside the metadata namespace. Removed: resourceMatchOriginOnly, registerResource(), the three-argument validateToken(), the originOnly parameter of resourceMatches(), and EmaValidationInput.matchOriginOnly. ResolveExternalTokenResult.audience is required and a single string; ExchangeTokenOptions.aud, AuthRequest.resource, and TokenExchangeCallbackOptions.resource are single strings.
    • Protocol: redirect_uri on a code exchange must equal the authorization request's (OAuth 2.1 §4.1.3); registered grant_types are enforced with unauthorized_client; token exchange is bound to the grant's client unless tokenExchangeCallback returns allowCrossClientExchange: true, and subject-token failures return invalid_request; an empty resource path equals /; a repeated identical resource is accepted; challenges carry resource_metadata on the resource and its path descendants; discovery answers HEAD and OPTIONS, every 405 carries Allow, and a query-bearing resource accepts extra request parameters.

Minor Changes

  • #317 1e0aa19 Thanks @​mattzcarey! - Bound the KV work completeAuthorization() does to revoke a user's earlier grants for the same client.

    Every grant key now carries its clientId, resource and redirectUri as KV key metadata, so the grants a new authorization replaces are found from list() alone. The cost is one list() per thousand grants the user has instead of one get() per grant, which exceeded a Worker's subrequest limit for a user with more than a few hundred grants on the paid plan, or a few dozen on the free plan.

    Grants written before this version have no key metadata and are still read individually; revokeExistingGrantsBatchSize now bounds how many of those are read at once (default 50, maximum 1000) rather than the list() page size. A refresh rewrites its grant with metadata, so that share shrinks on its own. Nothing about tokens, refresh tokens or grant records changes, and no migration is needed.

  • #327 6e03aaa Thanks @​mattzcarey! - onError.internal is now set on every error the library originates, not only the EMA path: { category, reason, detail? } names the exact check that failed (refresh_token_mismatch vs refresh_token_expired vs grant_not_found, code_replayed, client_secret_mismatch, resource_not_configured, …) while the wire response stays exactly as before (RFC 6749 §5.2). The shape is exported as OAuthErrorInternal; category slugs are kebab-case subsystems, reason slugs snake_case checks, and both are stable. OAuthError accepts options.internal so a tokenExchangeCallback can tag its own errors; one thrown without it reaches onError as { category: 'token-exchange-callback', reason: 'callback_error', detail: error }.

  • #318 2181402 Thanks @​mattzcarey! - Add opt-in sliding expiry for refresh tokens.

    A grant's lifetime is fixed at the code exchange by default: it expires refreshTokenTTL seconds later however often it is refreshed. The new refreshTokenIdleTTL option makes that lifetime slide, moving the grant's expiry, and the KV expiration of its record, to that many seconds after every successful refresh. tokenExchangeCallback can return refreshTokenIdleTTL during a refresh to set the lifetime for that refresh alone, so a Worker that proxies an upstream OAuth service can give the grant exactly the lifetime of the upstream refresh token it just rotated.

    The slide happens only when a refresh succeeds: a throwing callback, an expired grant, or a grant that expires while the callback runs leaves the old expiry in place. Returning refreshTokenIdleTTL for any other grant type, or a value that is not an integer of at least 60 seconds, is rejected with invalid_request. Nothing changes for deployments that do not set it.

  • #319 2c902a7 Thanks @​mattzcarey! - Keep dynamically registered clients alive while they are in use.

... (truncated)

Commits
  • 3352a2f Version Packages: 1.1.0 (#330)
  • c1a8a40 feat: consent and upstream sign-in helpers; revoke the grant on invalid_grant...
  • 46432a9 docs(readme): lead with the 1.0 split API (#331)
  • a1225a7 fix: keep createClient() clients permanent in updateClient() (#323)
  • a64e834 docs(agents): only humans merge Version Packages PRs (#329)
  • c93e05b Version Packages: 1.0.0 (#304)
  • d07e655 docs: 1.0 migration guide, agent skill, EMA experimental status (#328)
  • 6e03aaa feat: onError.internal on every generic error path (#327)
  • 65b1808 feat: ctx.auth, scope hints on 401, and insufficientScope() for handlers (#326)
  • 16fa151 refactor!: OAuthResourceServer is a class, like the other two roles (#325)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [@cloudflare/workers-oauth-provider](https://github.com/cloudflare/workers-oauth-provider) from 0.10.4 to 1.1.0.
- [Release notes](https://github.com/cloudflare/workers-oauth-provider/releases)
- [Changelog](https://github.com/cloudflare/workers-oauth-provider/blob/main/CHANGELOG.md)
- [Commits](cloudflare/workers-oauth-provider@v0.10.4...v1.1.0)

---
updated-dependencies:
- dependency-name: "@cloudflare/workers-oauth-provider"
  dependency-version: 1.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added the dependencies Pull requests that update a dependency file label Sep 28, 2026
@vercel

vercel Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
codflow-theme01 Ready Ready Preview Sep 28, 2026 9:31am UTC

@dependabot @github

dependabot Bot commented on behalf of github Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #152.

@dependabot dependabot Bot closed this Oct 5, 2026
@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/cod-server/cloudflare/workers-oauth-provider-1.1.0 branch October 5, 2026 09:38

This branch was successfully deployed

1 active deployment
Preview — 5ab9aca3 Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants