Petra Barus
09/16/2022, 9:17 AMuser-1
that purchased order order-1
that contains 2 videos video-1
and video-2
. when user-1
want to view
a video video-1
, the system will do check. How to best achieve this?
Should the system created a new principal policy on every successful purchase?Charith (Cerbos)
video
that has a condition for the view
action that checks whether the resource (say, video-1
) is in the list of purchased videos of the principal (user-1
). You have to send the list of purchased videos as a principal attribute. That will work if a typical user only purchases a small number of videos. If they can purchase hundreds or thousands, then it won't be practical to list all. In that case, I don't think using Cerbos for that would be very helpful because you can just do a much more efficient database check to see if the video is in the purchased list of the user.Petra Barus
09/17/2022, 12:37 AMprincipalPolicy:
principal: user-1
rules:
- resource: videos:video-1
actions:
- action: ['view', 'download_offline']
effect: allow
would that be efficient?Charith (Cerbos)
Petra Barus
09/19/2022, 3:54 AMCharith (Cerbos)
standard
level where users can play a video online only, a gold
level where they can play online or download the video, a preview
level where users can play a video only once. Here's a Playground link with a sample resource policy that enforces those rules: https://play.cerbos.dev/p/T632814caYDGEAPiZnzeEEyYPZcgkz31. When a user tries to do something with a video, you need to lookup the licence level assigned to that video for that user and send it to Cerbos. If there's no licence level stored in the database, that means that user has not bought it. You can either deny the request right away or assign them a default licence level like preview
and perform the check using Cerbos anyway.Petra Barus
09/19/2022, 9:45 AMapiVersion: api.cerbos.dev/v1
resourcePolicy:
version: default
resource: "videos"
rules:
- actions:
- "view"
effect: EFFECT_ALLOW
roles:
- customer
condition:
match:
expr: request.principal.attr.is_enrolled == true
The attr is_enrolled
will be queried between tables to determine whether the user is enrolled to certain videos.
Then I will send this
{
"id": "123456-7890123",
"roles": [
"customer"
],
"attr": {
"is_enrolled": true
}
}
The downside is, that the backend will need to query everytime they need to check.apiVersion: api.cerbos.dev/v1
principalPolicy:
version: default
principal: "user.123456"
rules:
- resource: "videos"
actions:
- action: "watch"
effect: EFFECT_ALLOW
condition:
match:
expr: R.id == "video.123456"
- action: "watch"
effect: EFFECT_ALLOW
condition:
match:
expr: R.id == "video.1234567"
Charith (Cerbos)
I am just curious, if I principal policy like this, how’s the database performance?Well, it's hard to give you a definitive answer there because it depends on a lot of factors. This is not the most efficient way to do it though and, frankly, I don't see the point of doing that. If all you're interested in are the videos that a user has access to, it would be much simpler to store them in a database table. That data won't be opaque, you can add indexes and partitions to look them up very efficiently, and you don' t have to constantly keep updating the policies (which is more complicated than adding a row to a table) as people buy more videos.