Repository navigation
Conversation
…gh a failed save A grant with no refresh token now reconnects before the host asks the store, as it does on the AES path and as usable reports. The store's renewed seal is written under the claim before the host re-seals it, so an adapter failure in that window leaves a claim that resumes from the rotated token instead of the replaced one. The adapter URL may not carry a query, the URL error moves to contracts, and the docs say the encryption key is still read.
… migration The adapter paragraph had split the accounts and deployments paragraph in two. It now follows that paragraph, wrapped like its neighbours, and says that turning the setting on or off after accounts exist leaves their records unreadable. The renew docs now say the store's encrypt must keep its own placeholders, and the comments state that a seal the host cannot open needs a new sign-in and that an interrupted store renewal can wait for four store calls.
… refusal rule exactly The host's own refresh accepts "expires_in":"3600" through oauth4webapi, so the store path now does too; before, the renewal failed as incompatible after the service had already rotated the refresh token. The CredentialsRenewalRefused doc now says what the classifier does: invalid_grant ends the grant only with the service's status.
A credentials store that passed the service's body as it came, with expires_in: null or a scope array, failed renewal before the resealed grant was saved, so a rotated refresh token was lost. The store path now runs the tokens through the same normalizedTokens the host applies to its own token response, and refuses a negative expires_in as invalid_response as oauth4webapi does on the host path instead of reading it as no lifetime.
This branch has not been deployed
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.
A custom
Credentialsstore on v2 only encrypts and decrypts, so at every renewal the host still decrypts the grant and sends the refresh token and client secret to the token endpoint from its own process. A store backed by a TEE or an HSM changes nothing about that.This adds optional
renewandrevoketoCredentials. When a store has them, the host calls the store for the refresh exchange and for the revocation after an account is deleted, keeps its own claim, lease and outcome classification, and never reads the refresh token or client secret. Self-host takesEXECUTOR_CREDENTIAL_ADAPTER_URLto use such a store over HTTP (/encrypt,/decrypt,/renew,/revoke, bytes as base64, 30 second wait per answer). The AES-GCM path is untouched. Two things to know: the setting is not a migration, nothing re-seals existing records, so it has to be on before the first account is saved; and the host still decrypts the store's reseal to set the renewed fields and lifetime and encrypts it again, so one renewal costs four adapter calls. The owner cascade in owners.ts deleting grants without revoking them is pre-existing and not touched here.This is #2084 redone in v2's shape, see #1585 for the series. Claude Code agents wrote and iterated it against the v2 tree under my direction. On a Mac mini the existing renewal, interruption, revocation and scheduled renewal scenarios passed against this tree with --test-name (14 on self-host, 1 on local) and bun run check was green. The adapter scenarios are in the tests PR stacked on this branch.