Skip to content

Commit f98ebed

Browse files
committed
feat(sdk): let a credential provider perform the OAuth refresh grant itself
Executor performed the OAuth refresh exchange itself, so it had to ask the credential provider for the stored refresh token and the client secret, which a sealed store cannot hand over. CredentialProvider gains an optional refreshGrant: the provider spends the refresh token, seals the new tokens under the same item ids and returns only lifetime and scope, which the host re-validates. Providers without it, client_credentials grants and first-party apps keep the existing host path unchanged.
1 parent d27e673 commit f98ebed

7 files changed

Lines changed: 1524 additions & 54 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@executor-js/sdk": minor
3+
---
4+
5+
`CredentialProvider` gains an optional `refreshGrant`. When a provider implements it, Executor asks it to perform the OAuth refresh exchange instead of asking it for the refresh token: the provider spends the token, seals the newly minted access token (and a rotated refresh token, if the authorization server sent one) under the same item ids, and reports only the granted lifetime and scope. Executor re-validates that metadata, reads the access token back through `get` like any other credential, and never resolves the refresh token or the client secret on that path.
6+
7+
A refused grant comes back as `RefreshGrantRejected` carrying a closed standards-defined token-endpoint code, so a delegated refusal classifies re-authentication, surfaces `invalid_grant` to the caller, and arms the known-dead gate exactly as a host-side refusal does. Providers that do not implement `refreshGrant` are unaffected, and so are the grants that have no refresh token to delegate.

‎packages/core/sdk/src/executor.ts‎

Lines changed: 346 additions & 50 deletions
Large diffs are not rendered by default.

‎packages/core/sdk/src/index.ts‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,18 @@ export type {
109109
} from "./connection";
110110
export type { Tool, ToolDef, ToolListFilter, ToolAnnotations } from "./tool";
111111
// Credential providers.
112-
export type { CredentialProvider, ProviderEntry } from "./provider";
112+
export {
113+
MAX_REFRESH_GRANT_EXPIRES_IN_SECONDS,
114+
RefreshGrantRejected,
115+
isRefreshGrantRejectionCode,
116+
} from "./provider";
117+
export type {
118+
CredentialProvider,
119+
ProviderEntry,
120+
RefreshGrantInput,
121+
RefreshGrantRejectionCode,
122+
RefreshGrantResult,
123+
} from "./provider";
113124

114125
// Public projections / detection.
115126
export { ToolSchemaView, ToolAnnotationsView, IntegrationDetectionResult } from "./types";

0 commit comments

Comments
 (0)