keto
keto copied to clipboard
Allow defining ABAC relation tuples
Is your feature request related to a problem? Please describe.
ABAC rules can not be added simply with relation tuples as the attributes have to be checked.
Describe the solution you'd like
In general, the database will not be the only source of relation tuples. For subject set rewrites we will have to dynamically generate relation tuples that are used for evaluation of requests.
ABAC rules can be added dynamically the same way depending on the actual attributes of the request context.
An example ABAC rule: allow write access to repository form sub net 192.168.2.0/24
This would translate to the following relation tuples (omitting namespaces):
repository#write@<192.168.2.0/24#accessing-from> <- fixed tuple always present
192.168.2.0/24#accessing-from@user <- dynamic tuple added based on attributes of the requests
These dynamic tuples only have to be computed initially on request. It would be best to have the client define them so that Keto does not have to support parsing 1000 different data formats and queries on them.
In essence, the client would translate any attributes it likes into relation tuples that then are used by keto for evaluation. In general, the client can add relation tuples dynamically only for single requests.
The check/expand API would have to get an additional parameter for dynamic relation tuples.
Describe alternatives you've considered
Keto should not support a complex language with an even more complex engine like OPA. Any other idea for implementing ABAC should be collected in this issue.
So, having Open Policy Agent already there to be able to do all the complex attribute based authorization control...
- Should we even have ABAC in Next Gen Keto?
- If yes, what would be the beneficial difference Keto offers compared to using Open Policy Agent +Keto ACL extention?
I think the Open Policy Agent +Keto ACL extention pair (OPA+Keto)
is just so endlessly powerful 🎉 that pretty much anything, including ABAC, RBAC, etc. can already be configured by users in rego. (...having #318 is just too exciting 😍)
The only thing may be useful Keto could provide in addition to ACL is an API for RBAC (literally just an API) using ACL as backend as planned, but even such opinionated RBAC API might be too constrained and not suffice all users needs as can be self-built with the OPA+Keto combination.
Maybe just provide documentation of how to use OPA+Keto to build highly customized RBAC, ABAC, ... systems for those ORY users that need it? @aeneasr @zepatrik
The problem with OPA is that it does not have any persistency, so one problem will definitely be the management of resource definitions in OPA, especially if we're looking at high scale. But I generally agree that we should not try to come up with too much fancy stuff here as it will make everything more complicated and bespoke.
This could be achieved also by allowing a check request to pass a list of subjects. A simple case is where *
is interpreted as a special subject that anyone can impersonate. Tuples can then be added accordingly to reflect the permissions of anonymous users. A request for user foo
would then be transformed by the client to the check request: object#access@(foo|*)?
.
This can then be used to add all the states a user can currently impersonate (e.g. by checking for some attributes) to the actual request:
let subject = [user.userId]
if (user.isAtWorkLocation()) {
subject = [...subject, "special at work user id"]
}
return keto.check({ object, relation, subject })
with the Keto relation tuples in the database:
disclosed_object#access@special_at_work_user
not_disclosed_object#access@user_foo
This could then be leveraged using all the set operators theoretically available in subject set rewrites to build even boolean operations on these subjects. This would probably work way better in a setting where you have many attributes that a user can have, while the first idea would be less complex to set up with view attributes. This would not solve integration with other services (like OPA), I guess.
A am not fully against ABAC support, but yet I think we might are going in an unsuitable direction with builtin ABAC support for ACL or likewise ideas. Zanzibar is not even designed to do this at its lowest level.
I don't quite see the vision of Keto's builtin ABAC system, because of the question:
- If one can use OPA+KetoACL (https://github.com/ory/keto/issues/319#issuecomment-728262296), can we still deliver actual value to Keto users with a standalone and fairly limited Keto ABAC?
We know that building a ABAC-supporting system is hard to get right and generic enough that users can highly adjust it to their unique use cases where whatever system they are building, such ABAC provider can output an arbitrary decision given arbitrary request input (not just "He
is allowed
to do this
"). That's why OPA exists.
If I did not miss anything discussed and from my perspective, I see the biggest potential for Keto lays in ACL for the following reasons:
-
If this project can put all efforts and focus of the Keto on getting ACL efficient and reliable, yet adhering to its simple API, we can solve the most crucial problems in most access control systems:
decisions at scale
-
That's why we shouldn't even think about implementing ABAC(-ish) solutions into the early Keto versions and instead provide all the glue (extentions/integrations and docs/tutorials) to ignite the probably incorrigible and most poweful open-source access control system combination one could bring most value:
-
Open Policy Agent + Keto ACL
.
-
-
Where OPA gives all the flexibility to use Keto's distributed ACLs for sub-decisions executed in the OPA's policy engine.
- OPA's scalability issues are compensated by Keto ACL
- Keto's policy/decision limitations are compensated by OPA
As much as I would like to think that, there can't be done much more improvement and I don't see a successful ABAC implementation within Keto. (Remember: Google's Zanzibar is a base-system - and so should Keto, I think).
Hm, I kind of agree with you @robinbraemer . Thinking about ABAC now is a good step forward, but we have yet to specify the user set rewrite configuration layout, figure out the scalability architecture, and more. Bending concepts of the ACL to solve this is maybe not the best path forward for the moment. Maybe we should keep it in the back of our heads and include it when planning new APIs, but not actually implement or talk about it yet.
Also, I would not fixate too hard on OPA. I love the project and the people behind it, but so far the project has been quite disappointing when actually using it. Getting the policies right is hard (learn a new programming language that is quite different from others due to its query structure), it is difficult to make changes persistent at scale (because it is not a concern for OPA), latency has been an issue from day one (and not yet solved unless you have maintainer level knowledge of rego parsing internals), and resource consumption is exorbitant for certain types of operations and datasets because everything is loaded in memory.
I am :100: % with you there, I was afraid already that my comments are not clear enough. Basically, both of the ideas presented above try to find an idea of how to integrate Keto with any other service. This would allow ABAC but also many other things. The only thing that would change in Keto would be one of:
- accept temporary ACL rules that are just considered for a single request
- allow to specify multiple subjects for a request, Keto will return "allowed" if any of the subjects is allowed
Keto would still not have any ABAC related features, it would just be very easy to add another service that allows that.
I guess casbin can help here
Auth0/openFGA was so kind to implemented the here mentioned approach of contextual tuples for us, so we can play with it already https://docs.fga.dev/modeling/basics/contextual-time-based-authorization The permission function in OPL were specifically designed to take an extensible context to allow adding request attributes later on. Ideally we want to support two cases here:
- Attaching attributes to a request. Unlike considered earlier, it probably makes more sense to have a simple
string->string
orstring->bool
mapping. A permissions function could then look similar to
class Document implements Namespace {
related: {
owners: User[]
collaborators: User[]
}
permits = {
view: (ctx: Context) => this.related.owners.includes(ctx.subject) || (this.related.collaborators.includes(ctx.subject) && ctx.attributes["is_working_hours"])
}
}
- Attaching attributes to an object. This would be another table storing the
(object, key)->value
mapping. The attributes are then exposed in OPL by adding an attributes key to the namespace class and accessing the attributes there to compare them to constants or (more useful) the attributes in the context. IMO the more useful use-case will be to filter/sort results by these attributes.
This approach will be easier to understand for devs, while not being too complex and providing about the same expressiveness as contextual tuples.
Hello contributors!
I am marking this issue as stale as it has not received any engagement from the community or maintainers for a year. That does not imply that the issue has no merit! If you feel strongly about this issue
- open a PR referencing and resolving the issue;
- leave a comment on it and discuss ideas on how you could contribute towards resolving it;
- leave a comment and describe in detail why this issue is critical for your use case;
- open a new issue with updated details and a plan for resolving the issue.
Throughout its lifetime, Ory has received over 10.000 issues and PRs. To sustain that growth, we need to prioritize and focus on issues that are important to the community. A good indication of importance, and thus priority, is activity on a topic.
Unfortunately, burnout has become a topic of concern amongst open-source projects.
It can lead to severe personal and health issues as well as opening catastrophic attack vectors.
The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone.
If this issue was marked as stale erroneously you can exempt it by adding the backlog
label, assigning someone, or setting a milestone for it.
Thank you for your understanding and to anyone who participated in the conversation! And as written above, please do participate in the conversation if this topic is important to you!
Thank you 🙏✌️
<... snip>
- Attaching attributes to an object. This would be another table storing the
(object, key)->value
mapping. The attributes are then exposed in OPL by adding an attributes key to the namespace class and accessing the attributes there to compare them to constants or (more useful) the attributes in the context. IMO the more useful use-case will be to filter/sort results by these attributes.
With regard to the model surrounding attached attributes, I assume attributes would be governed by the same consistency model as the rest of the tuple model. Would that be a correct assumption or am I missing something obvious?
I ask because there may be an edge case surrounding former access and current access when taking into account attributes.
For example: Bob once had access to Alice's document readme.md
. Now, Alice has limited access to readme.md
using the attribute is_working_hours
. From my understanding of Zanzibar, this would mean that Bob would retain access to readme.md
for the versions of that object for which he was Allowed but all versions from the commit_time
of the attribute is_working_hours
, Bob would only have access to readme.md
IFF his access attempt fulfilled the is_working_hours
attribute.
I think, in addition to those two cases mentioned by @zepatrik, the implementation would need a third case:
- Creating, Modifying or Removing attributes attached to an object would constitute a snapshot action. Resolving access would need to take into account the tuple state and the attribute(s) state for the
zookie
. Of course, in absence of azookie
the current state would prevail.
FYI, I just saw another Zanzibar inspired (fully opensource?) projects which offer RBAC, ABAC and ReBAC model. I don't want to comment which one is better. (I haven't had time to evaluate it). I do hope both projects can help and inspire each other.
Ref: https://www.permit.io/abac https://www.permit.io/rebac https://www.permit.io/blog/announcing-abac https://docs.permit.io/category/build-policies
PS: I don't have any relationship w/ the permit project/com/team. I just monitor this ticket for sooo long..... Let me know if anyone want to remove the links. ty.