-
Notifications
You must be signed in to change notification settings - Fork 16.4k
Update authorization logic on list APIs in FabAuthManager
#54197
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
Conversation
providers/fab/src/airflow/providers/fab/auth_manager/fab_auth_manager.py
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, a few points to mention:
- New core providing an extra unknown argument to old fab provider.
- For other list endpoint using
AccesView.Somethingfor permission we will keep returning 403 and not an empty list when permission is missing. For instanceget_plugins, that might feel inconsistent to sometimes end up with 403, and sometimes with 404 on listing endpoints.
Many a simple approach would be to keep the change located to the fab provider, and change _is_authorized_dag so instead of granting access if len(authorized_dags) > 0, it will grand access if:
- user has access to all dags: self._is_authorized(method=method, resource_type=RESOURCE_DAG, user=user) or one permission with
permissions.RESOURCE_DAG - or user has at least one dag permission with
RESOURCE_DAG_PREFIX. (The intend is to grant access to dags list to this user so it won't 403 in this case)
This way we don't change any of the core code and we could possibly get what we want:
- no permissions at all -> 403, makes sense
- at least one permission set for dag but no dag matching -> 200 empty list
- match endpoint filtering behavior, filters are set, but no resulting dag match the permissions set -> 200 empty list
And we don't get to modify core, add comments here and there, make it consistant with 'providers' or 'access view' endpoints and write compat code.
That's true only for the fab auth manager. The interface we call is |
|
And for the related issue, it won't solve it in case the user does not have any dag access at all (full, or at least 1 prefix permission), but to handle this we can simply catch the 403 on the front-end and return an empty list, that's what we plan to do for the get_providers call in the homepage that crashes the UI for user that do not have access to the plugin view. |
|
My concern with this approach is each auth manager needs to implement their own logic: "is the user is authorized to access at least one DAG?". Depending on the auth manager underlying service/tool it is using, it can be complex to check that. Very often, I think, it will end up using The solution you are proposing is a valid solution but only for Another possible solution is to add a new method |
|
After discussing offline with @pierrejeambrun , I actually I agree with him now, I am closing this PR and create a new one to update |
Resolves #53936.
Follow-up of this comment.
Description
For every list Dag or sub Dag entity (e.g. task instance, dag run, ...), the current authorization is a bit messy in
FabAuthManager. Since a user can have access to specifics Dags (and not all of them), when the user lists Dags, Airflow usesget_authorized_dag_idsfrom auth manager to figure whether the user has access to at least one Dag. If the user has access to at least one Dag then the access is granted to the API, if not the access is denied. If the access is granted, then the implementation of the API itself uses againget_authorized_dag_idsto retrieve the list of Dags to return to the user.I do think we should not check whether the user is authorized to list dags because the API returns only the dags the user has access to anyway. The consequence would is, instead of having a 403, the user would get an empty list of DAGs. In a fined grained access context, it makes more sense. Let's say I am user who has access to the Dag
testonly but this Dag does not exist (or has been removed) in the Airflow environment. In the current implementation, if I list Dags, I'll get a 403, but does it make sense? I have permissions to access Dags, I just happen to not have access to Dags existing in the environment. @pierrejeambrun also brought it up in his comment that with the introduction of filters, having this logic on the API level does not make sense.Testing
I tried to test it as much as I could but please test it on your end as well since this PR is quite impactful.
Future
Dags is the only resource type having fine grained access (authorizing a user having access to one specific Dag) in Airflow because it has been historically like this in
FabAuthManager. But technically, nothing prevent us today, throughKeycloakAuthManagerfor instance, to give permissions to users to say, one specific connection. Everything would work but the list API, you would get a 403. I am planning to add such capability across auth managers to other resources in the near future.^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named
{pr_number}.significant.rstor{issue_number}.significant.rst, in airflow-core/newsfragments.