I am planning to use OPA for Authorizations in microservice architecture. Initially i thought of Sidecar option, but it seams little complex and decided to start with centralized authorization service with OPA. Our authorization data is in external cluster and has to be fetched through a REST call. So the architecture looks like this.
-
I build a centralized Authz service in Java and all Microservices can call my service to
1.1 Check if the user has access to a resource with userid and resourceid
1.2 Call to get all resources which the User has access to. -
Authz Service will expose endpoints for serving auth requests from services
-
Authz service will also provide endpoints for Rego Policy creation and Updation. I think same policies will work for all microservices since we define the auth endpoints to be exposed. May be in future we can move policies to separate repo, so that all services can maintain their service policies separately. And Authz service will pull the policies from that Repo.
-
Authz service also have to provide external data to OPA. For this we will fetch data from external api(Roles of users), then convert them to json format and store it on cache using Redis Server.
-
Every request to OPA will get data from Redis cache overloaded with input, which makes the policy evaluation faster.
-
Since Roles of user can change(Modifying access and Deleting access), this needs to be updated in Redis cache. Hence i am planning to have Azure Service bus, to get events triggered whenever a user Role changes. The event will be consumed by Authz server and evict the cache for that User.
I could only think this much for now. I know this is a complex architecture. Can i know what changes i need to do here? what are the things i have to take care. and how can i improve this architecture. Any suggestion is highly appreciated.
Note : I saw OPAL project which is somewhat doing the same stuff, but i cannot use it as it is and hence thought of building it separately. https://www.permit.io/blog/introduction-to-opal
2
Answers
I’m sure you could make it work, although while a centralized service might be simpler conceptually, it also entails having a single point of failure for your whole application or cluster. Adding to that, there’s often a latency penalty to pay when querying for authorization decisions at a remote endpoint compared to querying OPA on localhost. On top of that, you’ll have to account for the latency introduced when querying Redis to fetch data in each request. If you can use OPA itself as the in-memory store for your authorization data, that’s almost always preferable.
Depending on the size of the data, and the frequency of changes, that might not be viable, but it’s certainly where I would start from, and only look into alternatives when that model is proven to not work.
I’ve done a few talks about the architecture of distributed authorization and OPA in the past. Here’s one from API Days in Paris last year. Perhaps you’ll find it useful.
I love that you use OPA and the best practice of decoupling your policy from code.
Now you need to manage your policy (the roles that you have and what they can do, whether it is RBAC, ReBAC, or ABAC)
You also need to sync your data to your authZ client (keep in mind that you send only the policy-related data and not all the data)
With OPAL those things are much easier because OPAL can load the changing data from different sources and spare you the need to manage the Redis cache.
It also keeps the policy synced from a git repo (recommended) or a "bundle server".
If this is a small project you can also consider managing your authZ with permit.io the free tier of Permit (up to 1000 monthly active users) and then you could manage it much more easily with the UI and their java SDK