38QARV0-1ET0G6Z-2CJD9VA-2ZZAR0X
1. Use UUIDv7 as the base ID to leverage timestamps
2. Encode the ID using Crockford Base32 for readability
3. Add artfully placed dashes for aesthetics
It seems to me like an exercise in persuasion like how Steve Jobs was sold on the idea of the NeXT logo by Paul Rand[0]. I myself prefer good ideas to be self-evident, but I tend to underestimate the value of salesmanship.[0] https://modernspecies.com/blog/post/understanding-the-200k-l...
Nobody types out api keys so there is no need to make them friendly to say or remember. After you have copied and pasted them once into your db, you are never going to seee or use that string again!
All that said, I'm not sure the juice was worth the squeeze here - I don't think their new API keys look any more beautiful than a standard UUID. I like that they cared all the same, though.
Nobody is going to choose their product just because their API Keys.
But they are generating a halo effect. Is like going to a restaurant with outstanding bathrooms. If they put a lot of care in that, you immediately assume they do the same in all the other aspects of their product/service.
Will it make you feel better to know that you have the shinier valve which looks prettier? Maybe, but nobody else will ever know and it will work just the same as the valve everyone else has in their bathroom which cost 10% of the price.
No surprise then that it is the worlds most used accounting software, even though most of its users hate it.
It's a trivial library to write. 99% of it is just deciding what you want the output to look like + writing the blog post.
> The dashes do remove easy double-click copying, but we think this a fine trade off for readability. We don't want users copying and pasting them everywhere, in fact we want them to be handled with care. Ideally, users copy each key exactly once - when they generate the key from our dashboard - so we added a copy button to our UI to solve that case
Don't even think about copying/pasting that key, you rube!
I want to just double click and copy, dragging is annoying.
IMHO this makes key much more beautiful than any internal structure.
https://github.blog/engineering/platform-security/behind-git...
I also like prefixed resource IDs. Stripe is the first one that comes to mind, but I've run into it multiple times where a customer is describing an issue and it turns out the ID they're trying to lookup is for a different resource (often similar). You don't get those accumulated hours of support time back...
Also, I don't really want API keys and such to be generally pretty. If things that have no business being end-user facing are ugly then they are less likely to be allowed to accidentally become end-user facing.
If being pretty or otherwise user-friendly is a priority, then I'd go with trying to make them readable/pronounceable rather than shorter, even if that actually makes them longer. There are numerous projects out there¹²³ for doing just that. You could even use the 256-word example³ with multiple small dictionaries, and give people a choice from various possibilities that map to the same number.
----
[1] https://github.com/Debdut/uuid-readable
E.g.: user_2x4y6z8a0b1c2d3e4f5g6h7j8k
[0] https://freedium.cfd/https://medium.com/@cristian.nedelcu/fc...
[1] https://news.ycombinator.com/item?id=19298196
[2] https://marco.org/2007/06/18/wow-fckgw-has-its-own-wikipedia...
It's a cute idea, but I really don't like the extra level of indirection, especially as I feel like there's nothing gained. The base32 encoded key is no more beautiful that the uuid7. I think it's to easy for someone to look at this and go uuid7().upper() and assume that's the same thing, if they just look at the key.
I bring this up a lot [2] but I do think there is value in being able to tell if something is a secret and tell where to go to revoke it if found. Most current API keys use some sort of prefix at least (AWS, SendGrid, GitHub, etc).
[1]: https://docs.github.com/en/code-security/secret-scanning/int...
I used T.U.M. for a number of sites including one that was in the Alexa top 2000, even though it was open source it got no pickup from anyone else. The standard at the time was to pick up some software like PHPNuke which did a lot of things badly as opposed to my Yahoo-inspired approach of "pick the best of breed software and plug them into a common user management system".
The idea didn't get any traction until 2013 when things like this popped up like mushrooms. Seemed the missing features were "vendor lock-in", "somebody else owns your user database", "they might shut down, get bought by Google or kick you out of the free tier."
[1] I've seen it enough that I'd expect higher uptake if you inject small flaws into a specification like that.
its an alphanumeric random string in both systems.
yes theres is kinda symetrical. but im not going to find it easier to communicate/remember say:
38QARV0-1ET0G6Z-2CJD9VA-2ZZAR0X
any easier than i am
d1756360-5da0-40df-9926-a76abff5601d
both are long random strings. both are awkward to have to read over say a phone call.
what am I missing here?
Example: "d1756360-5da0-40df-9926-a76abff5601d" => "38QARV0-1ET0G6Z-2CJD9VA-2ZZAR0X"
I think now you risk having 0 vs O or I vs 1 readability issues. [edit: good news, I was wrong]
(Seems uuidkey authors have decided to remove O and I instead, but the effect is the same)
EDIT: I’ve looked it up and I was wrong! Crockford alphabet does use all digits (0–9), but doesn’t have O, I or L. When decoding, O is mapped back to 0 and both I and L are mapped to 1. Sorry for the confusion!
If you're have the risk to users confusing 0 and O, then you can't use either. Your users aren't going to know that you're running Base32-Crockford and that they'll only encounter 0 and 1, never O, I or L.
We did a "password" generator, for people who made a purchase, but didn't want an account. To view an order they'd then need to enter a code, found in their confirmation email. Those codes where really short, 8 or 10 characters, no 0,1,I,O,L,U,V and all upper case. If the user entered the code in lower case, we'd automatically upper case it. You'd never use these as a real password, but for a temporary order tracking page they pretty much removed all of the input mistakes people could make.
> We chose a symbol set of 10 digits and 22 letters. We exclude 4 of the 26 letters: I L O U.
I had never heard of Base32 Crockford before. The whole rationale is clever.
Edit: okay, good to know were at least covered for 1 vs I issues.
See for example: https://docs.github.com/en/code-security/secret-scanning/sec...
They don't appear to check validity though? I haven't tested it so maybe someone else can double check.
0. Some folks don't care about API Keys, that's okay! But for those of you who did respond and do care, we are updating our design based on your feedback.
1. When we got to work on making our API Keys, we looked for an obvious standard but didn't find one. So we decided on our approach quickly and put together uuidkey in an afternoon. We knew it was not going to be everyone’s preferred design, but we wrote up the article to share our thought process as well as generate some marketing. We are happy to see that the article did well and we got feedback! :)
2. The ability to double-click to copy, which was lost with the addition of dashes, was more important to developer commenters than we thought it'd be (even if only needed once). We heard you, so we've already updated https://github.com/agentstation/uuidkey to support a `WithoutHyphens` option for the `Encode` function so you can generate keys without dashes.
3. Some folks were worried that our resulting key after encoding has fewer bits of entropy compared to the original UUID. The Crockford base32 encoding does not reduce entropy, it is a 1:1 mapping.
4. One quality piece of feedback pointed out that the UUID spec warns against using UUIDv7 (only 74 bits of entropy) and even UUIDv4 (standard 122 bits of entropy) alone for API Keys. We plan on still supporting UUIDv7 and UUIDv4, but will add additional entropy bits to follow the official recommendation.
4. Lots of commenters like prefixes, which make it easier to identify & search for keys (particularly to ensure they don’t get accidentally committed to a repo). We plan to add an option for that. Worth mentioning that a few folks pointed us to Github's auth token implementation that includes prefixes, which is a pretty great standard - https://github.blog/engineering/platform-security/behind-git...
Thanks again for reading, debating, and giving us some good advice! We want a product that feels good for developers to use. :D
Aren't you going to track the keys in a database, where you can keep the tenant id and creation time, scope of the key and any other significant metadata anyway?
A static prefix + checksum, maybe a version number so you can future-proof the system sounds like best practice. For example `ASKEY1-(128bit random base32 encoded)-(chksum)`.
1. API keys are security credentials: - They are meant to be secret and revocable - They often encode metadata about permissions and identity - Compromised API keys must be invalidated and replaced - They function like passwords for authentication/authorization
2. UUIDs are identifiers: - They are designed to be globally unique but not secret - They contain no inherent permissions or privileges - There's no security risk if others know a UUID - They function like serial numbers for identification
To use an analogy: An API key is like the key to your house (needs to be kept secret, grants access, can be changed if compromised), while a UUID is like your house's street address (can be public, just identifies the location, doesn't grant any access by itself).
Thinking they're equivalent is like saying your house key and address are the same thing just because they're both strings of characters. This misconception could lead to serious security vulnerabilities if API keys are treated with the same casualness as UUIDs.
PS, we all liked this site, right? https://everyuuid.com/
Disclaimer: I built it.
I try to make it obvious in UI by automatically converting to uppercase, replacing O->0 etc, and adding a dash in the middle.
I usually create an API key like this: `sk_${randomUUID().replace(/-/g, '')}`.
I'm not sure if this is meant to be read as "uppercase (letters and numbers)", but it is effectively what he's referring to.
Lowercase digits do exist[1], but there's no Unicode encoding for them and fonts typically have to choose to support one or the other.
Or, just ignore the dashes? It's not that difficult, we have the technology.
I have never ever heard a developer even mention the way api keys look before.
I doubt this matters in reality for this case, but the number of comments stating "there is no difference" or something to this effect shows how any added step can easily be misunderstood and could (in the worst case) introduce a fatal security flaw.