Establishing Trust between Microservices using JWT
How JWTs can be used to establish trust between system components such as Microservices
Introduction
In case you are unfamiliar with JWT (JSON Web Tokens) you can think of them as credentials you can use whenever a proxy or stand-in need to represent a user of any kind; human, another microservice or another system altogether. Besides the token itself, they can contain additional information that is cryptographically verifiable, meaning the information, whether is authorization claim, service request data or any other information, is secure against tampering.
In this post, the second in a series of posts about JWTs, I will present an example of how JWTs can be used to establish trust between microservices, allowing one microservice to verify the authenticy of a user, what authorizations a user has and the possibility to deliver request parameters other information between microservices in a secure way. We will be able to cryptographically verify that the information came from a trusted microservice and from which microservice it came and also verify that the information has not been tampered with. The first post introduced JWTs and surrounding topics.
The code for this article can be found here
Overview
You may know that JWTs are very useful for authorizing client requests to API endpoints, and if you have ever implemented such as solution, which is something of an industry best practice, you are already used to seeing an authorization request return an access token as well as a refresh token. This makes perfect sense and it is part of the envisioned JWT authorization flow. In this post we will instead consider the case of a microservice calling another microservice, where a microservice does not represent a user and so has no way of calling an authorization server to obtain access and refresh tokens using user credentials (and no, we won't be creating the dreaded “service user” that I've seen in far too many places). Instead we will take advantage of the public/private nature of RSA keys to uniquely identify and verify each microservice to other relevant microservices, for each request. This can then further be orchestrated using a hardened and trusted credentials service. In the next post in this series on JWTs, I will show an example how this can also be used in an event driven microservice system.
More here
Even more here
[overview images here]
docker-compose up -d
docker exec -t httpservice http http://clientservice/my-public-credentials
docker exec -it httpservice sh
/ # http http://clientservice/my-public-credentials
/ # http ...
HTTP/1.1 200
...
{
"keyId": "1dd88b71-86c1-4d02-8aa9-feb662d99097",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCY0x6HYkcs3jGHCz6XJoF3e1z-BqLZS_z2j5ME_vfO1OC1nlMv3P63n51fwEzG7BX8NKRfaR5sPF8meJ8_U5DhLG35Xt3hrYUH4diCugQgPIfpprI4i__J8IxWHWxbT_4eYfvSQDwzmlWanlh2TZfVfst3ZDw6URNRJWjujNOYqQIDAQAB"
}
public PublicCredentials refreshMyCredentials() {
myKeyPair = RsaProvider.generateKeyPair(1024);
keyId = UUID.randomUUID().toString();
PublicCredentials publicCredentials = getMyPublicCredentials();
// this microservice will trust itself
addPublicCredentials(publicCredentials);
return publicCredentials;
}
public PublicCredentials refreshMyCredentials() {
myKeyPair = RsaProvider.generateKeyPair(1024);
keyId = UUID.randomUUID().toString();
PublicCredentials publicCredentials = getMyPublicCredentials();
// this microservice will trust itself
addPublicCredentials(publicCredentials);
return publicCredentials;
}


Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Email