Skip to content

refactor(BA-6943): authorize scheduling-history scoped searches via RBAC#12974

Draft
jopemachine wants to merge 9 commits into
mainfrom
feat/BA-6943-scoped-search-rbac
Draft

refactor(BA-6943): authorize scheduling-history scoped searches via RBAC#12974
jopemachine wants to merge 9 commits into
mainfrom
feat/BA-6943-scoped-search-rbac

Conversation

@jopemachine

@jopemachine jopemachine commented Jul 20, 2026

Copy link
Copy Markdown
Member

Resolves #12971 (BA-6943)

Summary

  • Routes the session, deployment and route scheduling-history scoped searches through the RBAC scope chain. Each defines a SearchableActionTarget mapping to both an RBAC element (SESSION / MODEL_DEPLOYMENT / ROUTING) and a search scope; the actions extend BaseBulkAction and the processors run through BulkActionProcessor with validators.rbac.bulk.
  • Previously these actions carried a SearchScope built straight from request input and exposed no RBAC element, so validators.rbac never ran — the repository turned the scope into a WHERE clause and existence_checks only confirmed the entity existed, not that the caller could read it. The routes papered over this by requiring super-admin, which made the scoped variants useless to the users who actually own the entities.
  • The three scoped routes now drop to auth_required. With authorization enforced on the action path, a user can read the scheduling history of a session/deployment/route they hold, and gets PermissionDeniedError for one they do not — not a silently empty page. The unscoped admin searches stay superadmin_required.
  • Handlers lose the admin_ prefix, which no longer describes them.

SchedulingHistoryProcessors.__init__ already accepted ActionValidators without using it; that was the wiring point. The repository now takes Sequence[SearchScope] so multiple authorized targets can be matched.

Independent of the BA-6889..BA-6893 kernel stack — branched from main, touches only the three pre-existing entities. search_kernel_scoped_history is deliberately untouched here (converted in #12869); doing it on both branches would conflict.

Test plan

  • pants check clean (5251 source files)
  • pants lint clean over src/ai/backend/:: and tests/unit/manager/::
  • Scheduling-history service tests updated to the target shape and passing — each asserts the forwarded scopes and element_refs()
  • Scheduling-history repository tests passing
  • Confirmed BulkActionRBACValidator short-circuits for super admins, so the unscoped admin paths are unaffected
  • Verified against a live manager: a non-admin reading their own session's history succeeds, and another user's is denied

🤖 Generated with Claude Code


📚 Documentation preview 📚: https://sorna--12974.org.readthedocs.build/en/12974/


📚 Documentation preview 📚: https://sorna-ko--12974.org.readthedocs.build/ko/12974/

@github-actions github-actions Bot added the size:L 100~500 LoC label Jul 20, 2026
@github-actions github-actions Bot added the comp:manager Related to Manager component label Jul 20, 2026
@jopemachine
jopemachine force-pushed the feat/BA-6943-scoped-search-rbac branch from 36bc484 to 300fe27 Compare July 20, 2026 07:17
The session, deployment and route scoped searches carried a SearchScope
built straight from request input and exposed no RBAC element, so
validators.rbac never ran: the repository turned the scope into a WHERE
clause and existence_checks only confirmed the entity existed, not that
the caller could read it. The routes papered over this by requiring
super-admin, which made the scoped variants useless to the users who
own the entities.

Each scoped search now defines a SearchableActionTarget that maps to
both an RBAC element and a search scope, the actions extend
BaseBulkAction, and the processors run through BulkActionProcessor with
validators.rbac.bulk -- the ActionValidators argument the package
already accepted but never used. The repository takes a sequence of
scopes so multiple authorized targets can be matched. A caller asking
for a scope they do not hold gets PermissionDeniedError rather than an
empty page.

With authorization enforced on the action path, the three scoped routes
drop to auth_required; the unscoped admin searches stay
superadmin_required. Handlers lose the admin_ prefix, which no longer
describes them.

Kernel is converted separately in BA-6891.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-6943-scoped-search-rbac branch from 300fe27 to 18d537a Compare July 20, 2026 07:22
Co-authored-by: octodog <mu001@lablup.com>
@github-actions github-actions Bot added the area:docs Documentations label Jul 20, 2026
jopemachine and others added 6 commits July 20, 2026 16:32
…outes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: octodog <mu001@lablup.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Convert the session, deployment and route scoped searches to
BaseScopeAction, matching the kernel conversion in BA-6891 and the
other scoped searches in the codebase: the history is the entity being
read and the owning entity is the scope containing it. Each action
exposes target_element(), and the processors run through
ScopeActionProcessor with validators.rbac.scope -- the ActionValidators
argument the package already accepted but never used.

Add the three history element types to RBACElementType and its public
DTO (kept in sync by test_rbac_element_type_sync), ScopeType.ROUTING so
the route scope round-trips, and a migration mirroring every existing
READ grant on a session / model_deployment / routing onto its history
entity, following add_admin_page_read_permissions.

With authorization enforced on the action path, the three scoped routes
drop to auth_required. The unscoped admin searches are untouched and
stay superadmin_required.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added comp:common Related to Common component require:db-migration Automatically set when alembic migrations are added or updated labels Jul 20, 2026
Co-authored-by: octodog <mu001@lablup.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:docs Documentations comp:common Related to Common component comp:manager Related to Manager component require:db-migration Automatically set when alembic migrations are added or updated size:L 100~500 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce RBAC on the remaining scoped searches via SearchableActionTarget

1 participant