Token Expiration & Refresh Best Practices for APIs

Learn best practices for OAuth token lifecycles. Discover how to balance security and usability using short-lived access tokens, refresh tokens, and revocation.

Clifford Spielman |

Introduction

Token-based authorization in web APIs using OAuth is a common approach for controlling access to protected resources. APIs validate tokens presented with requests and use the information they contain to make authorization decisions.

Designing a secure token-based system requires making clear decisions about multiple factors, including how tokens are issued, validated, stored, and invalidated over time. Among these, three primary concerns are token expiration, refresh, and revocation. Each addresses a different aspect of how tokens behave throughout their lifetime and carries distinct security and usability trade-offs.

This article outlines high-level best practices for managing these three areas in OAuth-based web APIs. It focuses on conceptual guidance and architectural guardrails rather than implementation details or code examples.

Token Expiration

While authentication establishes who a caller is, authorization is how an API decides what a caller is allowed to do — often using information presented in an access token. Token expiration determines how long an API will accept an access token, both during normal operation and in the event of compromise.

In OAuth-based systems, access tokens are bearer credentials: possession alone is sufficient for use. Expiration places a hard upper bound on that risk window and is therefore a foundational design decision in any OAuth-based authorization strategy for web APIs.

Access tokens should be short-lived by default

Because access tokens are bearer credentials, short expiration times reduce the impact of token theft and are especially important in environments where tokens may be exposed through browser-based clients, logs, or intermediary systems. In practice, this often means lifetimes measured in minutes rather than hours. Longer-lived user sessions should be handled through refresh tokens rather than by extending access token lifetimes.

Expiration should be enforced using standard token claims

APIs validating JSON Web Tokens (JWTs) should rely on the expiration time (exp) claim to determine token validity and reject tokens that have expired. This check should occur on every request and be treated as a mandatory authorization condition, not an optional safeguard. Related claims such as "not before" (nbf) may also be used — when present — to limit token usage to a specific time window.

APIs should validate expiration locally and consistently

In token-based web APIs, expiration checks are typically performed as part of local token validation, alongside verification of the token signature, issuer (iss), audience (aud), and scopes or permissions (scope). APIs should not defer expiration decisions or other core token validation checks to downstream services, nor rely on client-side enforcement.

Expiration policy should be owned by the authorization server

Access token lifetimes are an issuance concern, not an API concern. Centralizing expiration configuration in the authorization server ensures consistent behavior across clients and APIs, allowing policies to evolve without redeploying APIs.

Expiration should not be treated as a substitute for revocation or logout

While expiration limits exposure over time, it does not provide immediate invalidation. Systems that require stronger guarantees must account for this limitation explicitly rather than assuming expiration alone provides revocation behavior.

Refresh Tokens

Refresh tokens are used to obtain new access tokens without requiring a user to reauthenticate. They allow access tokens to remain short-lived while still supporting longer-running sessions, making them a key part of balancing security and usability in token-based web APIs.

Refresh tokens should be treated as high-value credentials

Because a refresh token can be exchanged for new access tokens, its compromise often has more serious consequences than the theft of an individual access token. Systems should handle refresh tokens with stricter storage and handling requirements than access tokens, regardless of client type.

APIs should never receive or accept refresh tokens

Refresh tokens are intended for use with the authorization server as part of the refresh token grant. Resource servers should not see, store, or process refresh tokens under any circumstances in normal OAuth usage. Allowing refresh tokens to reach APIs increases the attack surface by introducing long-lived credentials into request handling, logging, and tracing paths. It also undermines the separation of responsibilities between authorization servers and resource servers.

Refresh token rotation, reuse detection, and reduced replay risk

Rotating refresh tokens on each use limits the impact of token theft by ensuring that a previously issued refresh token is no longer accepted after a successful refresh.

However, token rotation is not always an effective security strategy because sophisticated attackers can simply wait for the user's session to end, watch the rotations cease, and then use the last token in the chain to launch an attack.

Furthermore, rotation and replay detection introduces significant operational costs, including increased database pressure from constant token deletion and writing, and reliability problems, as a failed HTTP response with a new token can force the user to reauthenticate.

Using sender-constrained tokens with Dynamic Proof-of-Possession (DPoP) is typically a more effective security measure.

Client environment and risk profile should be accounted for in refresh token handling

The risks and constraints associated with refresh tokens differ significantly between browser-based applications and non-browser clients. Approaches that are appropriate for native or confidential clients may be unsafe in browser contexts. This is particularly true if refresh tokens are exposed to browser-managed storage accessible to JavaScript.

In browser-based applications, patterns such as Duende Software's Backend-for-Frontend (BFF) can further reduce exposure by keeping access tokens out of the browser entirely and enforcing expiration on the server side.

Refresh tokens should be used for session continuity, not authorization decisions

Refresh tokens exist to manage access token renewal and session duration. They should not be used to make authorization decisions directly, nor should their presence be interpreted as proof of current access rights without issuing and validating a new access token.

Token Revocation

Token revocation provides a means of invalidating tokens before their natural expiration kicks in. Unlike expiration, which limits access based on time, revocation relies on authorization server state to indicate that a token should no longer be accepted. This capability allows systems to respond to changing conditions by terminating access independently of token lifetime.

Revocation should be used primarily for cases requiring immediate invalidation

Revocation exists largely to intentionally invalidate tokens before their natural expiration when continued token acceptance is unacceptable, not to replace normal expiration behavior. Overreliance on revocation can make systems more complex and more susceptible to unintended side effects.

Systems that rely on revocation should account for the complexity it introduces

Because access tokens are typically validated locally, revocation requires some form of shared state or coordination to ensure that revoked tokens are consistently rejected. This often requires using revocation lists, token identifiers, or relying on refresh token invalidation to prevent further access.

Prefer revoking refresh tokens over revoking access tokens where possible

Revoking refresh tokens rather than access tokens reduces the need to track or invalidate individual access tokens, the latter being more challenging than revoking refresh tokens. This is because access tokens are validated locally across APIs rather than managed centrally by the authorization server. Another benefit is that it aligns revocation with the natural expiration process by allowing access tokens to expire as originally intended.

This tradeoff is even reflected in the OAuth specification, which recognizes refresh token revocation implementation as a primary requirement, while treating access token revocation as more of a recommended capability due to its added complexity.

Revocation mechanisms should be applied consistently across all resource servers

Partial or inconsistent enforcement undermines the effectiveness of revocation and can lead to unpredictable authorization behavior. Systems that rely on revocation should ensure that all APIs enforcing access are aware of and honor revocations.

Final Thoughts

Short-lived access tokens establish a predictable baseline by limiting how long a token can be used. Refresh tokens extend that model by allowing access to continue without reauthentication and making short-lived access tokens practical in reality. Systems that lean on expiration and refresh for normal operation can generally reserve revocation for the cases that genuinely require immediate access token invalidation.

Each of these mechanisms serves a distinct purpose, and systems tend to be more robust when those purposes and recommended best practices are adhered to during system development and implementation. Token expiration, refresh, and revocation each address different aspects of the same problem: controlling how long and under what conditions access is granted in a distributed system.

Identity providers such as Duende IdentityServer are designed around the best practices featured in this article, providing first-class support for short-lived access tokens, refresh token handling, and revocation workflows aligned with the OAuth specification.