Follow-up from the admin-panel OAuth refresh work in #13007 and ClickHouse/librechat-admin-panel#46.
Problem
/api/admin/oauth/refresh now correctly refuses to refresh when OPENID_REUSE_TOKENS is disabled, returning 403 TOKEN_REUSE_DISABLED. However, the initial admin OAuth exchange path can still include the IdP refreshToken in the /api/admin/oauth/exchange response and the admin panel stores it in its server-side session.
That does not currently allow session extension when reuse is disabled because the refresh endpoint fails closed, but it is policy-inconsistent and leaves an unnecessary sensitive token in the admin-panel BFF session.
Proposed fix
When generating the admin OAuth exchange code/response, only include the OpenID refresh token when token reuse is enabled. In practice this likely means gating the refreshToken passed to generateAdminExchangeCode in api/server/controllers/auth/oauth.js on isEnabled(process.env.OPENID_REUSE_TOKENS).
Also consider whether non-OpenID admin OAuth providers should omit refreshToken unless the admin panel has a supported refresh route for that provider.
Acceptance criteria
- With
OPENID_REUSE_TOKENS=false, admin OAuth exchange responses do not include a refresh token.
- With
OPENID_REUSE_TOKENS=true, OpenID admin OAuth exchange behavior is unchanged.
- Add focused coverage for both env-flag branches.
This is defense-in-depth/policy cleanup, not a blocker for #13007 because the refresh endpoint already refuses to use the token when reuse is disabled.
Follow-up from the admin-panel OAuth refresh work in #13007 and ClickHouse/librechat-admin-panel#46.
Problem
/api/admin/oauth/refreshnow correctly refuses to refresh whenOPENID_REUSE_TOKENSis disabled, returning403 TOKEN_REUSE_DISABLED. However, the initial admin OAuth exchange path can still include the IdPrefreshTokenin the/api/admin/oauth/exchangeresponse and the admin panel stores it in its server-side session.That does not currently allow session extension when reuse is disabled because the refresh endpoint fails closed, but it is policy-inconsistent and leaves an unnecessary sensitive token in the admin-panel BFF session.
Proposed fix
When generating the admin OAuth exchange code/response, only include the OpenID refresh token when token reuse is enabled. In practice this likely means gating the
refreshTokenpassed togenerateAdminExchangeCodeinapi/server/controllers/auth/oauth.jsonisEnabled(process.env.OPENID_REUSE_TOKENS).Also consider whether non-OpenID admin OAuth providers should omit
refreshTokenunless the admin panel has a supported refresh route for that provider.Acceptance criteria
OPENID_REUSE_TOKENS=false, admin OAuth exchange responses do not include a refresh token.OPENID_REUSE_TOKENS=true, OpenID admin OAuth exchange behavior is unchanged.This is defense-in-depth/policy cleanup, not a blocker for #13007 because the refresh endpoint already refuses to use the token when reuse is disabled.