Skip to content

feat(BA-5840): add effective-permissions DataLoader for batched RBAC resolution#11499

Draft
fregataa wants to merge 2 commits intomainfrom
feat/BA-5840-effective-permissions-dataloader
Draft

feat(BA-5840): add effective-permissions DataLoader for batched RBAC resolution#11499
fregataa wants to merge 2 commits intomainfrom
feat/BA-5840-effective-permissions-dataloader

Conversation

@fregataa
Copy link
Copy Markdown
Member

@fregataa fregataa commented May 7, 2026

Summary

  • Register resolve_effective_permissions ActionProcessor on PermissionControllerProcessors (the action and service method already existed but were not wired through a processor).
  • Add RBACAdapter.batch_resolve_effective_permissions as a thin wrapper over the processor.
  • Add DataLoaders.effective_permissions_loader keyed by PermissionResolutionKey; keys with no grant map to an empty frozenset[OperationType]. Repository-level grouping by (user_id, element_type, subject_entity_type) already collapses to one SQL round-trip per group, so a single page of same-typed nodes resolves in one query.

This enables BA-5841 (shared per-node permissions GraphQL field) to resolve per-row permissions in list views without N+1 round-trips.

Test plan

  • CI runs pants check / pants test on impacted targets.
  • Smoke-test the loader against a real DB once BA-5841 wires it into a node type (e.g. vfolder_node).

Resolves BA-5840

…resolution

Adds a request-scoped DataLoader keyed by PermissionResolutionKey so GraphQL
list queries can resolve per-row permission fields without N+1 round-trips.

- Register resolve_effective_permissions ActionProcessor on the permission
  controller package (action and service method already existed).
- Add RBACAdapter.batch_resolve_effective_permissions wrapping the processor.
- Add DataLoaders.effective_permissions_loader; missing keys map to an empty
  frozenset so callers do not have to handle None.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 7, 2026 04:08
@github-actions github-actions Bot added size:M 30~100 LoC comp:manager Related to Manager component labels May 7, 2026
@fregataa fregataa marked this pull request as draft May 7, 2026 04:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Wires up an existing effective-permissions resolution action through the permission controller, exposes it via the RBAC adapter, and adds a request-scoped GraphQL DataLoader to batch permission resolution for list views (avoiding N+1).

Changes:

  • Register resolve_effective_permissions on PermissionControllerProcessors.
  • Add RBACAdapter.batch_resolve_effective_permissions() wrapper around the processor action.
  • Introduce effective_permissions_loader GraphQL DataLoader keyed by PermissionResolutionKey.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/ai/backend/manager/services/permission_contoller/processors.py Registers the effective-permissions action processor so it can be invoked via the controller.
src/ai/backend/manager/api/gql/data_loader/data_loaders.py Adds a request-scoped DataLoader to batch and cache effective permission resolution.
src/ai/backend/manager/api/adapters/rbac/adapter.py Exposes a batched adapter method that forwards to the permission controller action.
changes/11499.feature.md Adds changelog entry for the new GraphQL DataLoader capability.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

action_result = await self._processors.permission_controller.resolve_effective_permissions.wait_for_complete(
ResolveEffectivePermissionsAction(keys=list(keys))
)
return action_result.permissions
Comment on lines +647 to +652
) -> Mapping[PermissionResolutionKey, frozenset[InternalOperationType]]:
"""Resolve granted operations for each input key; missing keys map to an empty frozenset."""
action_result = await self._processors.permission_controller.resolve_effective_permissions.wait_for_complete(
ResolveEffectivePermissionsAction(keys=list(keys))
)
return action_result.permissions
Comment on lines +695 to +699
async def load_fn(
keys: list[PermissionResolutionKey],
) -> list[frozenset[OperationType]]:
result = await adapter.batch_resolve_effective_permissions(keys)
return [result.get(key, frozenset()) for key in keys]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:manager Related to Manager component size:M 30~100 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants