About Behalf
Behalf facilitates in-purchase financing for B2B buyers and sellers. As a financial institution, it is critical to maintain...
For further actions, you may consider blocking this person and/or reporting abuse
Great writeup, it's amazing how many teams still try to couple authentication to authorization. But you got that exactly right to keep these separate.
I'm also wondering about the implementation, these are usually really challenging. I've found from many past experiences that building the user IAM aspects to allows encounter some pitfalls. I actually wrote up my most recent adventure into building authz in our services.
Thanks, Warren
Implementing and enforcing IAM isn't a trivial task and can be challenging in a microservice architecture.
We think that choosing the correct access management control depends on the application requirements and can be changed from one to another.
In the next part, we will see the implementations that feet for our needs.
I am 100% identify with your sentence: ״I've been through this journey myself, more than once. Every time, I was looking back...״
As humans, we have the nature to solve problems; Looking back and asking ourselves the questions, did we achieve our goals? What can we do otherwise? or did we choose the correct solution for that particular problem?
This step is critical while solving problems that keeping us going and improve our skills as software engineers
I generally include a handful of high level roles in service and application design. May also want groups. These can be included in the jwt. Authorization by ownership of of course separate.
That works with small systems, but invariably JWTs are not designed to handle resource management. There just was never a way to support granular permissions access stored in the JWT that works at scale.
I mostly agree, you still may need fine grained permissions. But you can go a long way with roles and groups for most things.
Document ownership. Things like owner read/write, group read, manager read/write and even manager above are typical oversights.
I'm just pointing out that for many applications, rules and groups fit well enough.
Nice. Separating authentication from authorization is a big step. However, using JWT may not be the best approach, and I can see you already started feeling the pain given the rather big pitfalls section of your article.
I hereby invite you to take a look at this article where I describe the huge bunch of problems you will face while using JWT, and propose a more straightforward solution:
dev.to/honatas/a-different-approac...
I'm open for discussion. =)
Hi Johatas,
Thank you for reading and sharing your thoughts. Understanding the separation of concern is critical to solving the problem of Authentication & Authorization solutions.
Indeed, stateless authentication(JWT in our case) suffers from several downsides that need to be aware of. There are pros and cons for both stateless & stateful concepts. For some use cases, the stateless approach isn't the best one.
With your permission, I would like to hold this discussion until I will publish part II :-)
What will be in part II and when it will be published?
Thanks for the article!
I was thinking in that it is OK to put roles/permissions in the JWT payload, however it could become very very large, and we have to account for header limits: stackoverflow.com/questions/686217...
Even if we have low-level permissions Posts.Manage.UpdateOwn, and we can send it in the JWT payload, the data could be very large as more permissions are created, but most importantly, the Posts microservice should be able to check the business rule regarding Posts.Manage.UpdateOwn.
So we have two options here, given a request PUT /users/profile
1) In the controller, you get the User and the Post object and send them to /authorize/Posts.Manage.UpdateOwn with the Post and User object's serialized, and then you check that Post.ownerId === User.id and return true or
2) In the Posts microservice you do the following check: permissions.includes('Posts.Manage.UpdateOwn') && Post.ownerId === User.id
I think that the second one makes more sense.
@jorgesivil How did you handle header limits?
By setting only the necessary information (like userid) and then having an endpoint to retrieve the full list of permissions
what happened to
the next article
? :)Thanks! That's a useful article, and I really enjoyed reading it. I have no experience with microservices on a large scale, but I can easily understand the concepts you have described. Using a single endpoint for authentication, although being difficult, looks like a valid and clean way of getting things in a flow.
Waiting for the next part!
Great piece, Tzachi! Thank you for sharing!
I wanted to share some more insights, in case it would be beneficial to anyone here :)
Authentication and authorization in microservices is very important to get right, especially since microservices introduce more entry points for potential attacks (it’s important to secure each service).
Flexibility is one of the benefits of using microservices. However, if not done correctly, this flexibility can result in inconsistencies which create vulnerabilities. There are 4 main aspects where these vulnerabilities show up: decentralized security, token propagation, security policies, and service-to-service communication.
There's no band-aid solution that will secure every vulnerability I mentioned. However, there are best practices to lower their impact on your microservices architecture. These include authentication and authorization (as you already mentioned), but also secure communication, API Gateways, and Zero Trust.
If anyone is interested, i've helped work on an ebook about transitioning from monolith to microservices. It has over 80+ pages, and guides you through the process of re-architecting both your tech stack and organizational structure when transitioning from a monolithic to a microservices. It also has examples from engineering teams at Uber, Spotify, and Netflix, and how they've successfully navigated the transition.
You can check out the first 4 chapters on our blog already, if you don't want to download the ebook. Here's the first one determining service boundaries & decompozing your monolith.
And chapter 7 is all about authentication + authorization in microservices :)
Would add that you can use asymmetric rsa signing. This is generally safer than a shared secret. I'm fact the authority generating the jwt can share it's public key publicly.
Other considerations are revocation and renewal.
Great write up, I've been searching for an article that breaks down authentication and authorization in a microservices environment. This article definitely helped me out. Looking forward to part II! When do you expect to release it?
Great post, seperating authentication and authorization is a right approach in microservices. What do you think if I add RBAC with domains/tenants in authentication? Example:
[PUT] /domainA/user/profile
In the example, would domainA service check for the validity of the token?
I'm waiting for the second part of this article, and it will be better if you share the date when you'd like to write that part...
Great article.. Just one comment - I see you have mentioned the Authentication as a cross cutting concern and hence can be implemented at the API Gateway level, however, I am not clear about the authorization piece. Are you suggesting that each Microservice manage the authorization at that level? Seems like I am missing something.
You've really good head in describing things. Awesome!
Nice! Thanks
Good explanation. BTW waiting for the next part.
Waiting for the next article!
Nice article
Great article. 've been wanting to ask, how do you manage unauthenticated routes for API Gateway as Global Auth service approach?
Nice article. Waiting for part 2! ^^
are the other parts of this post coming? :)