Hi Ory team, Apologies for the long message. I’m...
# talk-keto
b
Hi Ory team, Apologies for the long message. I’m evaluating Keto to accomplish an authorization and RBAC requirement for a SaaS platform in my organization. The SaaS allows users to have their own organizations, multiple projects inside an organization and multiple applications inside a project. For user management, we plan on having users, groups, roles and permissions. The idea here is that a group would be a collection of users and a role would be a collection of permissions. Hence a role can be attached to a single user as well as a user group. In order to accomplish this, we have come up with the following model in Keto. Namespaces:
organizations, projects, applications, roles, groups, permissions
We can come up with a few sample relation tuples as follows;
Copy code
organizations:starkindustries#users@(groups:admin#member)
organizations:starkindustries#users@(groups:developer#member)

groups:EngineeringManager#member@john
groups:Engineer#member@sarah

roles:admin#has@(groups:EngineeringManager#member)
roles:developer#has@(groups:Engineer#member)

permissions:*#allowed@(roles:admin#has)
permissions:view-application#allowed@(roles:developer#has)
permissions:develop-application#allowed@(roles:developer#has)
permissions:deploy-application#allowed@(roles:developer#has)
permissions:delete-application#allowed@(roles:developer#has)

projects:ProjectFoo#view@(permissions:view-project#allowed)
projects:ProjectFoo#edit@(permissions:edit-project#allowed)
projects:ProjectFoo#delete@(permissions:delete-project#allowed)

applications:HelloWorld#view@(permissions:view-application#allowed)
applications:HelloWorld#develop@(permissions:develop-application#allowed)
applications:HelloWorld#deploy@(permissions:deploy-application#allowed)
applications:HelloWorld#delete@(permissions:delete-application#allowed)
Question 01: I hope this would be an acceptable model to handle our use case! Appreciate some feedback on this approach. Second point to consider is that since we have multiple organizations, we cannot use object names like “admin”, “developer”, “view-application” etc since multiple orgs could have the role admin. Hence as instructed in the Keto docs, we used UUIDs for these object names for each organization in the SaaS platform.
Copy code
admin : b67d529a-0767-4641-8a1d-edccec24604c
developer : 61a1f3ac-541a-4ba0-a953-d0fd44fb06b4

create-project : 77fcc09c-bf25-45e3-a472-11a9eefecda6
view-application : c66d1eb2-9550-4085-9eb5-e4c211ec9d1a
Relation tuple based on above UUIDs. Role admin has view application permission
permissions:c66d1eb2-9550-4085-9eb5-e4c211ec9d1a#allowed@(roles:b67d529a-0767-4641-8a1d-edccec24604c#has)
Therefore, when checking for users with permission 77fcc09c-bf25-45e3-a472-11a9eefecda6 (create-project) we would only get the users in the organization which has the “77fcc09c-bf25-45e3-a472-11a9eefecda6" permission without listing users of other orgs. With this we’ll have to maintain the object - UUID mapping in one of our application databases. Question 02: I just wanted to clarify if there is any way that we can onboard this mapping to Keto as well rather than maintaining it on our end. Question 03: Do you have any best practices that we can follow when building up a central authorization service for a SaaS platform using Keto? I would really appreciate if you can share any other suggestions to handle our use case with Keto. Thanks in advance!
b
Why would you map the permissions to uuids? Wouldn't they be the same across all tenants?
n
Hi, Thanks for sharing your setup, it is always cool to see more Keto usage 🙂. Here are my ideas regarding your questions. Q1: This is definitely an acceptable model! The only thing to keep in mind is that the tuple
permissions:*#allowed@(roles:admin#has)
will (probably) not do what you think. There is no special wildcard in keto, so this will just map the literal
*
object in the permissions namespace. The other thing to note is that you are currently explicitly defining the transitions from a permission to a user (through subject-set expansions). This is currently the only way (so great job!), but there is the addition of user-set rewrites in the works (https://github.com/ory/keto/issues/263), which will let you reduce the amount of relation tuples you have to maintain in Keto. Q2: Since very recently, Keto maps all objects to UUIDs internally, but this is transparent to the user, as the same string always maps to the same UUID (UUID v5). In your case, I'd just recommend to prepend the permission names with the organization (since they should be scoped by org) like such:
create-project
becomes
starkindustries/create-project
. This is easy to read (in a log), and easy to map. Q3: I think you are on a very good track already. More examples and best practices are on the way with the before-mentioned user-set rewrites, as this feature will somewhat simplify the setup Keto users will have to do. I hope my questions help you, if not please reach out 🙂
b
@narrow-van-43826 To reply to your answer to Q2, what do you think about scoping permissions to an organization? We don't know if the user has the ability to edit the permission names (I assume not)
It doesn't sound logical and adds more overhead to have permissions per organization
n
Whether or not the overhead is warranted depends on the use case. In the example, the organization was never part of the path from the permission to the user. So if you ask Keto for
permissions:view#allowed@User
, there is no notion of an Organization in that query, and the query will succeed or fail regardless of
user
is part of some organization. In that use case, modifying the tuples and the query so that you can ask
permissions:myorg/view#allowed@User
simplifies some manners (you can ask directly what you want), but also adds an overhead (you have to add more tuples into Keto).
b
@narrow-van-43826 Thanks a lot for taking the time to share such an informative response. Really appreciate it. So just to be clear, what you are recommending is to straightaway use string names like “starkindustries/create-project”, instead of using a UUID and having a mapping in our application data, right? So going forward I can replace the following
permissions:c66d1eb2-9550-4085-9eb5-e4c211ec9d1a#allowed@(roles:b67d529a-0767-4641-8a1d-edccec24604c#has)
with
permissions:starkindustries/view-application#allowed@(roles:starkindustries/admin#has)
@bulky-greece-49863
Copy code
Why would you map the permissions to uuids? Wouldn't they be the same across all tenants?

I stumbled upon the same predicament when designing this and like @Henning Perl (Ory) already mentioned, there should be a way to distinguish if a particular permission belong to a specific organization.

Eg: Assume there are two organizations (orgA and orgB) and both can have the admin role

permission:view-application#allowed@(roles:orgA/admin#has)
permission:view-application#allowed@(roles:orgB/admin#has)

If we expand the view-application permission it will result in users with admin roles in both orgs. If we use a UUID for the view-application permission in both the orgs

permission:31d2b674-7136-45e0-99a8-62e4b93547fe#allowed@(roles:orgA/admin#has)
permission:ed4d8238-401b-4a82-a929-15970284497c#allowed@(roles:orgB/admin#has)

Then an expand query for "ed4d8238-401b-4a82-a929-15970284497c" will only result in the users with the orgB/admin role.

Now I guess we could go for the following which is much easier
permission:orgA/view-application#allowed@(roles:orgA/admin#has)
permission:orgB/view-application#allowed@(roles:orgB/admin#has)
Thanks all for the feedback!
b
Ah, yeah that makes sense
n
Yes, based on your description I'd go with "starkindustries/create-project" for the name 🙂.
b
Great. Thanks a lot @narrow-van-43826
@narrow-van-43826 one small question. If we start using strings like “starkindustries/create-project” instead of a UUID, now that the mapping is happening internally, do we still have to stick to the 64 character limit in object names or are you planning on upgrading it?
n
With the UUID mapping you are free to use arbitrary-length strings. The change is already in master and will land in the next release.
b
Excellent! Thanks!
s
The release already happened on Monday btw 😉
b
Thanks @steep-lamp-91158 for the update.