-
Notifications
You must be signed in to change notification settings - Fork 949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Security Model #4198
Comments
@tokoko we started thinking about a possible solution, that we can share after completing the internal review, but first we'd like to ask a few questions to verify our understanding of the initial requirements (*):
(*) We also like option 2 for the reasons you mentioned above. Additionally, we can share a reviewed definition to better align with the usual RBAC permission models coming from our previous work with Keycloak permission features. |
I'm not sure I'll be able to list everything comprehensively here, but I think there're two major sets of permissions (and protected resources as a result) to consider here. The first part is CRUD-like permissions for manipulating objects in feast registry: Another aspect is managing access to the underlying data.
You mean SDK usage without setting individual components as
I'm with you on that one. I think we should start by agreeing on some sort of
Maybe, I'm not sure what that would look like though. Do you mean listing defined roles or permissions that can be specified in those roles?
Cool, we can start there then. |
@dmartinol Sorry, I just took a look at pycasbin. I guess it's a rules engine, so disregard my answer above. It looks promising, but I'm fine with home-grown option as well, depends on how complicated our version will be to maintain I guess. |
Yep, something like
|
So you mean the FeastObjectType enum (to be extended to support the map also BTW: what about the |
Yes, that sounds about right. not sure what you mean about |
🤔 yes, seeing it from this perspective, this is fine. So, for completeness we probably need all the CRUD actions like: |
I'm undecided between having |
@tokoko on the implementation side, do you think a programmatic solution is mandatory (e.g., like the PyCasbin enforcer), or can we avoid changing the code and instead use decorators to enforce permission policies? |
@dmartinol @tmihalac I think the most logical points where permission enforcement should happen is in the methods of the major feast abstract classes ( |
@tokoko we want to share with you a gist describing a proposal to implement this functionality. The modelling part follows your initial requirement but tries to adapt it to some standards that we've found in Keycloak. |
@dmartinol Can you clarify what's
|
Also, what's To me something like this makes more sense instead of
And then we would have concrete classes like |
Quoting Keycloak docs,
So, the reason for having read_policy = RoleBasedPolicy(['reader', 'viewer'])
admin_policy = RoleBasedPolicy(['admin'])
permission1 = FeastPermission(...,policies=[read_policy, admin_policy],...)
permission2 = FeastPermission(...,policies=[read_policy],...)
permission3 = FeastPermission(...,policies=[admin_policy],...)
It is not a
The model that you are proposing describes the permissions allowed for any given role instead of the roles/policies allowed for any given permission. Since the cardinality is N-N, it probably doesn't change much, but please consider that roles are not policies, and in the future we could extend the concept and manage policies that are not based on roles. @jeremyary do you have any modelling preferences here? |
The idea here is that another entity like the Maybe |
@dmartinol thanks, that makes sense and looks like keycloak uses those terms so mustn't confusing for everyone. I'm probably influenced by AWS terms where policies and permissions aren't really separated in any way, policies are more or less just a collection of permissions. My only concern is that if we end up sticking with just |
I may be the one missing some context here, sure. The way I think about it when a user authenticates in some way, auth provider is also usually the one that can provide additional info regarding roles and attributes. mlflow has something similar where |
@tokoko I would suggest each, as the flexibility will be great for users |
I am also pro Option 2 at the moment |
@dmartinol Looks really good overall, thanks. Obviously still going through it, but I'll leave remarks here along the way:
|
Agree, there are no keycloak-specific details, and the required URLs can be retrieved from the discovery URL like |
This was also my initial concern (see previous comment, and you suggested to use decorators, which instead may be difficult to apply to
because the decorator, IIUC, needs to identify the input arguments containing the protected resources (e.g. For this reason, we can adopt a programmatic approach (mentioned in the POC) at all identified entry points, allowing us to apply precise validation, such as: a : ResourceA = ...
_get_security_manager().assert_permissions(a, AuthzedAction.EDIT) I've updated the POC with an BTW, this approach works if we agree on the above assumption that we:
We are aware that client code can bypass these start methods and directly access the inner objects; however, this is outside the scope of our investigation. |
I guess I was referring to a more complicated decorator, something that would know how to inspect values passed in |
There's a def assert_permissions(
self,
resource: Resource,
actions: Union[AuthzedAction, List[AuthzedAction]],
):
return True Of course, it's a POC, and we can elaborate on it further |
thanks, overlooked that part. Another question, I understand that role manager and policy enforcer should be global objects, but isn't |
🤔 of course it is, sorry for missing this point! I think we can use the contextvars module to define thread local current user, WDYT? (not sure you got the reply, so adding a mention to @tokoko) |
@dmartinol sorry, forgot to reply here. I'm not too familiar with contextvars. I guess they should work well with fastapi, but not too sure about the flight server (or registry server) as they aren't async. |
@tokoko by async you mean that the parameters are first sent with |
@tokoko we added a section in the POC for the ArrowFlight server use case, using the middleware function to handle the authentication token, extract the user details and pass them to the context of the |
Is your feature request related to a problem? Please describe.
This is an offshoot ticket from #4032. Feast is slowly approaching a state in which all major components can be deployed as remote servers. This enables us to start thinking about a comprehensive security model for access to each of them (registry, online store, offline store)
Describe the solution you'd like
Here's a high-level overview of what I'm expecting from the security model:
I'd avoid incorporating user management into feast as much as possible. We should probably have a pluggable authentication module (LDAP, OIDC, etc...) that takes user/password (or token), validates it and spits out the roles that have been assigned to this particular user. Each server will have to integrate with this module separately, http feature server will get user/pass from basic auth, grpc and flight will get them according to their own standard conventions and pass credentials to the module to get the list of assigned roles. (Somewhat inspired by Airflow security model)
(Option 1) We enrich Feature Registry to also contain information about the roles available in the system and each feast object should be annotated with permissions. In other words, the user would run
feast apply
with something like thisThe upside of the second approach is that it's a lot less invasive than the first one. You could potentially end up with a setup where permissions and objects are managed with some level of separation between them. I think I'm more in favor of this.
The text was updated successfully, but these errors were encountered: