3 added 385 characters in body
source | link

tl/dr: A JWT is simply not the correct solution for a server-to-server API token/key. API keys need to be revokable in the case the user needs to change it (for whatever reason), and JWTs by their nature cannot be revoked. You need a completely different solution for server-to-server authentication.

This combination of properties gives JWTs a particular use-case: authenticating a user who first logs in with a username and password. The idea is that when the user logs in the application gives them a JWT and refresh token, which the app then uses in combination to keep the user logged in for as long as they need (aka the phone app or website use the refresh token to automatically get a new JWT as needed, and send up the latest JWT with all requests).

Note, if your JWTs don't have a short lifetime, or don't expire at all, then you are leaving a potentially severe security vulnerability in your system, since an attacker who gets one effectively gains permanent access to the account even if a password is reset. Since JWTs go to the actual client (aka a mobile app or a web application), they are much more vulnerable to theft by outside actors, which is why short lifetimes isare necessary.

Of course there are a wide variety of ways to manage access tokens for APIs, but you mentioned systems which show the API token on the dashboard. These typically have a different set of properties. In particular, they are long-lived and revokable. They are long-lived because they will often be used for server-to-server communication,. This means that they are often sitting in a configuration file (or similar) and so you don't want to force your end users to manage the refresh process themselves or update the token for newwithout good reason.

This combination of properties gives JWTs a particular use-case: authenticating a user who first logs in with a username and password. The idea is that when the user logs in the application gives them a JWT and refresh token, which the app then uses in combination to keep the user logged in for as long as they need (aka the phone app or website use the refresh token to automatically get a new JWT as needed, and send up the latest JWT with all requests).

Note, if your JWTs don't have a short lifetime, or don't expire at all, then you are leaving a potentially severe security vulnerability in your system, since an attacker who gets one effectively gains permanent access to the account even if a password is reset. Since JWTs go to the actual client (aka a mobile app or a web application), they are much more vulnerable to theft by outside actors, which is why short lifetimes is necessary.

Of course there are a wide variety of ways to manage access tokens for APIs, but you mentioned systems which show the API token on the dashboard. These typically have a different set of properties. In particular, they are long-lived and revokable. They are long-lived because they will often be used for server-to-server communication, and you don't want to force your end users to manage the refresh process themselves or update the token for new reason.

tl/dr: A JWT is simply not the correct solution for a server-to-server API token/key. API keys need to be revokable in the case the user needs to change it (for whatever reason), and JWTs by their nature cannot be revoked. You need a completely different solution for server-to-server authentication.

This combination of properties gives JWTs a particular use-case: authenticating a user who first logs in with a username and password. The idea is that when the user logs in the application gives them a JWT and refresh token, which the app then uses to keep the user logged in for as long as they need (aka the phone app or website use the refresh token to automatically get a new JWT as needed, and send up the latest JWT with all requests).

Note, if your JWTs don't have a short lifetime, or don't expire at all, then you are leaving a potentially severe security vulnerability in your system, since an attacker who gets one effectively gains permanent access to the account even if a password is reset. Since JWTs go to the actual client (aka a mobile app or a web application), they are much more vulnerable to theft by outside actors, which is why short lifetimes are necessary.

Of course there are a wide variety of ways to manage access tokens for APIs, but you mentioned systems which show the API token on the dashboard. These typically have a different set of properties. In particular, they are long-lived and revokable. They are long-lived because they will be used for server-to-server communication. This means that they are often sitting in a configuration file (or similar) and so you don't want to force your end users to manage the refresh process themselves or update the token without good reason.

2 added 1026 characters in body
source | link

The solution

So how should you generate the API keys for the user? That just depends on your needs, but since I don't know what those are I'll give you a suggestion that may be overkill in some cases, but sufficient in all cases.

The most secure solution is to allow the end-user to have multiple keys. When they request a new key generate a public/private key pair, let the user download the private key, and then throw away the private key on the server side. It is from then on the user's responsibility to use/store/copy it as needed. The server keeps the public key and requests are signed and verified using standard asymmetric cryptography methods. This also allows the user to generate multiple keys if needed, potentially with different access levels.

There are of course simpler ways to do things, but I would say that it's a bit out of scope to try to choose the "best" authentication method for you. Everyone has different needs and needs to balance security/usability/cost for themselves.

The solution

So how should you generate the API keys for the user? That just depends on your needs, but since I don't know what those are I'll give you a suggestion that may be overkill in some cases, but sufficient in all cases.

The most secure solution is to allow the end-user to have multiple keys. When they request a new key generate a public/private key pair, let the user download the private key, and then throw away the private key on the server side. It is from then on the user's responsibility to use/store/copy it as needed. The server keeps the public key and requests are signed and verified using standard asymmetric cryptography methods. This also allows the user to generate multiple keys if needed, potentially with different access levels.

There are of course simpler ways to do things, but I would say that it's a bit out of scope to try to choose the "best" authentication method for you. Everyone has different needs and needs to balance security/usability/cost for themselves.

1
source | link

I'm going to answer with a frame-challenge.

You are actually talking about two completely different kinds of authorization tokens with two different purposes. You don't want to figure out how to regenerate the JWT and show it on the user dashboard because a JWT is not what you want on the user dashboard anyway.

Understanding JWTs and their use cases

JWT's have two properties that distinguish them from the other kind of access token that we'll talk about: they can't be revoked and they are typically short-lived (which is a necessary consequence of them being non-revokable).

The fact that they can't be revoked is a natural consequence of the fact that you can verify them without checking the database. Everything you need to check the JWT is built into the JWT, and the only way they could be revoked is if you marked them as such in a database and checked the database everytime you verified the JWT (which would defeat its purpose). Therefore, since they are effectively irrevokable, it is best for them to have short life-times to minimize the damage done in the event that an attacker steals one. As a result JWTs typically also come with a refresh token, which is longer-lived and which the user can use to generate a new JWT when the first one expires.

This combination of properties gives JWTs a particular use-case: authenticating a user who first logs in with a username and password. The idea is that when the user logs in the application gives them a JWT and refresh token, which the app then uses in combination to keep the user logged in for as long as they need (aka the phone app or website use the refresh token to automatically get a new JWT as needed, and send up the latest JWT with all requests).

Note, if your JWTs don't have a short lifetime, or don't expire at all, then you are leaving a potentially severe security vulnerability in your system, since an attacker who gets one effectively gains permanent access to the account even if a password is reset. Since JWTs go to the actual client (aka a mobile app or a web application), they are much more vulnerable to theft by outside actors, which is why short lifetimes is necessary.

API access tokens

Of course there are a wide variety of ways to manage access tokens for APIs, but you mentioned systems which show the API token on the dashboard. These typically have a different set of properties. In particular, they are long-lived and revokable. They are long-lived because they will often be used for server-to-server communication, and you don't want to force your end users to manage the refresh process themselves or update the token for new reason.

As a result, revokability is very important. If the user decides they want a new access token (for whatever reason), they need to have an easy way to generate a new one. In more advanced systems they also come with their own privilege system, and the admin can generate as many access tokens as needed and assign privileges to them. This gives the users the tools they need to manage the security of their own accounts.

Bringing it all together

In summary, these things are two different kinds of access codes for two completely different reasons. A JWT is a short-lived access code because it goes down to an end-client where it is at higher risk of being stolen. A new one is assigned everytime the user logs in, expires shortly thereafter, and is automatically refreshed by the client.

A server-to-server API token is long-lived and only stops working when explicitly revoked by the customer. They can copy it into the configuration information of their server and only change it if necessary. It never expires and doesn't have to be refreshed.

These are two completely separate authentication needs - the way you authenticate a front-end client is not the same way you authenticate server-to-server communication, because the two communication channels have different security needs. You're trying to fulfill both needs with one "kind" of authentication, and the reality is that trying to adjust your JWTs to work for server-to-server authentication as well is just a bad idea. If your user's need to interact with your system in two different ways, then you need to provide two different kinds of authentication. In particular, it sounds like you're not planning on allowing your JWT tokens to expire (so that they can be used for server-to-server authentication), and that's a very bad idea.