Tracking IDs are review bookkeeping that rots in shipped source; the rationale they tagged is kept. Comment-only change (CommentChecker 458 -> 16 false positives).
GatewayBrowseScopeProvider resolved `identityAccessor.Current?.EffectiveConstraints
?? ApiKeyConstraints.Empty`, so an absent ambient identity produced an empty
BrowseSubtrees list — which the shared GalaxyRepository library reads as "no
scoping". The control's fail state was therefore open: any future path reaching the
library's galaxy service without GatewayGrpcAuthorizationInterceptor having pushed
the identity would silently hand a browse-scoped key the full hierarchy, with
nothing failing and nothing logged. A constraint-narrowing control's absence is
invisible in normal operation, which is what made the honest "safe only because the
global interceptor runs first" comment insufficient on its own.
The provider now distinguishes the two states the old expression collapsed:
- authenticated key with no BrowseSubtrees constraint -> empty list, unscoped
(unchanged, and now asserted in its own test rather than implied);
- no ambient identity with Authentication:Mode=ApiKey -> log a warning naming the
broken ordering invariant and throw RpcException(PermissionDenied);
- no ambient identity with Authentication:Mode=Disabled -> unscoped, because
nothing authenticates there so no key and no constraints exist to scope by.
The registration-order comment at GatewayApplication.cs now says the ordering is
still required but no longer silently trusted.
Tests: GatewayBrowseScopeProviderTests gains the PermissionDenied case and the
Disabled-mode case alongside the unconstrained-identity one.
GalaxyRepositoryHostWiringTests phase 1 now pushes an identity carrying no
BrowseSubtrees instead of pushing none — that, not an absent identity, is
production's unscoped case.
Docs: docs/Authorization.md's constraint section states the two-state distinction
and both fail behaviours under browse_subtrees.
Add GalaxyRepositoryHostWiringTests.BrowseChildren_BrowseSubtreesConstraintThroughHostWiring_FiltersChildren:
constructs the real GatewayRequestIdentityAccessor + GatewayBrowseScopeProvider, passes the
provider as IGalaxyBrowseScopeProvider to the lib GalaxyRepositoryGrpcService, and asserts
two children (unconstrained) then empty (BrowseSubtrees=["NonExistent"]) — proving the full
production authz-filtering chain is correctly wired.
Strengthen DashboardSnapshotServiceTests.GetSnapshot_ProjectsGalaxySummaryFromHierarchyCache:
add Assert.Equal(2, TopTemplates.Count) and Assert.Contains($Area, InstanceCount==1) so the
test guards the complete summary output, not just the $Pump entry.