Safeguard
Security Guides•

How long should an OAuth authorization code live, and why once?

RFC 6749 says codes must expire shortly, with a maximum of 10 minutes recommended, and be used once. What reuse means and how a server should respond.

Safeguard Security Team
4 min read

An authorization code should live for seconds to a few minutes, with a maximum of 10 minutes recommended by RFC 6749, and it must be redeemable only once. If a code is used twice, the server must reject the second attempt and should revoke the tokens already issued from it.

What the code is for

In the authorization code flow, the redirect back to your app carries a code, not a token. The app then sends the code to the token endpoint and receives tokens. The code is a short lived, one use ticket that travels through the browser, where it can show up in history, logs and referrer headers.

Because it passes through such exposed places, the spec limits both its lifetime and its reuse.

What RFC 6749 says

The authorization code must expire shortly after it is issued, to reduce the risk of leaks. A maximum lifetime of 10 minutes is recommended. The client must not use a code more than once. If a code is used more than once, the authorization server must deny the request and should revoke, when possible, all tokens previously issued from that code. The code is also bound to the client identifier and the redirect URI.

RFC 9700 adds a related point: a code injection attempt will also fail if the legitimate user already redeemed the code and it was one time use only.

Implementation checklist

PropertyWhat to do
LifetimeShort, measured in seconds to a few minutes, never beyond 10 minutes
RandomnessUnguessable, from a cryptographically secure generator
Single useMark as used atomically at redemption
BindingStore client ID, redirect URI and PKCE challenge with the code
Reuse responseDeny, and revoke tokens issued from that code
LoggingLog the reuse event, but not the code value

Why atomic marking matters

If two requests present the same code at the same moment, a naive "check then mark" lets both succeed. Use a database transaction, a conditional update, or a cache operation that fails if the key was already consumed. Test it with concurrent requests, not just sequential ones.

What to do on reuse

Treat it as a possible theft signal. Reject the request with an error, revoke access and refresh tokens that came from that code, and consider ending the session. Record the client, time and source address so you can investigate.

A legitimate client can trigger reuse by retrying after a network timeout. That is one reason to return a clear error and let the user sign in again rather than silently accept the retry.

For client developers

  1. Send the code to the token endpoint once. If the call fails with a network error, restart the sign in flow rather than replaying blindly.
  2. Never log the full redirect URL, since it contains the code.
  3. Use PKCE so a stolen code is useless without your verifier.
  4. Strip the code from the address bar after handling, for example by replacing the history entry.

Try it yourself

Click through it at your own pace, or open it full screen. Look at how an API scan reports authentication findings, then compare with the checklist above for your own token endpoint.

Quick check

Can I make codes last longer to avoid errors?

Longer codes raise the leak window. The spec recommends 10 minutes at most, and most flows complete in seconds.

Does PKCE replace single use?

No. They work together. PKCE ties the code to the client that asked, and single use limits replay.

Safeguard's SBOM and dependency scanning shows which OAuth server and client libraries you ship. There is a free scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.