7
votes

There are several ways to build authentication in micro-services. However very popular is using JWT tokens and OAuth protocol together with OpenID Connect identity layer.

In this tutorial explaining how it can be achieved there is one tip:

Pass by reference when tokens have to leave your network, and then convert them to by-value tokens as they enters your space. Do this conversion in your API gateway.

However it's not clear to me what's reason behind it. I suspect it might be due to some security benefits (not to give client possibility to read any specific info). Because in the JWT token itself it might be info about roles/permission. But for this purpose token can also be encrypted.

Another reason might be that JWT token is too big and in order to don't carry this token every time such approach might be used. (or if JWT token is stored in cookie it has size limits).

I haven't seen any info that JWT token authentication is compromised and it's a bad practice to keep it on client (in browser).

On the other hand I see that Ping Identity is also using pass by reference approach. Can you help me understand the reasoning behind it?

2
Regarding by-reference/by-value question: have you watched the video placed near the text you are citing?cassandrad
Yes, however it didn't answer for my question :(user1459144

2 Answers

2
votes

They are both valid options and as always it's the exact scenario where you want to apply them that will dictate the most appropriate. As it's generally the case, each option will have its pros and cons and you already mentioned a few, so I'll try my best to add something new to the discussion.

The major difference is in the contents, by-value will contain the actual values while the reference is just a random sequence of bits. If you want to represent sensitive information in the token, this may tip the scale in favor of reference tokens.

It's true that if you use JWT you can encrypt them to ensure confidentiality, but this adds a significant layer of complexity and the support for JWT encryption in the available libraries is most likely not as good as the support for signing given that encryption does not have a similar widespread use.

Regarding the size, I don't think this should be a deciding factor. Yes, if you go with by-value tokens you need to keep them sufficiently small as to not cause significant overhead on the channel, but you should not pick one vs the other only because of this constraint.

One thing you did not mentioned, but I believe it's important is that reference tokens seem more suitable for situations where the authorization server and resource server belong to the same entity. It's true that there is already a standard to cover token introspection so that an external resource server can query information about a reference token in an interoperable way. However, it's still true that, when both actors are within the same security boundary, reference tokens should be easier to scale and implement.

The suggestion on the article it's also interesting, you get reduced overhead on the external network and no issues with information disclosure and then do the upgrade to by-value tokens in one central place meaning that all other services behind it may still gain from the simplicity of having the required information already within the token itself.

In summary, if information disclosure is an issue to you you'll probably go for reference tokens in order to not take the cost of JWT encryption; otherwise, you might as well make life simple for you and go with value tokens.

1
votes

I believe the main benefit (which the article wanted to convey - apart from the information disclosure) of using reference token (Opaque tokens) over by-value (JWT) is the ability to control the Access tokens when it is distributed outside the network.

In other words, if we issue Access Tokens as JWTs outside the network then it is hard to revoke the access during emergency (when a user is deactived /terminated, lost mobile phones, etc ). But reference tokens can be easily revoked since it is a pointer within the AS boundaries.

A more detailed explanation on this is available here.