NIST's digital identity guidelines say an out-of-band authentication is invalid unless completed within 10 minutes, each secret may be accepted once, and the secret must be at least six decimal digits. Verifiers also rate limit failed attempts, up to a cap of 100.
Definition
An out-of-band code is a secret your system sends to a separate channel, such as a text or an email, which the user then types back. NIST SP 800-63B, in its current revision, covers these authenticators. This post uses that text as a reference. Whether it binds you depends on your context, so treat it as a strong baseline.
What the guidance says
| Property | Guidance |
|---|---|
| Lifetime | Invalid unless completed within 10 minutes |
| Reuse | Each secret accepted once during that window |
| Length | At least six decimal digits or equivalent |
| Short secrets | If shorter than 64 bits, the verifier must rate limit failed attempts |
| Attempt cap | No more than 100 failed attempts before disabling that authenticator; agencies may set lower |
| Resets | Generating a new secret does not reset the failed attempt count |
| Push notifications | Verifiers should limit how many are sent since the last successful authentication |
| SMS and voice | The public telephone network for out-of-band is a restricted authenticator, and an unrestricted alternative must be offered |
Applying it
Six digits has only a million possibilities, so the rate limit is what protects it. A code that lives ten minutes with unlimited guesses is weak. A code with a small attempt budget is far stronger.
The line about resets matters. If your flow lets an attacker request a new code and thereby clear the failed counter, brute force becomes feasible again. Count failures per account across codes, not per code.
Resends need their own limit. Without one, an attacker can flood a user's phone or inbox, or run up your sending costs. See throttling reset and OTP endpoints and what SMS pumping is.
Steps
- Generate codes with a cryptographically secure random generator.
- Expire at ten minutes or sooner, and invalidate on first successful use.
- Store only a hash of the code server side where practical.
- Count failed attempts per account, and keep the count when a new code is issued.
- Set an attempt cap well under 100 for consumer flows, and lock or add friction when it is hit.
- Limit resends per account and per destination, and tell the user a code was sent without confirming whether the account exists.
- Offer a stronger option such as a passkey or authenticator app.
Where Safeguard fits
Safeguard's API security scanning helps spot verification endpoints with no visible rate limit, and its policies help keep the check in your release gates. The free scan is at https://gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Is ten minutes mandatory for my app?
It is NIST guidance for the agencies and contexts it covers. Many teams adopt it as a reasonable default.
Do longer codes remove the need for rate limits?
Longer codes help, but rate limits remain good practice for any guessable secret.
Sources
Last reviewed: 19 October 2026.