fix(graphql): authorize patchEntity by URN type with Edit Entity or the type's management privilege - #19872
Conversation
PR SummaryOverview Privilege rules are aligned with dedicated type mutations: a patch is allowed with Edit Entity on the target (unchanged) or the entity type’s API UPDATE management privilege (e.g. Manage Policies for Tests cover URN/type mismatch, bad URNs, and policy patches with Manage Policies vs Edit Entity vs unrelated privileges. Updating DataHub documents this as a breaking change for clients that passed a wrong Reviewed by Cursor Bugbot for commit c5fc28d. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3470eb7. Configure here.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
3470eb7 to
2a77a45
Compare
|
CI note: the first push failed Fixed in 7e68485: Edit Entity remains sufficient for every entity type except the platform-managed ones ( |
The patch authorization check used the client-supplied entityType as the resource type for policy matching, while the patch itself is applied to the URN's entity type. A grant scoped to one entity type could therefore be matched against a URN of another type by claiming the wrong entityType. Take the type from the URN, and reject requests whose URN cannot be parsed or whose entityType disagrees with it.
7e68485 to
e3f8617
Compare
|
Scope reduced, force-pushed as a single commit (e3f8617). Following the review discussion: unscoped Edit Entity is treated as the top of the privilege hierarchy in this codebase, and the What remains is the part that is correct under either model: the authorization check now takes the entity type from the URN (which is what the patch is applied to) instead of the client-supplied |
…hEntity In addition to Edit Entity on the target, patchEntity and patchEntities now accept the entity type's own API UPDATE privilege (for example Manage Policies for dataHubPolicy), matching the dedicated GraphQL mutations for those types. Edit Entity remains sufficient for every entity type.
|
Second commit (0ad2a43) adds the rule agreed with the security lead: This is a pure widening: Edit Entity remains sufficient everywhere, so unscoped Edit Entity keeps its place at the top of the hierarchy, and actors who were granted a type-specific management privilege can now use the generic patch mutation the same way they already can use the dedicated mutations. The URN-derived type check from the first commit is unchanged. Tests cover Manage Policies alone (allowed), Edit Entity alone (allowed), and an unrelated privilege (denied). Description and release note updated. |

Summary
AuthorizationUtils.isAuthorizedForPatch, used by both thepatchEntityandpatchEntitiesGraphQL mutations, took the entity type for its authorization check from the client-suppliedentityTypeargument and only fell back to the URN when that argument was absent. The patch itself is always applied to the URN's entity type (PatchResolverUtilsresolves the type from the URN). So the resource type used to match policies and the type actually written could differ: a caller holding an Edit Entity grant scoped to, say, datasets could get a write to a URN of another type authorized by claimingentityType: "dataset".This PR makes two changes to that check.
entityTypethat disagrees with the URN is rejected with a warning.dataHubPolicy, Manage Secrets fordataHubSecret, Manage Global Settings forglobalSettings, the user-and-group privileges forcorpuser/corpGroup. This matches what the dedicated GraphQL mutations for those types already accept. For entity types without a type-specific rule the check is simply Edit Entity. This is a pure widening: nobody who could patch before loses the ability.AuthorizationUtils.isAuthorizedForPatch: URN-derived type, deny on unparseable URN, deny on mismatch; privilege group is the type's API UPDATE privileges plus Edit Entity.PatchEntityResolverTest: a glossary-term URN withentityType: "dataset"is rejected and never reachesingestProposaleven with an always-allow authorizer; an unparseable URN is rejected; a policy patch succeeds with Manage Policies alone and with Edit Entity alone, and is denied with an unrelated privilege.docs/how/updating-datahub.md: Breaking Changes entry.Behavior change
Clients that omit
entityTypeor pass the URN's actual type see no change to what is required of them. Clients that pass a mismatchedentityTypenow receive an authorization error instead of having the request checked as the claimed type. Actors holding a type-specific management privilege (for example Manage Policies) without Edit Entity can now usepatchEntityfor that type, as they already could through the dedicated mutations.Scope note
An earlier revision of this PR required the type-specific management privilege for policies, secrets, and settings and no longer accepted Edit Entity for them. That was reverted after review: unscoped Edit Entity is the highest privilege in this model and the
MANAGE_*privileges are UI carve-outs, so requiring one on top of the other inverted the hierarchy and would have broken deployments whose policies are built around unscoped Edit Entity. The current rule accepts either.Verification
spotlessApplyondatahub-graphql-core; markdown prettier on docs.PatchEntityResolverTest(7) andPatchEntitiesResolverTest(7): 14 tests, 0 failures.Checklist