Skip to content

Prevent concurrent redemption of rotating OAuth refresh tokens #514

Description

@zackbart

Motivation

Downstream OAuth connections created under different request scopes can independently observe and redeem the same expired refresh token. An authorization server that rotates refresh tokens may accept the first redemption and reject the second with invalid_grant; some providers also revoke the newly issued credential after reuse is detected.

Connecta's credential-generation fence prevents an older authorization flow from publishing over a newer generation. It does not establish ownership of an ordinary token refresh before the authorization server sees it.

Executor encountered this failure across concurrent MCP sessions and moved refresh ownership above the individual execution stacks: UsefulSoftwareCo/executor#1537. Connecta should establish its own guarantee without adopting Executor's session model.

Behavioral requirements

  • For one connector credential generation within one registry runtime, concurrent callers must share one refresh attempt rather than redeeming the same refresh token independently.
  • Every joined caller must observe the resulting credential or the same bounded failure.
  • A failed refresh must release ownership so a later call can retry.
  • A force reauthorization or issuer change must continue to invalidate work captured under an older generation.
  • One caller's cancellation or deadline must not corrupt the credential or strand another caller that joined the refresh.
  • The guarantee must remain honest about its coordination boundary. KVStorage has no atomic compare-and-set operation, so this issue does not claim exactly-once refresh across processes or Worker isolates.

Acceptance criteria

  • A regression test starts two OAuth-backed downstream connection attempts under distinct request scopes with the same expired credential.
  • The fake authorization server rotates refresh tokens and rejects a second redemption of the retired token.
  • The test observes exactly one refresh grant within a registry runtime and both callers can continue with the resulting credential.
  • Tests cover refresh failure followed by retry, cancellation of one joined caller, and a concurrent generation change.
  • Existing generation-fence and force-reauthorization tests continue to pass.
  • Downstream OAuth documentation states the runtime-local guarantee and the unresolved cross-runtime boundary.
  • npm run check passes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions