I've got a question regarding using complex ABAC p...
# help
h
I've got a question regarding using complex ABAC policies (for example resource ownership, but it can be even more complex than that). The architecture problem that I'm struggling with is: how to properly populate the request context with the needed attributes. As I understand it, resource ownership does not belong to the identity service, so it can't be populated there. Instead, it would be populated in the service that owns the resource, before making the call to cerbos. The problem that I'm having is that I need to get a bunch of attributes in the request context (that are owned by 2-3 services). The solution that we're having in mind is to have some sort of attribute cache system that stores all the attributes needed in policy evaluation. The doubt that I'm having is that this isn't really scalable and it will introduce a weird dependency in the AuthZ system. Does anyone have any thoughts on this?
c
Hey, we typically assume that the service trying to do something with the resource knows all the attributes that it needs to know about the resource and that's what you pass on to Cerbos to offload the decision making process. (E.g. a user is trying to access account
X
which has attributes
A
,
B
,
C
and on). If that's not the case and you need extra data from other sources to make the decision, you'd need some kind of a wrapper service that can gather that data from relevant places and communicate with Cerbos to get back the authorization decision. Cerbos is designed to be stateless because if it tries to hook into your data sources directly, it becomes incredibly complicated to manage. As you can imagine, there are so many variables to contend with such as different API types, query languages, access credentials and caching requirements. Only you're in a position to navigate those requirements in your environment securely and in a performant way. Cerbos is there to give you visibility and easy management of the business logic of authorization within that context.
j
This is system you are talking about is called the
Policy Information Point
or
PIP
in an ABAC solution. You can google it. You either add the data itself into the call to Cerbos (via some kind of wrapper that you'd have to write) like what Charith said or you include the data as
AuxData
payload (in a JWT). I won't recommend the latter unless you are comfortable with possibly exposing some internal information (JWTs are not designed to be private). In my company, the layer that acts as the
PIP
is our FastAPI layer.
h
thanks you both. This really clarifies things for me. it definitely sounds that we need to have a PIP. The only Cerbos article that I found on this topic is this: https://cerbos.dev/blog/the-case-for-granular-permissions This is a great overview of PIP, PEP and PDP and I was wondering if there's also a deployment recommendation. According to that article, the PIP is called only when needed. As far as I understand from @Charith (Cerbos), Cerbos does not currently support that flow. Any plans to implement that on the Cerbos roadmap?
j
So in your environment, what system will initiate the call to Cerbos?
In other words, what acts as the PEP?
BTW there is one more role in this system - it's called the PAP. 🙂
c
Thanks Jesum. Horia, what I meant above by "wrapper service" is a PEP+PIP because in your system, the individial services don't have all the information necessary to communicate with the Cerbos PDP directly to make decisions. Therefore, you'll need an additional service that can consolidate that information from various sources and use Cerbos to make the authz decisions. We wanted to keep things simple because in a majority cases just the PDP is all one needs. That's why currently our primary focus is on that part only.
h
@Jesum Yip, the application/service that is being accessed acts as the PEP.
j
Then that's the best place to put the PIP as well. In the Fastapi implementation we use, that layer acts as the PEP+PIP wrapper and supplies all the resource related attributes to the PDP aka Cerbos. It works like magic and we are very happy. The PEP is typically the best place to fetch additional attributes because the PEP has the best contextual knowledge of what is going to be accessed. This approach is more optimal than trying to have the PDP integrated with a central PIP. It is likely more performant as well.
Think of the PDP as a huge if-then-else engine on steroids. Logic that you would traditionally write in code at the PEP can now be converted to config and stored in YAML files. Everytime you change logic, you do not recompile / redeploy code. The way Cerbos has been designed, it's simplicity makes it so easy to deploy, manage, and scale out. It's a single binary!
h
@Jesum Yip thanks for your suggestion. My question with your approach is: are you checking Authorization of your PIP requests in any way?
j
In my case, no. The way it's been designed, there is no need. The fastapi layer has a single resource attribute it attaches to the request sent to cerbos. This single attribute indicates the organisationid that owns the data. This attribute is extracted from the jwt token that the user presents to the api. There is separate authentication and authorization performed by an upstream idp layer during token minting that decides whether to grant a user access to that organization id. In effect, we have designed the jwt token based on an Opaque token pattern. Therefore, the resource attribute we need is always available without needing a separate call to a PIP. It's more performant, and it doesn't expose any private information about the resource. In other words, our IDP sort of acts like a pseudo PIP by attaching that resource attribute (org id) to the logon session via a jwt. We have very good control (we can write custom logic) over what gets injected into the token because of the systems we use and the way we have configured it.
It is sort of arguable that there is some pseudo authorization at the PIP level in our design. The JWT is further checked for validity against the set of issuing keys by an API gateway before the call finally reaches our fastapi layer.
Are you thinking about modelling resource policies with the correct set of attributes? Do the attributes you are looking at consolidating change in real-time / arbitrarily? Will the system that makes the final call to the PDP be able to compute the attributes beforehand (or can they be statically derived)? Are they really attributes for the data or attributes for the user? Can you compute a derivedRole that would infer those resource attributes? There are many ways to skin this cat.
h
Jesum, I am deeply grateful for your thoughts and perspective. THis is very insightful for me and it will take some time to process all of what you've said (maybe even make a POC). It think that correctly modeling the access policies is a great point. I can see how a bad model might be a lot of hassle down the road. And the question that you offered will be useful heuristic to keep in mind. Maybe "how to model access policies well" is a good topic for a blog post on the cerbos site? @Alex Olivier (Cerbos) @Charith (Cerbos)
c
We do have some tips here: https://docs.cerbos.dev/cerbos/latest/policies/best_practices.html, and a longer version of that as a blog post: https://cerbos.dev/blog/mapping-business-requirements-to-authorization-policy. If you have specific questions regarding your system that you want to discuss confidentially, you can also book some time with us: https://go.cerbos.io/workshop
j
For what it's worth, I had to rewrite all my policies about 6 times before I got it right. Granted, I'm not the brightest bulb around lol
s
Thank you @Horia Constantin @Jesum Yip, This is helpful!