5

I am planning to implement JWT authentication on my micro-services to achieve zero trust architecture. User will generate a JWT token through front end micro-service. Each subsequent request will contain this JWT which will be forwarded to backend services so the service can authenticate the user on it's own instead of taking a simple user id from front-end service. The scenario fails in two conditions

  • User initiates a call on front end service which generates a long list of steps to be performed on backend services sequentially. The JWt token will eventually expire and the sequence of steps will stop as backend services will not authenticate further requests from frontend with an expried token
  • A backend service starts some process on user resource through an internal process. e.g. Delete user server if the invoice is unpaid.

In both of the scenarios user will not be available to generate a new JWT token through login credentials. Should I implement one time and purpose specific tokens in addition to JWT to resolve these issues or is there a better alternative?

Saqib
  • 151
  • 4
  • It should be noted that this doesn't quite sound like zero-trust. You're trusting at least two things here: that the JWT signing key is not compromised, and that the request as "forward to backend services" has not been tampered with prior to the forwarding. Typically so-called "zero-trust" accepts the first risk, but expects your client to be communicating directly with the backend services without prior TLS termination. True zero-trust requires end-to-end encryption of not only the connections but also the data, such that it is opaque to the server and impossible for the server to modify. – CBHacking Aug 27 '22 at 07:28

1 Answers1

0

tl/dr: it's okay to have the backend accept a user id as part of a zero-trust architecture. The more important part is that your services must authenticate themselves to the backend, and the appropriate parts of the backend should only accept requests from your services (not from end-users). As a result your issue is trying to use the auth token of an end-user for services that the end-user isn't supposed to access directly. Let your services authenticate themselves with the backend, and then it's perfectly fine to pass along a user id.

Who is a "user"?

I think the key is that you're confusing who the "user" of some of your backend systems is.

This is most clear with your second example: deleting an inactive user. This is a system-only process. The user will never trigger this action themselves. The backend is the "user" performing the action, even though a user account is being affected. As a result it doesn't really make sense in the first place to be using the user's access token to delete the user. It's not like the user is ever going to be making these requests to the backend themselves. Indeed, user's should not be able to access these endpoints anyway. If somehow a user managed to access the backend to try to delete their account, their access token should be rejected - this endpoint is intended for system use only, (presumably) not for users to delete themselves. Therefore, by using the user's auth token to perform these system actions, you're authenticating as the wrong "person".

The situation is a bit more murky with your first example, because it is the user who makes an initial request which triggers the later actions. However, the overall situation seems is still the same anyway - a backend process is taking action on the user's data. The "user" of this system is not the actual end user, but is instead part of your own system. It just happens to be acting on behalf of your users.

In short, if you have backend services that are not meant to be invoked directly by users, then those services shouldn't accept the user's access token.

So what to do?

So how do you implement a zero-trust system? Naturally, the same way you are trying to do it - you're just authenticating as the wrong person. It's not the user that needs to authenticate itself to the backend, but rather it is whatever service is making use of the backend that needs to authenticate itself. This may or may not be with JWTs. It may be a simple matter of having an authentication token that only the "cron" service knows, and which it uses to authenticate itself with your backend. Those details are up to you.

However, I think that's the only real answer. These services need their own way to authenticate themselves with the relevant parts of your backend, and those parts of the backend should only accept requests from your authenticated services - not from end users with end-user JWTs. You'll obviously have to build the authentication method for your services in a way that covers issues with credential rotation if relevant. However, since you won't be using the user's password as part of that process, that won't be a concern.

Conor Mancone
  • 29,899
  • 13
  • 91
  • 96