REST GET /folders silently ignores group_id (scope not applied in VFolderService.list)
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 368
Description
## Summary
The REST endpoint `GET /folders` (vfolder list) accepts a `group_id` query
parameter but **silently ignores it** — the returned set is identical with or
without `group_id`. Verified on **26.4.4**.
## Details
`api/rest/vfolder/handler.py::list_folders` resolves `group_id` into a scope:
```python
group_id = params.group_id
if group_id is not None:
scope_type = ScopeType.PROJECT
scope_id = str(group_id)
else:
scope_type = ScopeType.USER
scope_id = str(owner_user_uuid)
result = await self._vfolder.list_vfolder.wait_for_complete(
ListVFolderAction(user_uuid=owner_user_uuid, _scope_type=scope_type, _scope_id=scope_id)
)
```
…but `services/vfolder/services/vfolder.py::VFolderService.list` never uses the
scope. It calls `list_accessible_vfolders(user_id, user_role, domain_name,
allowed_vfolder_types)` with **no** scope filter, and the action's
`_scope_type`/`_scope_id` are only echoed back into the result:
```python
return ListVFolderActionResult(
user_uuid=action.user_uuid,
vfolders=vfolders,
_scope_type=action.scope_type(), # echoed, never used to filter
_scope_id=action.scope_id(),
)
```
So the result is always the wide `query_accessible_vfolders` union (user-owned +
invited + every MODEL_STORE project in the domain + all-domain groups for admins
+ all group vfolders for superadmins), regardless of `group_id`.
## Reproduction (26.4.4)
Signed `GET /folders` as both a superadmin and a `role: user` account:
```
/folders == /folders?group_id= == /folders?group_id=
```
…return identical result sets every time.
## Impact
Clients cannot scope the REST vfolder list to a single project. This looks like
an incomplete RBAC refactor: the handler wires the scope but the service still
calls the legacy union. Downstream UIs that use this endpoint surface every
MODEL_STORE / cross-project group folder. (The `vfolder_nodes` GraphQL
connection with `scope_id: "project:"` *does* scope correctly, and the WebUI
relies on it — but the REST `group_id` param remains misleading.)
## Suggested fix
Either honor the scope in `VFolderService.list` (filter group vfolders by the
PROJECT scope when `_scope_type == PROJECT`, restrict to the user when USER), or
remove the dead `group_id` param and document `vfolder_nodes` as the scoped path.
Found while debugging a downstream client (Backend.AI FastTrack) that showed
many empty, duplicate-named project folders on its data-folder page.
Contributor guide
Research direction
Start with api/rest/vfolder/handler.py::list_folders and services/vfolder/services/vfolder.py::VFolderService.list, then trace list_accessible_vfolders and compare the scoped vfolder_nodes GraphQL path. Confirm with maintainers whether REST should honor group_id or remove it; done means the endpoint no longer silently returns the unscoped union and its documented behavior matches the implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, authorization, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100