Skip to content

Make the FAB roles PATCH endpoint replace permissions, not just add them - #71933

Merged
vincbeck merged 2 commits into
apache:mainfrom
dheerenmohta:worktree-agent-a3e56ab99cdc75723
Aug 24, 2026
Merged

vincbeck merged 2 commits into
apache:mainfrom
dheerenmohta:worktree-agent-a3e56ab99cdc75723

Conversation

@dheerenmohta

Copy link
Copy Markdown
Contributor

PATCH /roles/{name} only ever added permissions found in the request body to a role; it never revoked permissions that were on the role but missing from the body, so there was no way to remove a permission from a role through the stable REST API. The endpoint already required "PUT"-level authorization, and every other PATCH endpoint in this API (connections, dags, dag runs, pools, variables) treats a field as fully replaced once it is present in the request (via model_fields_set) or named in update_mask -- roles just never extended that convention to the "actions" list. This also fixes update_mask silently letting stray "actions" in the body get applied even when the mask didn't request it.

A 2023 attempt (#30193) added a separate POST .../actions/revoke endpoint instead of fixing PATCH, which required callers to compute their own diff and stalled on bikeshedding over new exception classes and HTTP status codes; it went stale and was closed unmerged. This instead makes PATCH itself diff against the role's current permissions and apply add/remove using the security manager's existing single-item methods, so the request body can just state the desired end state.

closes: #18714
related: #30193


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Sonnet 5)

Generated-by: Claude Code (Sonnet 5) following the guidelines

PATCH /roles/{name} only ever added permissions found in the request
body to a role; it never revoked permissions that were on the role but
missing from the body, so there was no way to remove a permission from
a role through the stable REST API (apache#18714). The endpoint already
required "PUT"-level authorization, and every other PATCH endpoint in
this API (connections, dags, dag runs, pools, variables) treats a field
as fully replaced once it is present in the request (via
model_fields_set) or named in update_mask -- roles just never extended
that convention to the "actions" list. This also fixes update_mask
silently letting stray "actions" in the body get applied even when the
mask didn't request it.

A 2023 attempt (apache#30193) added a separate POST
.../actions/revoke endpoint instead of fixing PATCH, which required
callers to compute their own diff and stalled on bikeshedding over new
exception classes and HTTP status codes; it went stale and was closed
unmerged. This instead makes PATCH itself diff against the role's
current permissions and apply add/remove using the security manager's
existing single-item methods, so the request body can just state the
desired end state.
@vincbeck
vincbeck merged commit 9b9fc0e into apache:main Aug 24, 2026
78 checks passed
@boring-cyborg

boring-cyborg Bot commented Aug 24, 2026

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

imrichardwu pushed a commit to imrichardwu/airflow that referenced this pull request Sep 11, 2026
…hem (apache#71933)

PATCH /roles/{name} only ever added permissions found in the request
body to a role; it never revoked permissions that were on the role but
missing from the body, so there was no way to remove a permission from
a role through the stable REST API (apache#18714). The endpoint already
required "PUT"-level authorization, and every other PATCH endpoint in
this API (connections, dags, dag runs, pools, variables) treats a field
as fully replaced once it is present in the request (via
model_fields_set) or named in update_mask -- roles just never extended
that convention to the "actions" list. This also fixes update_mask
silently letting stray "actions" in the body get applied even when the
mask didn't request it.

A 2023 attempt (apache#30193) added a separate POST
.../actions/revoke endpoint instead of fixing PATCH, which required
callers to compute their own diff and stalled on bikeshedding over new
exception classes and HTTP status codes; it went stale and was closed
unmerged. This instead makes PATCH itself diff against the role's
current permissions and apply add/remove using the security manager's
existing single-item methods, so the request body can just state the
desired end state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make it possible to delete a permission from a role using the stable REST API

2 participants