A one-time passcode (OTP) is a code your server generates and sends to someone over SMS, email, voice or chat. The floor and the ceiling come from the National Institute of Standards and Technology (NIST), the US body whose security standards most of the industry follows. A code produced by an authenticator app follows different rules, covered in OTP vs TOTP vs HOTP.
How long should the passcode stay valid?
Ten minutes at most, and it works only once inside that window.
NIST SP 800-63B, NIST's guideline for authentication, puts two obligations on your server: reject a passcode older than ten minutes, and reject one you have already accepted. Section 3.1.3.2:
In all cases, the authentication SHALL be considered invalid unless completed within 10 minutes. Verifiers SHALL accept a given authentication secret as valid only once during the validity period to provide replay resistance
When someone submits the right code, mark it used. Reject that code if it arrives again, even inside its ten minutes.
Ten minutes is the limit, not the target. The clock starts when you issue the code, so delivery comes out of the window. A passcode that takes forty seconds to arrive leaves nine minutes and twenty seconds to read and type. Measure your own delivery times before you pick a window (how to measure OTP delivery time).
How many digits should it have?
Six, drawn at random.
NIST puts the floor at six decimal digits, generated by an approved random bit generator. That rules out a counter, a timestamp, or anything else a stranger could work out. The same section states the requirement:
The verifier SHALL generate random authentication secrets that are at least six decimal digits (or equivalent) in length using an approved random bit generator as described in Sec. 3.2.12.
Six digits alone is one code in a million, which a script can guess. NIST closes that gap with an attempt limit, not more digits: count failed attempts against the account, and leave that count where it is when you issue a new code. The same section adds:
Generating a new authentication secret SHALL NOT reset the failed authentication count.
Otherwise anyone who can press resend has unlimited guesses. Section 3.2.2 caps the count at 100 consecutive failed attempts on one authenticator, after which your server locks that code path for the account. That is the highest cap NIST permits, and a much lower one costs you nothing. Five attempts against a six-digit code give a guesser 5 chances in 1,000,000, about one in two hundred thousand.
Should I use eight digits instead?
Use eight when the action behind the code is worth the extra typing.
Eight digits is one code in a hundred million, against six digits' one in a million. A guesser capped at five attempts goes from 5 chances in 1,000,000 to 5 in 100,000,000, a hundred times harder to hit. The cap is already doing most of that work. Two more digits also lengthen what someone reads off one screen and types into another, often the same handset.
If you cannot rate limit at all, length is the only lever you have. Fixing the rate limiting is the better repair.
What can I set in Bird?
You set the passcode policy once per workspace, in five fields.
code_length, digits in a generated passcode, 4 to 8.code_type, the character set,numericoralphanumeric. The verification response reports which one applied.ttl_seconds, how long a verification stays open, 1 to 59940, up to 16 hours 39 minutes. The top of that range runs well past NIST's ten minutes, so keep your own value under ten minutes.max_attempts, incorrect submissions allowed before the verification fails, 1 to 10.resend_cooldown_seconds, the minimum wait between sends to one recipient, 0 to 3600.
A single verification can override those values in its own request. Each verification reports the settings that applied to it as its resolved settings.
What should I choose?
- Six digits, with an attempt cap behind them.
- A window sized from your own arrival times. Use your slowest typical delivery time, then add time to type.
- An attempt cap in the low single digits, counted against the account.
- A resend cooldown, so a new code is not a way around the cap.
- Single use, enforced the moment the code is accepted.
In short
A passcode is valid for ten minutes at most.
NIST SP 800-63B, the US federal standard for authentication, requires an out-of-band authentication to fail unless it completes within ten minutes.
A passcode works once.
The same section requires a verifier to accept a given secret only once inside its validity period, so mark a code used the moment you accept it.
Six random digits is the floor.
NIST requires at least six decimal digits from an approved random bit generator, which puts a guesser at one code in a million.
A resend does not clear the failed-attempt count.
NIST caps consecutive failed attempts on the account, and requires that issuing a new code leave that count where it is.
Delivery time comes out of the window.
The clock starts when you issue the code, so a passcode that takes forty seconds to arrive leaves nine minutes and twenty seconds to read and type.
Bird sets the policy per workspace.
code_length,code_type,ttl_seconds,max_attemptsandresend_cooldown_secondsare set per workspace, and each verification reports the values that applied to it.