Do not use UUIDs as secret tokens, password reset links or share URLs where possession grants access. The UUID standard itself says implementations should not assume UUIDs are hard to guess and must not use them as security capabilities. Generate a purpose-built random token instead.
What the standard says
RFC 9562 describes version 4 UUIDs as built from 122 random bits, with 6 bits fixed for version and variant. It warns that a predictable random number source is a vulnerability and recommends a cryptographically secure generator.
Its security section is blunt: implementations should not assume UUIDs are hard to guess, and UUIDs must not be used as security capabilities, meaning identifiers whose mere possession grants access.
OWASP adds that version 1 UUIDs are not random at all, since they combine a timestamp with a hardware address, and that whether a version 4 UUID uses a secure generator depends on the implementation.
Why 122 bits is not the whole story
The size looks fine. The trouble is in what you cannot see:
- Your UUID library may use a general-purpose generator, not a CSPRNG.
- Some identifier versions embed time, so they leak creation order and narrow guesses.
- UUIDs get logged, put in URLs, copied into tickets and exposed in APIs because they are treated as ordinary identifiers. A secret needs a different handling habit.
- Developers copy UUID generation into new code without checking which version it creates.
What to do instead
For a token that grants access:
- Generate at least 128 bits, or 16 bytes, from your platform's CSPRNG. See our guide on how long a random token should be.
- Encode it with base64url or hex.
- Store only a hash of it server-side, so a database leak does not hand out live tokens.
- Give it an expiry and make it single-use where it fits, as in a reset flow.
- Check authorization on every request as well. A hard-to-guess link is not a substitute for an access check.
UUIDs remain perfectly good as identifiers for rows and objects. The point is to keep identification and authorization apart.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how each result names the exact place to fix.
Quick check
Is UUIDv4 fine as a database primary key?
Yes, as an identifier. Just never rely on it staying secret.
What about UUIDv7?
It embeds a timestamp, so it is even less suitable as a secret. Use it for sortable identifiers only.
Sources
Last reviewed: 19 October 2026.