Skip to content

fix: self-heal OIDC token on a reused vmx_client() (GEN-2344)#14

Merged
jburos merged 1 commit into
mainfrom
feature/gen-2344-oidc-refresh
Jul 3, 2026
Merged

fix: self-heal OIDC token on a reused vmx_client() (GEN-2344)#14
jburos merged 1 commit into
mainfrom
feature/gen-2344-oidc-refresh

Conversation

@agentic-task-writer

Copy link
Copy Markdown
Contributor

Summary

  • Resolve the client bearer token per request via a provider closure instead of freezing the OIDC access token at construction, so a persistent con <- vmx_client() silently refreshes the short-lived access token from the cached refresh token and keeps working across a full session (no more vmx_auth_error minutes in).
  • Wrap .vmx_oidc_device_flow() failures (user-denied / code-expired / polling-exhausted) as vmx_auth_error; warn before overwriting a config-mismatched cache on interactive auto-login (and name the mismatch non-interactively) instead of silently clobbering the CLI-shared cache; reword the "no usable cached token" message to state the actual cause; document VMX_OIDC_TOKEN_CACHE as testing-only.

Closes GEN-2344

Design note

Scope offered either refresh-on-401+retry or a token-provider closure. Chose the closure (Option B): re-resolving per request lets the existing skew-based proactive refresh self-heal before a 401, whereas refresh-on-401 against a frozen client$token would 401→refresh→retry on every request after expiry (the frozen string never updates on the immutable client object). For the config-mismatch nit, chose the warn-before-overwriting floor (explicitly permitted by scope) so interactive auto-login still works while eliminating the silent-clobber harm.

Test plan

  • Reused-client stale path: construct client → simulate access-token expiry → next call on the same client refreshes + succeeds (the gap the fresh-client-per-call suite couldn't catch).
  • Skew boundary: a valid non-expired token is returned without refreshing; a token inside the 60s skew is refreshed.
  • Config-mismatch cache: interactive login warns before overwriting; non-interactive raises vmx_auth_error naming the mismatch.
  • Device-flow failures wrap to vmx_auth_error.
  • CI green (R-universe R CMD check runs the suite; R not available locally).

🤖 Generated with Claude Code

Resolve the bearer token per request via a provider closure instead of
freezing the OIDC access token at construction. A persistent
`con <- vmx_client()` (the dominant R idiom) now re-reads the cache and
silently refreshes the short-lived access token from the cached refresh
token, so it keeps working across a full session instead of throwing
vmx_auth_error minutes in.

Also addresses the agreed PR #13 review nits:
- Wrap .vmx_oidc_device_flow() failures (user-denied / code-expired /
  polling-exhausted) as vmx_auth_error so they stay in the vmx_error
  hierarchy.
- Don't silently clobber a config-mismatched cache on interactive
  auto-login: warn before overwriting (the cache is shared with the CLI);
  non-interactive raises a message naming the mismatch.
- Reword the "no usable cached token" message so it is accurate when a
  token exists but is expired-without-refresh or for another config.
- Document VMX_OIDC_TOKEN_CACHE as a testing-only override.

Tests: reused-client stale path (the structural gap), skew-boundary
(valid token returned without refresh; within-skew refreshed),
config-mismatch handling, and device-flow error wrapping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jburos jburos merged commit b759861 into main Jul 3, 2026
22 checks passed
@jburos jburos deleted the feature/gen-2344-oidc-refresh branch July 3, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant