Security Priniciples of JWT Use - JWT Requests on behalf of user
-
Hi, I'm quite new to doing security manually. I'm handling the client (Vue) and Server (Symfony) side of an application, but not the FusionAuth server, so I am logging users in through the FusionAuth system in place.
However, I am wondering about making API calls from my web app server to the fusionauth server as that user using the JWT. Basically, my setup is that I validate the client on my web app server via FusionAuth login, store the JWT, and create a secure session between the server and the client.
But every call that I am making to FusionAuth is with my server's API key, so essentially the user is asking my server to do things, and then my server is asking FusionAuth to do things with the server's credentials, not the user's credentials.
This leaves security "up to me", so to speak, where it's up to me to validate the JWT before I do any changes. I might be misunderstanding the security of the situation, but wouldn't it be better if I could update a user's info using the user's JWT instead of my API key?
That way if the user doesn't have access via FusionAuth anymore, I don't have to validate the JWT before the request, and therefore do two separate requests. The FusionAuth lists the update User api call as only being valid with an API Token, not with a JWT token. Which essentially means, if I messed up, I could accidentally update the wrong user since I have "sudo" access with each call, when it seems like I'd ideally only have that user's access (which I assume allows them to update themselves?).
Have I misconfigured something? Am I implementing this incorrectly?
Hope that all makes sense. Thanks!
-
FusionAuth is really good at minting JWTs. These JWTs can be consumed by other APIs that you write and serve as a token indicating your client has been authenticated by FusionAuth. It can rely on the JWT for user data, including roles.
FusionAuth itself doesn't accept too many JWTs for manipulation of user data. It expects you to do those manipulations with an API key, as you mentioned. Having JWTs be a widely accepted API authentication method is on the roadmap, please follow this issue if you want to be informed about when it is implemented.
Also on the roadmap is a FusionAuth managed self service user profile portal (probably going to be a premium feature).
I wrote an example app self service portal here as well: https://github.com/FusionAuth/fusionauth-example-flask-portal
I guess you could say that JWTs are the key to knowing who a user is, but the API key is the key to doing things in FusionAuth. This is similar to if you had a 'todo API' that managed todos. You wouldn't expect the 'todo API' to consume a JWT and allow the user to update their todos. Instead the JWT would identify the user, and then whatever method the 'todo API' chose for managing its data store would be used (maybe that's an API key, maybe direct database access, maybe something else).
Hope that helps.
-
Another aspect in favor of the approach involving API keys is the fact that your application can control the process of data entities modification. To be more precise, your application may implement additional authorization and data sanitization checks. You may prevent a user form changing his user name each day or restrict phone numbers to some country. Notably, many of the FA entities features
data
attribute that can hold any information. FA has no knowledge of what is the purpose or type of those data, so it has no means of deciding whether to allow an user to change its content or not.So summing it up - yes, it's up to you to authenticate an user (via JWT validation) and authorize the request, and if everything is ok, to perform the specific API operations with omnipotent API key. It is so, since what does authorize the request mean may be different for each application.