Principle:OpenHands OpenHands Token Refresh
| Knowledge Sources | |
|---|---|
| Domains | Distributed_Systems, Conversation_Management |
| Last Updated | 2026-02-11 21:00 GMT |
Overview
Token refresh is the practice of proactively renewing authentication credentials before they expire, ensuring that long-running agent conversations never encounter stale or revoked tokens mid-execution.
Description
Agent conversations in a SaaS environment rely on third-party provider tokens (OAuth tokens, API keys with expiration, short-lived JWTs) to access LLM APIs, Git hosting services, and other integrations. These tokens have finite lifetimes -- often measured in minutes to hours. A conversation that runs longer than the token's validity window will fail at an unpredictable point unless the system proactively refreshes credentials.
Token refresh addresses this by:
- Proactive renewal -- Refreshing tokens before they expire, rather than reacting to 401/403 errors at call time.
- Atomic replacement -- Swapping the old token for the new one in a way that in-flight requests using the old token can still complete.
- Scope preservation -- Ensuring the refreshed token retains the same scopes and permissions as the original.
- Persistence -- Storing the refreshed token so that conversation resumption after a node failover uses the latest credentials.
Usage
Use token refresh:
- Immediately after provisioning a runtime but before injecting credentials into it.
- Periodically during long-running conversations if the provider supports refresh tokens.
- Before replaying a conversation that was suspended and may have stale saved credentials.
Theoretical Basis
Token refresh follows the sliding window renewal pattern: at each renewal point, the system obtains a new token and advances the expiration window forward.
Pseudocode:
function refresh_provider_tokens(settings, conversation_id, user_id):
refreshed_settings = copy(settings)
for provider_name, token in settings.provider_tokens.items():
if token.is_expired() or token.expires_within(REFRESH_THRESHOLD):
# Obtain a fresh token using the refresh token
new_token = token_manager.refresh(
provider=provider_name,
refresh_token=token.refresh_token,
user_id=user_id,
)
# Validate the new token
validate_token_scopes(new_token, required_scopes=token.scopes)
# Replace in settings
refreshed_settings.provider_tokens[provider_name] = new_token
# Persist for durability across failovers
persist_token(conversation_id, provider_name, new_token)
return refreshed_settings
Key invariants:
- No silent failures -- If a token cannot be refreshed (refresh token revoked, provider down), the system must raise an explicit error rather than proceeding with stale credentials.
- Idempotency -- Refreshing an already-fresh token is a no-op; the system checks expiration before attempting renewal.
- Confidentiality -- Tokens are treated as secrets (wrapped in SecretStr or equivalent) and never logged in plaintext.