Commit Graph
13 Commits
Author SHA1 Message Date
Classic298 d67bc4ffcd perf: batch the file access check queries (#27383)
has_access_to_file runs for every non-owner file GET, per RAG file check and per shared-chat or model-attached file. Its final step called Models.get_models_by_user_id, which issued one grant query per non-owned workspace model, so a single file check on an instance with M workspace models cost M grant queries plus a group query, with the deny path always paying full price. Its collection_name step listed every knowledge base the user can access (itself one grant query per knowledge base) just to scan the list for one id. And get_accessible_folder_files repeated the whole pipeline per folder entry, refetching the caller's group memberships every time.

Three changes, all using parameters and helpers that already exist:
- Models.get_models_by_user_id resolves grants for all non-owned models in one get_accessible_resource_ids call and accepts prefetched user_group_ids.
- The collection_name check fetches the one referenced knowledge base and performs a single owner-or-grant check with the already-resolved group ids, preserving the write-requires-owner guard exactly (including its short-circuit before any grant query).
- get_accessible_folder_files resolves group ids once and threads them through every per-entry check.

Benchmark:

| metric | before | after |
| --- | --- | --- |
| filter loop CPU, 300 workspace models (queries stubbed) | 47 us | 19 us |
| grant queries per file-access check, M workspace models | M | 1 |
| group membership queries per folder listing, F files | F | 1 |

The stubbed CPU row understates the win: each removed query in the other two rows was a real database round trip.

Functionally verified with stubbed accessors: owned plus granted models are returned with owned ids excluded from the batch query; model-attached file access resolves through the batched path; the collection_name path does one KB fetch and one grant check with no full listing; a missing KB falls through; write access via a KB still requires the KB owner to own the file and short-circuits before the grant query; folder listings fetch groups exactly once.
2026-07-23 17:50:08 -05:00
17df026492 Confer object-derived file write only for files the object owner owns (#26032)
has_access_to_file() derives file access from the objects a file is attached to
(knowledge bases, workspace models). Those branches returned True for any access_type
whenever the user held that permission on the object, write/delete included. Since a
user can create their own KB or model and attach any file they can merely READ (KB
attach and the model meta.knowledge validator both gate on read access only), a user
with read access to a victim file could launder it into write/delete: attach it to an
object they own, then rename, overwrite or delete it via the write-gated file routes
(POST /files/{id}/rename, /data/content/update, DELETE /files/{id}). This is the
residual of GHSA-vjqm-6gcc-62cr (CVE-2026-54012) left open by the read-only attach
validator (CWE-863).

An object now confers write/delete on a file only when the object's owner owns that
file, so delegation originates from the file's own owner. Read is unchanged (RAG and
shared-object reads still work), and legitimate delegation is preserved: a write grant
on an object whose owner owns the attached file still confers write. Applied to all
three object branches: knowledge base, file home collection, and workspace model.

Co-authored-by: rexpository <30176934+rexpository@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 03:05:57 +02:00
d169f086da fix: respect access_type in shared-chat file authorization branch (#24755)
has_access_to_file granted access whenever the file was attached to a
shared chat the user could read, ignoring the requested access_type. A
read-only shared-chat recipient therefore satisfied write and delete
checks and could delete or mutate the chat owner's attached file. Gate
the shared-chat branch on read access, matching the channels branch
directly above it.

Co-authored-by: oxsignal <oxsignal@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 22:09:56 +04:00
Timothy Jaeryang Baek 6d0295588e refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
Timothy Jaeryang Baek 2dbf7b6764 refac 2026-05-11 02:12:38 +09:00
Timothy Jaeryang Baek 2e52ad8ff2 refac: shared chat 2026-04-17 10:16:32 +09:00
Timothy Jaeryang Baek 27169124f2 refac: async db 2026-04-12 14:22:11 -05:00
Timothy Jaeryang Baek de3317e26b refac 2026-03-17 17:58:01 -05:00
Shamil 3a6b5ebb5f refac: modernize type hints and imports in access_control module (#22594) 2026-03-11 15:28:39 -05:00
Timothy Jaeryang Baek 10daa64d5b chore: format 2026-03-02 17:26:18 -06:00
Classic298 65fbbf5e35 fix: grant file access for knowledge attached to shared workspace models (#22151) 2026-03-02 18:08:49 -05:00
Timothy Jaeryang Baek 93bab8d822 refac 2026-03-01 13:54:44 -06:00
Timothy Jaeryang Baek 259d5ca596 refac 2026-03-01 13:49:36 -06:00