Hacker Newsnew | past | comments | ask | show | jobs | submit | OrwellianChild's favoriteslogin

This question comes up all the time on HN. I'm one of a bunch of people on HN that do this kind of work professionally. Here's a recent comment on a recent story about it:

https://news.ycombinator.com/item?id=16006394

The short answer is: don't overthink it. Do the simplest thing that will work: use 16+ byte random keys read from /dev/urandom and stored in a database. The cool-kid name for this is "bearer tokens".

You do not need Amazon-style "access keys" to go with your secrets. You do not need OAuth (OAuth is for delegated authentication, to allow 3rd parties to take actions on behalf of users), you do not need special UUID formats, you do not need to mess around with localStorage, you do not need TLS client certificates, you do not need cryptographic signatures, or any kind of public key crypto, or really any cryptography at all. You almost certain do not and will not need "stateless" authentication; to get it, you will sacrifice security and some usability, and in a typical application that depends on a database to get anything done anyways, you'll make those sacrifices for nothing.

Do not use JWTs, which are an increasingly (and somewhat inexplicably) popular cryptographic token that every working cryptography engineer I've spoken to hates passionately. JWTs are easy for developers to use, because libraries are a thing, but impossible for security engineers to reason about. There's a race to replace JWTs with something better (PAST is an example) and while I don't think the underlying idea behind JWTs is any good either, even if you disagree, you should still wait for one of the better formats to gain acceptance.


This developer has pretty much arrived at the right answers by themselves.

Key Generation

generate-safe-id is fine. For a secret API key, UUIDs are less fine. Also fine: directly reading 16-32 bytes from crypto.getRandomBytes and converting to hex.

Key vs Secret

An AWS_Access_Key is basically just a random username. If you understand how userids work in your system, you don't have to worry about this.

Key Usage

Don't use JWT; JWT is a mess. The real distinction here isn't what a secret key can get you, but whether you attempt to track clients without serverside state. What JWT ostensibly gets you is an arbitrary per-client state store without requiring database lookups on the serverside. In reality, you almost never get that, and inherit all the downsides of JWT --- including extreme, scary complexity --- for very little practical benefit. If you're already using a database to handle client request (like most applications), keep it simple.

Key Storage (Clientside)

Cookies are safer than localStorage; modern browsers are bristling with defenses for cookies, but not for localStorage access.

Key Storage (Serverside)

We hash passwords because passwords are valuable across sites; it's a big deal to compromise someone's password, even on a random low-value application. That's not true of API keys. If your database is compromised, the API keys don't matter anymore. Don't bother encrypting them.

Authorization

Authorization is a big topic. API keys are an authentication concern. AuthN != AuthZ. Keep it simple with AuthN.

Don't:

* Bother with TLS client certificates. Client certs are useful internally, when you have an ensemble of services that need to talk to each other securely. They're much less useful when you have tens of thousands of semi-anonymous clients. They're a huge pain in the ass to deal with on both the client and the server side, and have extremely bad UX.

* Use JWT or Macaroons. If you can get away with opaque random strings and a serverside database, then get away with that, for as long as you possibly can. We work on applications running at "popular Internet app" scales and they manage this just fine. Trying to push client state to the client costs security; it's something you get away with, not something you do to shore up your defenses.

* Bother with OAuth. The only "interesting" thing OAuth provides is a UX to allow you to delegate authentication to third-party services --- think, every app that wants to see your Twitter timeline. If you don't have that problem, OAuth doesn't buy you anything except complexity.


> The Board of Trustees of Social Security tells us that the program is going to completely run out of money within the next 15 years. Millennials’ retirement horizon is far beyond that.

That’s not how Social Security works. For practical purposes, it’s pay-as-you-go system: http://www.heritage.org/social-security/report/misleading-th.... As boomers retire, taxes will need to go up to account for the higher ratio of retirees to workers. But when the millenials retire, unless they end up having a substantially smaller generation after them, that strain will not be there.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: