pub fn verify_bearer_token(
token: &str,
keys: &[ApiKeyEntry],
) -> Option<AuthIdentity>Expand description
Verify a bearer token against configured API keys.
Argon2id verification is CPU-intensive, so this should be called via
spawn_blocking. Returns the matching identity if the token is valid.
§Timing-side-channel resistance
Always performs exactly one Argon2id verification per configured key, regardless of:
- which slot (if any) matches the presented token, or
- whether a key has expired.
Expired and post-match slots are verified against an internal dummy PHC hash, a fixed Argon2id PHC string with the same cost parameters as the real hashes. This bounds the timing observable to “one Argon2 per configured key” regardless of which (if any) slot held the matching credential, closing the first-match latency oracle (CWE-208) and the expired-slot timing leak.
subtle::ConstantTimeEq folds each slot’s match bit into the running
result without comparing the token bytes in short-circuiting fashion.
The guarantee this function provides is the Argon2 count, not full
branchlessness: selecting verify_against and recording matched_index
are both ordinary data-dependent branches. They are cheap, predictable,
and operate on locals, so they are dwarfed by the Argon2id verification
that dominates every iteration – but the timing claim stops at
“one verification per configured key”. Do not read this as a
constant-time selection routine.
§Panics
Panics if the internal dummy PHC hash cannot be parsed as an Argon2id PHC string.
This is impossible by construction: the static is generated by
argon2::Argon2::hash_password which always emits a valid PHC string.