7

Currently we are debating over securing our multiple micro-services. The major concern is that the JWT token provided to us will expire before the call is finished. (This is in the synchronous design) Here are three proposals:

  1. Client App has an 'ensure(int minutes)' method before lengthy calls, calling token provider if necessary. Let JWT expire if it hits security filter.
  2. Client App sends both JWT and Refresh Token. If JWT expires, use refresh token to get new one and place on response headers via token provider.
  3. Create "login" service. Login caches refresh info and returns JWT. Send old JWT to get a refreshed JWT via token provider.

Thoughts? Note: My vote is for #1. The rest seem insecure, but convenient.

4
  • 5
    For any long-running call, I would set it up so that you can get receipt acknowledgement of the request, and then expire the token. Subsequent requests can ask for status or get the result, using a new JWT token. Commented Feb 19, 2018 at 3:58
  • Agreed with @RobertHarvey, seems like a bad design to couple the calls to a single token in any case.
    – Paul
    Commented Feb 19, 2018 at 4:28
  • One-use tokens are ok. Problem is the long connection.
    – Laiv
    Commented Feb 19, 2018 at 7:19
  • 1
    I like this question a lot. We have a similar problem, where a client can launch a chain of further actions. Unfortunately, each step in this chain can take a day or so. Commented Feb 19, 2018 at 9:06

3 Answers 3

3

I don't understand why you think having the JWT token expire will be a problem. You should only be validating the expiry when the message hits your system (request submitted). If you have a Queue in front of your service, you should check / validate tokens before the message containing them get into the Queue. If you have a service operation which takes a long time, check the expiry at the start of processing, not the end.

One important ability created by microservices patterns is that you can reply a stream of events. This naturally means some of the data in the replay will be expired.

Expiry is intended as a mechanism to prevent users outside of your system from using 'replay' attacks against your system. Once the data has made it INSIDE your system, you should not be checking for expiry any longer.

2
  • While this makes sense when you only have one service, what when you have a service calling other services and there could be a long delay from the start of the request to the call of the last service.
    – Peter
    Commented Oct 28, 2021 at 18:34
  • 2
    VERY good point I had not considered! I stand LARGELY corrected. I think if I faced this sort of situation, I would use the JWT Refresh token flow (which still works fine with the above - when you get the request - even if it takes time to be ready - you can start a token refresh while doing your other work. Commented Oct 29, 2021 at 20:59
3

What works is using a separate token for external-to-internal ("external token" for brevity) and internal-to-internal ("internal token" for brevity) requests:

  1. When Clients send requests to the Resource Server, the API Gateway exchanges the external token for an internal token with the Authorization Server.
  2. The API Gateway then forwards the request with the internal token to internal services.

A variant of Token Refresh using mTLS or the internal service's credentials can be used to obtain a new internal token.

OWASP recommends this approach.

after the external request is authenticated by the authentication service at the edge layer [referring to API Gateway], a data structure representing the external entity identity (e.g., containing user ID, user roles/groups, or permissions) is generated, signed, or encrypted by the trusted issuer and propagated to internal microservices.

Netflix (see references 1 & 2) uses this approach.

we created a new identity structure called Passport. What is Passport? It is an identity structure created at the edge [referring to API Gateway] for each request and services consumed in the scope of same request. It contains user and device identity information. It is internal to Netflix ecosystem, meaning it is an internal identity token that we don't send it out back to the device.

You can see my discussion with contributors from OWASP on GitHub.


Edit: Previously, I suggested validating the lifetime of the Access Token only at the API Gateway and not validate at the services. This is insecure as it violates Defense in Depth (see link to GitHub above).

0

Client App sends both JWT and Refresh Token. If JWT expires, use refresh token to get new one and place on response headers via token provider.

Is mostly correct except they go on the request headers, not the response.

So, the web api receives a request with a valid JWT that expires in a minute and the request runs for 5 minutes, the server issues a response and the next request gets 401'ed because the jwt is expired and then a call to refresh token should be made (refresh token expiry should be > 5 minutes in this case).

Not the answer you're looking for? Browse other questions tagged or ask your own question.