Repository navigation
Refresh expiring oauth_token credentials at serving time - #686
Merged
TheGreatAxios merged 5 commits intoSep 8, 2026
Merged
TheGreatAxios merged 5 commits into
TheGreatAxios merged 5 commits into
Conversation
The serving-time refresh work needs a provider-agnostic OAuth refresh layer (skew-aware expiry, coalesced concurrent refreshes, pluggable refresh grant), and oauth-core already implements it as createTokenSession, but the package was never published. Hand-copy the initial-release sources with the VENDORED.md ledger row and its 2026-10-07 kill date in the same change.
getValidToken adapts oauth-core's createTokenSession onto the credential row's secret/refreshSecret/expiresAt columns: skew-aware expiry lead, concurrent refreshes coalesced into exactly one refresh grant per credential, and a pluggable refresh grant the hub supplies per credential class. Failure reports re-auth-required instead of throwing, and an api_key row takes its exact pass-through path untouched.
Wire the token session into the material-resolution path. The vendored db/hub-api/hub-sessions packages take a recorded local delta: buildSource gains an optional servingRefresh hook, threaded through resolveModelSources, resolveInstanceModelSources, resolveDefinitionSources, and the hub-sessions push path, which offers each served oauth_token credential to the hook and skips the offering as credential_needs_reauth when the hook cannot save it — an unauthenticated dial is never served, and an api_key credential never reaches the hook. The hub composes the hook in credential-material-refresh.ts: the connections token session refreshes the row in place (coalesced, skew-aware) through a pluggable grant (defaulting to the generalized MCP auth() refresh), the refreshed material reaches running deployments via the existing credentials-updated push, and a failed grant marks the credential status "error" so the settings Connections card shows needs-attention — the expiry sweep's mail remains the human nudge. The chat platform runs the tenant-wide refresh ahead of every sendMail, so serving time is the only trigger. Update the vendored delta notes and tree hashes in the same change.
The token session reloaded only the credential id for a refresh grant, so the grant's exchange inputs came from the row captured when the session was created — a second refresh sent the pre-rotation refresh secret, which rotating authorization servers reject as invalid_grant. Every grant call now receives the current persisted row, and the vendored session's rotated tokens are threaded through to the writer. applyRefreshedTokens' UPDATE now carries the status = active predicate its doc claims, and a false return is honored as a lost race (no error, no redundant push). A grant that states no expires_in used to store now + 120s, putting the row back in the due set for refresh-plus-push on every dial. Missing lifetime information now persists a NULL expiry — non-due, matching the vendored oauth-core stance. The serving-refresh module header now describes the live wiring: the chat sendMail choke point is the trigger, the MCP sweep remains the background backstop, and the buildSource seam is threaded but reserved pending launch-resolution wiring.
Contributor
Author
|
Self-review ( |
…als-at-serving-time
TheGreatAxios
deleted the
cl-7505-serve-refreshed-oauth_token-credentials-at-serving-time
branch
September 9, 2026 04:16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
oauth_tokencredentials refresh at serving time as a credential class: a tenant-wide pass runs ahead of every chatsendMaildial, refreshing any active credential whoseexpiresAtfalls inside a skew lead, with concurrent refreshes coalesced into exactly one grant per credential.@corbits/oauth-coreis vendored hand-copied undervendor/intx/oauth-corewith its VENDORED.md ledger row and 2026-10-07 kill date (the package is unpublished); the credential-row token session inpackages/connectionscomposes itscreateTokenSessiononto the credential table's secret/refreshSecret/expiresAt columns with a pluggable refresh grant generalizing the MCP precedent.buildSourcematerial-resolution seam gains an optional serving-refresh hook (recorded local delta, db/hub-api/hub-sessions) that skips an offering ascredential_needs_reauthwhen the hook cannot save it — threaded and tested, reserved pending launch-resolution wiring; the module header states the live wiring honestly.status: "error"(settings Connections card shows needs-attention), pushescredentials-updatedframes so instances re-resolve, and never serves a dead secret;api_keyrows take an unchanged pass-through path at every layer.Verification
bun run checkexits 0 before each commit (typecheck, lint, full test matrix, structural checks); the push-time pre-push gate ran the full suite green (935 pass / 0 fail on the final web shard).bun run scripts/checks/killdates.tsexits 0 (17 ledger hashes match their trees).Closes CL-7505