2

We are building a public-facing API. The consumers of this API will be business partners of ours - we will probably have a personal relationship with each one, and I suspect there will only ever be 10-40 of these customers. So we're not dealing with the same problems that e.g. Spotify/Facebook might with their public APIs.

We want to give each user different API read permissions, so some level of authorization is required.

We were going to issue each customer with an API key, and store the related permissions in a table. But now we're wondering if we should implement JWTs to handle this (or even another option like OAuth).

Pros of API keys:

  • Simple. Easy for the clients to implement (fairly important for us)
  • Makes rate limiting simpler, as there will be fewer auth calls.
  • Cheaper (we are using AWS lambda so paying per request)
  • Quicker for us to build too

Pros of JWTs

  • More established way of handling authorization. No need to reinvent the wheel.
  • Avoid any unforeseen pitfalls around implementing your own access mechanism
  • Fewer database look-ups on our end (but presumably slower flow overall)
  • ...any others I've missed here?

We're leaning towards API keys for simplicity, but want to ensure we're not missing something important.

1 Answer 1

3

I believe API keys are actually an older convention for auth than JWTs (which were only standardized in 2010); you certainly aren't re-inventing any wheels to use them. This scenario definitely seems ripe for using them, whereas I think JWTs would actually add quite a bit of needless complexity.

JWTs are especially valuable for certain authentication and/or authorization scenarios, but I don't think any of them apply here. You're presumably not separating authentication from authorization (JWTs allow one party to authenticate a user and then another party to provide - or deny - service based on that). You're keeping a small pool or users and presumably will have few active connections and request rates, so cutting one database (or, realistically, data cache) lookup per request isn't likely to be urgent. It doesn't sound like your partners will likely expect multiple tokens each with a minimal set of permissions - it's more secure in some scenarios, but definitely more complicated to implement - and you could do that with API keys anyhow.

On the other hand, JWTs introduce significant risks. JWT-parsing libraries need to be secure against a number of attacks that just don't come up with API keys (those have their own risks, but they're mostly well-known things like SQL Injection, brute-forcing, or timing attacks). JWTs require generating, storing, using, and hopefully rotating cryptographic keys; they may also require distributing them if you're separating the authentication provider from the service provider. JWTs are hard to revoke, so they're usually made short-lived, meaning you need to support some other authentication token (like a DB-stored refresh token) or low-friction auth method, at which point you might as well use the API key anyhow.

Another option (which may or may not be suitable for your customers or API) would be to use TLS client certificates. These can be more secure than either of the approaches discussed (the control and simple processing of individually issued and revoked keys, the built-in expiry and impossibility to brute-force of JWTs, and unlike either you avoid ever transmitting the actual secret over the wire even within a TLS tunnel and "accidentally send the token via plain text" isn't even a meaningful risk). They also have drawbacks, though (requires handling key material, makes enrollment more complicated, makes it harder for an individual user to enable access for multiple devices, rotation can be more complicated in the event of a compromise, users are likely just less familiar with them). I wouldn't even mention it except that you're expecting a very small number of users and a working relationship with them.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .