Skip to content

fix(query): respect wildcard ExcludedSubjects in LookupSubjects intersection#3136

Open
matte1782 wants to merge 2 commits into
authzed:mainfrom
matte1782:fix/lookupsubjects-wildcard-intersection-excluded
Open

fix(query): respect wildcard ExcludedSubjects in LookupSubjects intersection#3136
matte1782 wants to merge 2 commits into
authzed:mainfrom
matte1782:fix/lookupsubjects-wildcard-intersection-excluded

Conversation

@matte1782
Copy link
Copy Markdown

Fixes #3135.

Problem

In the experimental query-plan engine, intersectSubjectSets (pkg/query/intersection.go) admits a concrete subject matched by the other operand's wildcard without consulting that wildcard's ExcludedSubjects. So a subject explicitly excluded from a wildcard (viewer:* - banned) is re-admitted when the exclusion feeds an intersection ((viewer:* - banned) & reader), and LookupSubjects enumerates a banned subject as authorized. Check is unaffected (it resolves the wildcard ban at the leaf), so this is a Check vs LookupSubjects consistency violation under --experimental-query-plan ls (default off).

This is reachable through the real schema compiler, not just hand-built iterators. For the schema in #3135 the plan compiles to:

Intersection
  Alias(limited) -> Exclusion[ Alias(viewer)->Union(*, ...), Alias(banned)->bob ]
  Alias(reader)  -> {alice, bob, charlie}

Before: IterSubjects(viewable) = [alice, bob, charlie]. After: [alice, charlie].

Fix

intersectSubjectSets now:

  • builds an index of the matching wildcard's ExcludedSubjects and, when admitting a concrete subject matched by that wildcard, applies the exclusion via combineExclusionCaveats — dropping the subject for an absolute exclusion, or conditioning it on the negated exclusion caveat. Reusing combineExclusionCaveats keeps caveated exclusions consistent with how ExclusionIterator already treats them.
  • unions both sides' ExcludedSubjects in the wildcard ∩ wildcard case, since (* - E1) ∩ (* - E2) = * - (E1 ∪ E2) (OR-combining caveats when the same subject is excluded on both sides; an unconditional exclusion dominates).

When neither wildcard carries exclusions the behavior is byte-for-byte unchanged.

Tests

  • pkg/query/wildcard_intersection_test.go: unit subtests in TestIntersectSubjectSets for excluded-concrete dropping (both wildcard sides), caveated exclusion conditioning, and exclusion union in wildcard ∩ wildcard; plus an end-to-end (viewer:* - banned) & reader subtest in TestIntersectionIterator_WildcardBehavior. Each new test fails on main and passes with this change.
  • internal/services/integrationtesting/testconfigs/wildcardmainexclusionintersect.yaml: companion consistency config. The existing wildcardintersectionexclusion.yaml only covers an exclusion whose main set is concrete ((viewer & reader) - banned); this one exercises a wildcard main set ((viewer:* - banned) & reader). It passes the default TestConsistency (stable engine) suite.

go test ./pkg/query/... and go vet ./pkg/query/ pass.

…section

The experimental query-plan engine's intersectSubjectSets admitted a
concrete subject matched by the other operand's wildcard without
consulting that wildcard's ExcludedSubjects. A subject explicitly
excluded from a wildcard (e.g. `viewer:* - banned`) was therefore
re-admitted when the exclusion fed into an intersection such as
`(viewer:* - banned) & reader`, so LookupSubjects enumerated a banned
subject as authorized. Check is unaffected (it resolves the wildcard ban
at the datastore leaf), so this manifested as a Check vs LookupSubjects
consistency violation under `--experimental-query-plan ls`.

intersectSubjectSets now applies the wildcard's exclusions when admitting
concrete subjects, reusing combineExclusionCaveats so caveated exclusions
are handled consistently with the exclusion iterator, and unions the two
ExcludedSubjects sets in the wildcard-with-wildcard case
((* - E1) intersect (* - E2) = * - (E1 union E2)).

Adds unit and end-to-end coverage in wildcard_intersection_test.go and a
wildcardmainexclusionintersect.yaml consistency config (companion to
wildcardintersectionexclusion.yaml, whose exclusion main set is concrete).
@matte1782 matte1782 requested a review from a team as a code owner May 25, 2026 19:57
@github-actions github-actions Bot added the area/tooling Affects the dev or user toolchain (e.g. tests, ci, build tools) label May 25, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@matte1782
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

authzedbot added a commit to authzed/cla that referenced this pull request May 25, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

❌ Patch coverage is 86.27451% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.50%. Comparing base (9a71382) to head (2214eb7).

Files with missing lines Patch % Lines
pkg/query/intersection.go 86.28% 6 Missing and 1 partial ⚠️

❌ Your project check has failed because the head coverage (74.50%) is below the target coverage (75.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3136      +/-   ##
==========================================
- Coverage   75.97%   74.50%   -1.46%     
==========================================
  Files         566      566              
  Lines       64236    64287      +51     
==========================================
- Hits        48797    47891     -906     
- Misses      11770    12782    +1012     
+ Partials     3669     3614      -55     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tooling Affects the dev or user toolchain (e.g. tests, ci, build tools)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LookupSubjects re-admits a subject excluded from a wildcard via intersection (experimental query-plan engine)

2 participants