# Permissions and data isolation # ******************************** REST and WebSocket authorization policy for Agency (``todo/04-api-permissions.md``). Scope model =========== .. list-table:: :header-rows: 1 :widths: 28 36 36 * - Resource - Scope - Notes * - Execution, Interruption - **User** - List/retrieve/update only rows where ``user`` matches the signed-in operator. Staff (``is_staff``) sees all. Cross-user access returns **404**. * - Agent, Mission, Tool, Model, Provider - **Shared catalog** - All authenticated operators share one catalog (single-workspace dev default). Tenant/workspace isolation is future work. * - Document, Workspace - **Tenant / workspace** (Phase 3 shipped) - Corpus models use ``Tenant`` → ``Workspace``; API filters by ``TenantMembership``. * - Display, DisplayView - **Authenticated** (+ kiosk token for runtime) - Operator CRUD requires login; kiosk snapshot uses display credential. REST (Phase 1 shipped) ====================== Implementation: ``agency.api.permissions.filter_by_owner`` used by: * ``ExecutionViewSet`` — ``IsAuthenticated``; queryset filtered by ``user``. * ``InterruptionViewSet`` — ``IsAuthenticated``; queryset filtered by ``user``. * ``POST /api/execution//message/`` — inherits queryset filter (404 if not owner). Dispatch and special actions ---------------------------- * ``POST /api/mission//dispatch/`` — authenticated; execution owned by ``request.user``. * ``PATCH /api/interruption//`` — authenticated; queryset filter + WS answer checks ``interruption.user``. * Provider sync, agent test — authenticated (catalog ops). WebSocket (Phase 2 shipped) --------------------------- * **UserConsumer** — joins ``user-{id}`` only when authenticated; interruption answers check owner. * **ThreadConsumer** — authenticated; ``thread-{id}`` requires thread owner (or staff); global ``threads`` group staff-only. * **TaskConsumer** — admin-style task monitor; review for production. Corpus (Phase 3 shipped) ------------------------ * ``TenantMembership`` — links operator to tenant. * ``WorkspaceViewSet`` / ``DocumentViewSet`` — ``IsAuthenticated``; queryset filtered by membership. * ``document_reindex``, ``document_extraction``, ``workspace_search``, ``workspace_ask`` — 404 cross-tenant. * ``UserPreferences.for_user`` — ensures default-tenant membership on first prefs access. Verification ------------ .. code-block:: bash cd agency-django && pytest tests/test_api_permissions.py tests/test_thread_consumer_permissions.py tests/test_api_corpus_permissions.py -q Related backlog: ``agency-workspace/todo/04-api-permissions.md``.