Token Expiry & Renewal

Introduction

Token expiry and renewal are core parts of modern API security. Most protected APIs do not ask users to send usernames and passwords with every request. Instead, a user or client authenticates once and receives an access token. The client sends that access token to protected APIs until the token is no longer valid. If access tokens stayed valid forever, a leaked token could be used forever. To reduce that risk, secure systems give access tokens a limited lifetime.

When an access token expires, the API should reject it. In many OAuth 2.0 and JWT-based systems, the response is `401 Unauthorized` because the token is no longer valid authentication for the protected resource. The client then needs a way to continue without forcing the user to log in again after every short token lifetime. That is where token renewal comes in. Many systems issue a refresh token that can be sent to the authorization server to obtain a new access token.

This design balances security and usability. Short-lived access tokens limit the impact of token theft. Refresh tokens allow users to stay signed in and continue working. The user does not need to type credentials again every few minutes, but the API still avoids trusting a single access token indefinitely. This is why token expiry and renewal are common in web applications, mobile applications, enterprise portals, cloud services, OAuth 2.0 systems, OpenID Connect implementations, and microservice architectures.

For API testers, token expiry and renewal must be tested directly. It is not enough to call an API once with a valid token. A good test strategy verifies valid access, expired access, invalid access, missing access, refresh-token renewal, refresh-token expiry, refresh-token revocation, refresh-token rotation, logout behavior, password-change behavior, account disablement, secure storage, and safe logging. Many serious security defects appear only when tokens move through their lifecycle.

What Is Token Expiry?

Token expiry is the point at which an access token becomes invalid because its configured lifetime has ended. After expiry, the token should no longer allow access to protected resources. The API should reject requests that use the expired token, even if the token was valid when it was first issued. Expiry is usually defined by the authorization server when it creates the token.

In OAuth token responses, expiry is often communicated through an `expires_in` field. For example:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Here, `expires_in` means the access token is valid for 3600 seconds, or one hour. In JWT systems, the token itself may include an `exp` claim:

{
  "exp": 1752000000
}

The resource server compares the current time with the expiration time. If the current time is past the expiration value, the token must be rejected. A system that accepts expired tokens has weakened its security model because the configured token lifetime is no longer meaningful.

Why Tokens Expire

Tokens expire to reduce risk. An access token is a credential. If an attacker steals it, the attacker may call protected APIs as the token holder until the token stops working. A short token lifetime limits that window. If an access token is valid for 15 minutes, the risk from token theft is smaller than if the same token is valid for six months. Expiry is a simple but powerful control.

Token expiry also supports periodic revalidation. User permissions can change. Accounts can be disabled. Passwords can be reset. Consent can be revoked. Client applications can be suspended. Short token lifetimes force the system to recheck authorization conditions more often, especially when combined with refresh-token policies or token introspection. This helps access control stay aligned with current account state.

Expiry also improves session management. Applications can provide a smooth user experience while still limiting how long one issued access token is trusted. A user can remain signed in through refresh tokens, but the actual access token used against APIs remains short-lived. This is a common pattern in enterprise and consumer applications.

Typical Token Lifetimes

Token lifetime is implementation-specific. An access token may be valid for 5 minutes, 15 minutes, 30 minutes, 1 hour, or another configured period. A refresh token may be valid for days, weeks, months, or until revoked. The right value depends on the sensitivity of the system, client type, regulatory requirements, user experience, and risk tolerance.

TokenCommon Lifetime PatternReason
Access TokenMinutes to hoursLimits direct API access if stolen
Refresh TokenDays, weeks, or monthsMaintains user sessions without repeated login
Authorization CodeSeconds to minutesShort-lived one-time exchange value
Device CodeMinutesLimited time for user verification

Testers should not assume one universal lifetime. The expected expiry values should come from the API documentation, identity provider configuration, or security requirements. If the documentation says access tokens expire after one hour, the API should reject the token after that period. If refresh tokens expire after 30 days, renewal should fail after expiry.

What Happens When a Token Expires?

When an access token expires, a protected API should reject requests using that token. A common response is:

GET /employees
Authorization: Bearer expiredAccessToken

HTTP/1.1 401 Unauthorized

The client should not continue retrying the same expired token. Instead, it should obtain a new access token if a refresh mechanism is available. In a well-designed application, the client may detect the `401`, call the token endpoint with a refresh token, receive a new access token, and retry the original API request. This renewal behavior should be controlled so it does not create infinite retry loops.

If the refresh token is also expired or invalid, the client should usually redirect the user to login or ask the user to authenticate again. The exact user experience depends on the application. From the API perspective, expired tokens must be denied, and renewal must happen only through the authorization server.

What Is Token Renewal?

Token renewal, also called token refresh, is the process of obtaining a new access token after the current access token expires. This is commonly done by sending a valid refresh token to the authorization server. The refresh token proves that the client is still allowed to obtain new access tokens without requiring the user to log in again.

A refresh request commonly looks like this:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
refresh_token=abc123xyz

A successful response may return a new access token:

{
  "access_token": "newAccessToken",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Some systems also return a new refresh token. That pattern is called refresh token rotation. Token renewal is handled by the authorization server, not the resource server. The resource server should not accept refresh tokens for protected business APIs.

Access Token vs Refresh Token

Access tokens and refresh tokens have different jobs. The access token is sent to protected APIs. The refresh token is sent to the authorization server to obtain new access tokens. The access token is short-lived and used frequently. The refresh token is usually longer-lived and used only when renewal is needed.

FeatureAccess TokenRefresh Token
PurposeAccess protected APIsObtain new access tokens
Sent toResource serverAuthorization server
Typical lifetimeShort-livedLonger-lived
Used frequentlyYes, with API callsOnly during renewal
Risk if stolenAPI access until expiry or revocationAbility to obtain new access tokens

This separation is fundamental in testing. If an expired access token is accepted by the resource server, expiry validation is broken. If a refresh token is accepted by a resource server as if it were an access token, token type enforcement is broken. If an invalid refresh token produces a new access token, renewal validation is broken.

Refresh Token Expiry

Refresh tokens also expire. They usually live longer than access tokens, but they should not be trusted forever unless the system has a very specific design and compensating controls. Refresh token expiry may be absolute, where the token expires after a fixed time, or sliding, where activity extends the session until a maximum lifetime is reached. Some systems rotate refresh tokens on every use.

When a refresh token expires, the authorization server should reject renewal requests. A common OAuth-style error is `invalid_grant`, often with `400 Bad Request`. The user usually needs to authenticate again to obtain fresh tokens. If an expired refresh token still works, the session can continue beyond the intended security policy.

Refresh token expiry should also account for client type. A backend web app can store refresh tokens more securely than a browser-only application. A mobile app has platform secure storage but still runs on a user's device. Public clients may require stricter rotation and expiry policies. Testers should validate behavior according to the client architecture.

Refresh Token Rotation

Refresh token rotation means the authorization server issues a new refresh token each time the old refresh token is used. The old refresh token then becomes invalid. This improves security because a stolen old refresh token is less useful after legitimate use. It can also help detect suspicious reuse. If an old refresh token is used again after rotation, the authorization server may treat that as a possible compromise.

Old Refresh Token
  -> Authorization Server
  -> New Access Token
  -> New Refresh Token

Testing rotation is important. A valid refresh token should return a new access token and a new refresh token if rotation is enabled. The old refresh token should fail after use. The new refresh token should work for the next renewal. Reusing an old refresh token should produce the documented error. If the old token keeps working, rotation is not actually enforced.

Rotation also affects client behavior. The client must store the new refresh token safely and replace the old one. If the client fails to update stored refresh tokens, users may be logged out unexpectedly. Testing should include both server-side behavior and client-side handling where possible.

Token Revocation

Token revocation means making a token invalid before its natural expiration time. Tokens may be revoked when a user logs out, changes password, loses permission, has an account disabled, reports suspicious activity, revokes application consent, or when an administrator disables a client. Revocation is important because waiting for natural expiry may be too risky in some situations.

Revocation is easier in some token designs than others. Opaque tokens can be checked against server state or introspected. JWT access tokens are often validated statelessly, which can make immediate revocation harder unless the system uses short lifetimes, revocation lists, session identifiers, key rotation, or introspection. Refresh tokens are usually easier to revoke because they are checked by the authorization server during renewal.

API testers should validate revocation policies explicitly. If logout is supposed to revoke refresh tokens, verify that renewal fails after logout. If password change should invalidate existing sessions, verify that old refresh tokens stop working. If account disablement should block access, verify both access-token behavior and refresh behavior. The expected timing should be documented because distributed systems may have propagation delays.

Token Expiry in API Testing

Token expiry testing verifies that APIs reject tokens after their configured lifetime. A valid token should work before expiry. The same token should fail after expiry. If the token is a JWT, the API should enforce the `exp` claim. If the token is opaque, the API or gateway should enforce the stored expiration. The result should be consistent with the API contract.

Testing expiry can be done in several ways. In a test environment, the identity provider may issue short-lived tokens, such as tokens valid for one minute. The tester can wait for expiry and call the API. Another approach is to use controlled test tokens with expired claims. Some teams provide test utilities or mock identity providers. The key is to validate the API's actual behavior rather than only reading token contents.

Clock skew is a practical detail. Distributed systems may allow a small tolerance to account for time differences between servers. This tolerance should be controlled. A token that expired one second ago may be treated differently from one that expired hours ago depending on policy. Testers should understand expected skew before filing defects.

Token Renewal in API Testing

Token renewal testing verifies that a valid refresh token can obtain a new access token and that invalid renewal attempts fail. A successful refresh response should include a new access token, expiry information, and optionally a new refresh token. The new access token should work against protected APIs. The expired old access token should remain rejected. If refresh token rotation is enabled, the old refresh token should no longer work.

Negative renewal tests are just as important. An invalid refresh token should fail. An expired refresh token should fail. A revoked refresh token should fail. A refresh token belonging to one client should not work for another client. A refresh request with missing `grant_type` or wrong `grant_type` should fail. A refresh request over HTTP should be blocked in secure environments. A refresh token should not be accepted at normal business endpoints.

Renewal tests should also check response safety. Token endpoint errors should not reveal secrets or internal token lookup details. Logs should not print access tokens or refresh tokens. Automation reports should mask token values. If test tools capture requests and responses, sensitive fields should be redacted before sharing.

Client-Side Renewal Behavior

Token renewal is not only a server-side concern. The client application must also handle expiry correctly. A good client should know when an access token is close to expiry, request a new token when appropriate, store the new token safely, and retry the original API request only when retrying makes sense. Poor client handling can create visible user problems even when the authorization server and API are working correctly.

Some applications renew tokens proactively. They check the token expiry time before making a protected API call and refresh the token if it is about to expire. This can avoid unnecessary `401 Unauthorized` responses. Other applications renew reactively. They call the API, receive `401`, refresh the token, and retry the failed request. Both approaches can work, but both need clear rules. The client should not refresh on every error. It should not keep retrying forever. It should not use an old refresh token after rotation. It should not continue working silently after renewal fails.

Client-side behavior should also respect user session rules. If the refresh token is expired, revoked, or invalid, the client should stop trying to renew and require login again. If the user logs out, stored tokens should be cleared according to the application design. If the account is disabled, renewal should fail and the user should not remain active through cached credentials. These behaviors affect security and user experience, so they deserve testing in web, mobile, and desktop clients.

For API testers, this means token testing can extend beyond direct API calls. Backend API tests prove that expired and invalid tokens are rejected. End-to-end or integration tests can prove that the client reacts correctly when a token expires. A complete strategy validates both: the API must reject expired credentials, and the client must recover or fail cleanly without exposing tokens or creating retry loops.

Diagnosing Token Expiry Failures

When token expiry or renewal fails, the first step is to identify which component rejected the request. A protected API may reject an expired access token. An API gateway may reject it before the backend service receives it. The authorization server may reject a refresh token. The client may fail before sending the request because it believes the token is expired. Each failure points to a different area of investigation.

If an API returns `401 Unauthorized`, check whether the access token is missing, expired, malformed, revoked, signed by the wrong issuer, intended for the wrong audience, or sent with the wrong authorization scheme. If the token endpoint returns `invalid_grant`, check whether the refresh token is expired, revoked, reused after rotation, tied to another client, or submitted with incorrect parameters. If an API returns `403 Forbidden`, the token may be valid but lack the required scope or permission.

Logs can help, but they must be safe. Security logs should identify the reason category without exposing full token values. A useful log may say that token validation failed because of expiry or audience mismatch. It should not print the full access token or refresh token. Testers should verify that troubleshooting information exists, but also confirm that sensitive credentials are redacted.

Clear diagnosis is valuable during defect reporting. Instead of saying "login is not working," a tester can report that an expired access token is accepted by the resource server, a rotated refresh token can be reused, or a revoked refresh token still produces a new access token. Specific reports reduce debugging time and help developers fix the correct security layer.

Example Test Cases

ScenarioExpected ResultPurpose
Valid access token calls protected API200 OK or expected success statusConfirms active token access works
Expired access token calls protected API401 UnauthorizedConfirms expiry enforcement
Invalid access token calls protected API401 UnauthorizedConfirms untrusted tokens are rejected
Valid refresh token requests renewalNew access token returnedConfirms renewal works
Expired refresh token requests renewal400 Bad Request or invalid_grantConfirms refresh expiry
Revoked refresh token requests renewalDocumented OAuth errorConfirms revocation
Old refresh token reused after rotationRejectedConfirms rotation enforcement
Refresh token sent to resource APIRejectedConfirms token type separation

REST Assured Example

A valid access-token API call in REST Assured may look like this:

given()
  .header("Authorization", "Bearer " + accessToken)
.when()
  .get("/employees")
.then()
  .statusCode(200);

A refresh-token request can be sent to the token endpoint:

given()
  .formParam("grant_type", "refresh_token")
  .formParam("refresh_token", refreshToken)
.when()
  .post("/oauth/token")
.then()
  .statusCode(200);

In a real automation framework, the test should extract the new access token from the response and verify that it works. If rotation is enabled, the framework should capture the new refresh token and verify that the old one fails. Credentials and tokens should come from secure configuration. Request logging should mask the authorization header and token response fields.

Postman Example

In Postman, access tokens are usually used through the Authorization tab by selecting Bearer Token. The token is sent in the `Authorization` header. For renewal testing, the tester sends a POST request to the token endpoint with form fields such as `grant_type=refresh_token` and `refresh_token=<value>`. The response should return a new access token when the refresh token is valid.

Postman can also automate renewal using pre-request scripts, but testers should be careful. Automatic refresh can hide expiry behavior if every request silently renews before the test observes failure. Keep separate tests for expired access-token rejection and successful renewal. Store tokens in environments only when appropriate, and avoid exporting real token values in shared files.

Karate Example

Karate can send access tokens and refresh requests clearly:

Given header Authorization = 'Bearer ' + accessToken
When method GET
Then status 200
Given form field grant_type = 'refresh_token'
And form field refresh_token = refreshToken
When method POST
Then status 200

Karate is useful for lifecycle testing because one scenario can obtain a token, another can call a protected API, and another can validate refresh behavior. Use clear variable names such as `validAccessToken`, `expiredAccessToken`, `validRefreshToken`, and `revokedRefreshToken` so test intent remains readable.

Real-World Examples

Google APIs use access tokens with limited lifetimes. Refresh tokens can allow applications to obtain new access tokens without requiring the user to sign in again, depending on the OAuth flow, consent, and provider policy. Microsoft Graph also uses access tokens and refresh behavior for long-running authenticated sessions. Tokens must match the correct audience, tenant, scopes, and expiry rules.

Banking applications often use short-lived access tokens to reduce the impact of token theft. A mobile banking app may require reauthentication for highly sensitive actions even if a token is still active. Enterprise applications use refresh tokens to maintain sessions while minimizing repeated logins. Microservices may use short-lived service tokens and renew them through client credentials or platform identity systems.

Security Best Practices

Use short-lived access tokens. Protect refresh tokens carefully. Always use HTTPS for token issuance, renewal, and protected API calls. Validate access-token expiration on every protected request. Revoke compromised tokens quickly. Implement refresh token rotation when appropriate. Bind refresh tokens to the correct client. Request only necessary scopes. Avoid issuing refresh tokens to clients that do not need them.

Never expose tokens in logs, URLs, screenshots, browser history, source code, downloadable reports, or shared API collections. Mask authorization headers and token endpoint responses. Store tokens securely according to the client type. Backend systems should use secure server-side storage or secret management. Browser and mobile clients need platform-specific storage decisions and additional protections.

Keep renewal behavior controlled. A client should not retry endlessly after a `401`. It should refresh once when appropriate, retry the original request, and fail cleanly if renewal fails. Infinite refresh loops can create poor user experience, extra load, and confusing logs. Testers should validate both successful and failed renewal paths.

Common Mistakes

A common mistake is using expired tokens and not handling the failure. Applications should detect expiry and renew tokens through the correct flow when possible. Another mistake is sending refresh tokens to protected resource APIs. Refresh tokens should go only to the authorization server. If resource servers accept refresh tokens, the token model is unsafe.

Storing tokens insecurely is also common. Access tokens and refresh tokens should not be hardcoded, logged, or casually stored in shared files. Refresh tokens are especially sensitive because they can obtain new access tokens. If a refresh token leaks, access can continue beyond a single access-token lifetime.

Ignoring token revocation is another serious issue. A token may become invalid before expiry due to logout, password change, account suspension, consent revocation, or admin action. Testers should verify that revocation rules are enforced. A system that accepts revoked tokens may allow access after the user or administrator intended it to stop.

Practical Testing Mindset

Think of token expiry and renewal as a timeline rather than a single request. The token is issued, used, expires, renewed, rotated, revoked, or rejected. Each event should have clear behavior. A strong API test suite follows that timeline and confirms that the system grants access only during the intended period and only through the intended path.

When a test fails, identify the exact layer. If an expired access token still works, resource-server validation is weak. If a valid refresh token cannot renew, token endpoint behavior may be broken. If an old refresh token works after rotation, rotation enforcement failed. If logout does not revoke renewal access, session termination policy may not be implemented. Clear diagnosis makes security defects easier to fix.

Interview Questions

A common interview question is: why do access tokens expire? A strong answer is that access tokens expire to limit the impact of stolen or leaked tokens and to reduce the duration of unauthorized access. Short-lived tokens are safer because they stop working after their configured lifetime.

Another question is: what is token renewal? Token renewal is the process of obtaining a new access token using a valid refresh token. The refresh token is sent to the authorization server, not to the protected API. If the refresh token is valid, the authorization server returns a new access token.

Interviewers may ask which token is sent to the resource server. The answer is the access token. They may ask which token is sent during renewal. The answer is the refresh token. They may also ask what testers should validate: token expiration, renewal, refresh-token expiry, revocation, rotation, correct status codes, invalid_grant errors, HTTPS, and secure token handling.

Interview-Ready Explanation

Token expiry means an access token becomes invalid after its configured lifetime. Once expired, the token should no longer access protected APIs, and the resource server commonly returns `401 Unauthorized`. Expiry reduces the risk of stolen tokens because the attacker can use the token only for a limited time.

Token renewal is the process of obtaining a new access token using a valid refresh token. The refresh token is sent to the authorization server, usually with `grant_type=refresh_token`. It is not sent to resource APIs directly. Refresh tokens are generally longer-lived than access tokens and must be protected carefully. Some systems use refresh token rotation, where each refresh returns a new refresh token and invalidates the old one.

During API testing, testers should validate valid access tokens, expired access tokens, invalid tokens, revoked tokens, refresh-token renewal, expired refresh tokens, revoked refresh tokens, refresh token rotation, logout behavior, password-change behavior, correct `401` and OAuth error responses, HTTPS usage, and secure token storage and logging. Good token lifecycle testing proves that API access is temporary, renewal is controlled, and revoked or expired credentials cannot continue to grant access.

Key Takeaway

Token expiry and renewal keep API security practical. Access tokens expire so leaked tokens cannot be used indefinitely. Refresh tokens allow clients to obtain new access tokens without forcing users to log in repeatedly. The access token goes to the resource server. The refresh token goes to the authorization server.

For API testers, the practical rule is to test the whole lifecycle. Verify valid access, expiry rejection, renewal success, refresh-token expiry, revocation, rotation, token type separation, status codes, and secure handling. A secure API does not only issue tokens correctly; it also expires, renews, rotates, and rejects them correctly.