Conversation
…teLink With a domain matching function, the role manager of a concrete domain also holds the links it inherits from matching patterns such as "*". DeleteLink removed the link from that role manager and from every domain matched by the deleted pattern without checking whether another link still granted it, so: - removing "g, alice, admin, domain1" also dropped the grant that "g, alice, admin, *" still gives in domain1, and - removing "g, bob, admin, *" also dropped bob's own "g, bob, admin, domain2". Enforce then denied these requests until the policy was reloaded. DomainManager now records the links as they were added and only deletes a link from a domain when no remaining link grants it there. rebuild() replays these records instead of the per-domain role managers, which also hold the copied pattern links. Generated-by: Claude Opus 5.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
With a domain matching function (for example
e.AddNamedDomainMatchingFunc("g", "KeyMatch", util.KeyMatch)), removing one grouping rule can revoke a role that another rule still grants.Enforcethen denies requests the policy allows, and keeps doing so untilLoadPolicy()runs.Using
examples/rbac_with_domain_pattern_*:Any code path that calls
DeleteLinkdoes this:RemoveGroupingPolicy,DeleteRoleForUserInDomain,UpdateGroupingPolicyandRemoveFilteredGroupingPolicy, as well as watcher updates on other nodes.Cause:
DomainManager.getRoleManagercopies the links of every matching pattern domain into a concrete domain's role manager, andAddLinkadds a pattern link to every domain that already exists. After that copy, a domain's role manager can't tell its own links from the ones it inherited.DomainManager.DeleteLinkdeleted the link from the domain itself and from every domain the deleted pattern matches, without checking whether another link still granted it there.Fix:
DomainManagernow records each link with the domain it was added in.DeleteLinkremoves that record first, then deletes the link from a domain only when no remaining record grants it there: neither the domain itself nor a pattern that matches it.rebuild()(run byAddDomainMatchingFunc) replays these records. Before, it replayed the per-domain role managers, and those also hold the copied pattern links, so each copied link would be recorded as the domain's own.Clearresets the records, andDeleteDomaindrops the records for that domain.ConditionalDomainManagerhas its ownAddLink/DeleteLink/rebuild, so this change doesn't touch it.Testing
TestRemoveGroupingPolicyWithDomainPattern(rbac_api_with_domains_test.go) runs the scenario above through the enforcer and checks thatLoadPolicy()gives the same answers.TestDomainPatternDeleteLinkKeepsLinksStillGranted(rbac/default-role-manager/role_manager_test.go) covers both directions at the role manager level, and checks that a link is gone once no rule grants it any more.TestDomainPatternRebuildUsesAddedLinksguards therebuild()change. A"*"link copied intodomain1must not become adomain1link of its own when the matching function is set again.Results:
master@524f3f2: the first two tests fail (alice, domain1, data1, read: false, supposed to be true;bob, domain2, data2, read: false, supposed to be true).go test ./...suite passes,go test -race ./rbac/... .passes, andgofmtandgolangci-lint run ./...(v2, repo config) report 0 issues.I found this bug with AI assistance (Claude, per the ASF generative tooling guidance) and used it to write the fix and tests; I reviewed the change and ran the tests above.