Coalesce Token Refresh and Normalize Failures
Let one runtime refresh while every waiter rechecks the authoritative vault version. • Lab status: conceptual reconstruction. Receipts are expected simulated outputs, not deployed-system measurements.
System map · Day 08
Whole-system design
Five stable layers. Today's work is expanded and linked; the rest stays in context.
Entry and policy
Covered — Client entry · Browser and callback
Onboarding and control
Covered — Connector control plane
Authorization services
Authorization server
Design target · not proved
Receives one upstream refresh for concurrent callers and returns a typed success or failure.
Compute and execution
Covered — External resource server
Connector runtime compute
Design target · not proved
Detects stale authority, joins the shared refresh flight, and retries only after durable renewal.
Refresh coordinator compute
Design target · not proved
Combines local singleflight with a distributed lease and completion signal across processes.
Storage and evidence
Covered — Specification draft store · Connector configuration store · Sanitized discovery cacheAhead — Ordered migration log
Traversed today
Overview
Why an expiring token becomes a distributed-systems problem
Day 07 proved that a runtime can resolve and inject one credential safely. With several runtimes, the same near-expiry token can trigger concurrent refresh requests. If refresh-token rotation is enabled, the first request may invalidate the credential used by the rest, producing a storm or false reauthentication.
Today you will combine in-process singleflight with a distributed lease and completion signal, then normalize provider failures without copying sensitive prose. Refresh-token handling follows the base lifecycle in OAuth 2.0 and the rotation/replay guidance in RFC 9700.
Elect one refresher and make waiters recheck
Singleflight coalesces callers in one process. A distributed lease with a fencing version elects one refresher across processes. The winner rereads the vault, refreshes only if the version is still stale, atomically persists the rotated result, and signals waiters. Every waiter rereads the vault after the signal; it never trusts token material in a message.
const lease = await coordinator.tryAcquire({ key: grantId, ttlMs: 10_000 });
if (!lease.acquired) {
await coordinator.waitForVersion(grantId, currentVersion + 1);
return vault.read(grantId);
}
const latest = await vault.read(grantId);
if (latest.version !== currentVersion && isFreshAndUsable(latest)) return latest;
if (latest.version !== currentVersion) throw new Error("ambiguous_grant_state");
return refreshAndPersistAtomically(latest, lease.fence);
{
"grantId": "grant-d04",
"versionBefore": 7,
"versionAfter": 8,
"refreshCalls": 1,
"waitingCallers": 11,
"tokenMaterialInSignal": false
}
Map provider failures to stable gateway actions
Provider strings vary and may contain sensitive detail. The gateway maps a bounded set of protocol facts to stable categories: retryable transport failure, throttled, invalid grant requiring reauthentication, invalid client requiring operator repair, and permanent policy denial. Unknown errors stop safely with a correlation ID.
{
"providerError": "invalid_grant",
"gatewayCategory": "reauth_required",
"retryAutomatically": false,
"secretFieldsPersisted": false
}
{
"receipt": "SCG-R08",
"callers": 12,
"refreshRequests": 1,
"committedVersions": [8],
"normalizedFailure": "reauth_required",
"unaffectedControl": "other-grant-version-3"
}
The failure path kills the lease holder after contacting the provider but before commit. If the provider might have rotated the refresh token, the vault is now stale and rereading it cannot prove recovery; the next holder must stop, reconcile with provider-supported state when available, or require a fresh Day 04 authorization transaction. A fence prevents a stale process from overwriting a newer local version, but it cannot undo an upstream rotation. Another grant remains the unaffected control. Cleanup expires test leases, removes signals, and destroys disposable grant versions.
Score one recovery action
Given lease state, vault versions, and one normalized provider category, choose only retry, reauthorize, or stop. A transient transport failure within budget may retry; invalid_grant means reauthorize; stale fencing or ambiguous state means stop and reconcile. The evidence is one action plus the decisive supplied fact.
The misconception is “a lock means the token is current.” Replay a waiter after notification and show why the vault recheck is authoritative. Decline arbitrary provider-text classification, unbounded retries, or sending token material through coordination messages.
Carry the token ledger forward
SCG-R08 records caller count, one refresh, fence/version transition, waiter rechecks, normalized errors, recovery, unaffected grant, and cleanup. Day 09 consumes that ordered credential state when mirroring writes and deciding whether a migration may cut over.