You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Missing refresh token when using client credentials #116
The access token doesn't have a refresh token if we use client_credentials as grant_type - however the OAuthAccessTokenProvider tries to refresh the token if it's expired instead of requesting a new one, which results in this error:
oauth2-2.0.9/lib/oauth2/access_token.rb:118:in `refresh': A refresh_token is not available (RuntimeError)
microsoft_kiota_authentication_oauth-0.8.0/lib/microsoft_kiota_authentication_oauth/oauth_access_token_provider.rb:66:in `block in get_authorization_token'
Additional context from reviewing the current OAuthAccessTokenProvider#get_authorization_token implementation: the missing-refresh-token case is not the only issue in this control flow.
For an unexpired cached token, token.token is evaluated but does not exit the Fiber; execution continues to @token_request_context.get_token.
After a successful refresh!, the refreshed token is cached, but its string value is likewise discarded and another token acquisition follows.
For an expired token without a refresh token, refresh! raises before the code can request a replacement, as described in this issue.
A network-free probe with a stub context and an unexpired OAuth2::AccessToken confirmed that two consecutive requests to the same allowed host call get_token twice (Ruby 3.3 in Docker).
When fixing this, regression cases should distinguish:
An unexpired cached token is returned without another acquisition.
An expired token with a refresh token returns the refreshed token without a redundant acquisition.
An expired token without a refresh token requests a new token rather than calling refresh!.
Also see #190 for per-request default scopes. Cache reuse should remain consistent with the effective scopes when one provider is used across multiple allowed hosts.
The current diffs in #187 and #189 do not change this caching/refresh block; this remains a separate follow-up.
Activity
baywet commentedon Oct 23, 2026
Additional context from reviewing the current
OAuthAccessTokenProvider#get_authorization_tokenimplementation: the missing-refresh-token case is not the only issue in this control flow.Relevant code:
token.tokenis evaluated but does not exit the Fiber; execution continues to@token_request_context.get_token.refresh!, the refreshed token is cached, but its string value is likewise discarded and another token acquisition follows.refresh!raises before the code can request a replacement, as described in this issue.A network-free probe with a stub context and an unexpired
OAuth2::AccessTokenconfirmed that two consecutive requests to the same allowed host callget_tokentwice (Ruby 3.3 in Docker).When fixing this, regression cases should distinguish:
refresh!.Also see #190 for per-request default scopes. Cache reuse should remain consistent with the effective scopes when one provider is used across multiple allowed hosts.
The current diffs in #187 and #189 do not change this caching/refresh block; this remains a separate follow-up.