andrewmusselman opened a new issue, #20:
URL: https://github.com/apache/tooling-gofannon/issues/20

   ### Summary
   List endpoints for agents, demos, and deployments return all records in the 
database without filtering by user or workspace. Phase B-1 (the workspace 
membership model) is implemented; Phase B-3 (filtering resources by workspace) 
is not. The codebase explicitly calls this out in `models/workspace.py`: 
workspace filtering on those resources is introduced in B-3; B-1 only 
establishes the membership model.
    
   ### Details
   **Symptom:**
   - Site admins observe each other's agents, demos, and deployments — 
initially appeared to be admin-specific leakage but applies to all 
authenticated users.
   - A second user cannot see another user's run progress logs (a different gap 
— see ISSUE-003).
   - No "publish" / "share" concept gates this visibility today.
   **Root cause:**
   1. `routes.py:list_agents` (line 504) issues `db.list_all("agents")` with 
zero filtering.
   2. `routes.py:list_demo_apps` (line 942) and 
`routes.py:list_deployments_route` (line 652) do the same.
   3. The Agent model has no `user_id`, `workspace_id`, `created_by`, 
`published`, or `visibility` field — nothing to filter on even if filtering 
were added.
   4. `routes.py:get_agent` (line 517) looks up any agent by id with no 
membership check; same for PUT/DELETE.
   5. `routes.py:list_data_store_namespaces` (line 1023) does filter by 
`userId`, demonstrating the partial-scoping inconsistency.
   Site admin status (`session.is_site_admin`) is not the issue — list 
endpoints don't check that flag at all, so admins and non-admins hit the same 
unfiltered query.
    
   **Impact:**
   - Hosted multi-tenant launch is unsafe with this state.
   - No isolation between users sharing a deployment.
   - Agent IDs are guessable (UUIDs in URLs), and any authenticated user can 
read/write/delete any agent.
   ### Remediation
   1. **Schema.** Add `workspace_id` and `created_by` to Agent, Demo, 
DeployedApi models. Backfill existing rows into a `legacy:pre-b3` workspace; 
operators migrate them manually.
   2. **Writes carry workspace.** Create endpoints take the active workspace 
from the request (header or query param) and validate the session has 
membership.
   3. **Reads filter by workspace.** Every list endpoint becomes 
`db.find("agents", {"workspace_id": {"$in": session_workspace_ids}})`. Single 
helper to enforce the pattern.
   4. **Authorize by-id endpoints.** `get/update/delete` for each resource must 
check the resource's workspace_id is one the session is a member of. 
`require_workspace_member(resource, session, role)` helper.
   5. **Site admin escape hatch (deliberate, opt-in).** `?include_all=true` 
query parameter on list endpoints, or a separate `/admin/*` route — never 
silent.
   6. **Frontend.** Workspace switcher, "this agent belongs to <workspace>" 
badge, share-into-workspace affordance.
   ### Acceptance Criteria
   - [ ] Fixed: `Agent`, `Demo`, `DeployedApi` models include `workspace_id` 
and `created_by` fields
   - [ ] Fixed: existing DB rows backfilled to `legacy:pre-b3` workspace
   - [ ] Fixed: all list endpoints filter by `workspace_id IN 
(session.workspace_ids)`
   - [ ] Fixed: get/update/delete endpoints check workspace membership
   - [ ] Fixed: site-admin global view requires explicit `?include_all=true`
   - [ ] Fixed: data-store namespace filtering converted from per-user to 
per-workspace
   - [ ] Test added: User A cannot list, read, update, or delete agents owned 
by User B
   - [ ] Test added: Site admin without `include_all` flag sees only their 
workspaces
   - [ ] Test added: Workspace member can access shared workspace resources
   - [ ] Frontend: workspace selection UI exists in agent/demo creation flows
   - [ ] Documentation: migration guide for existing deployments
   ### References
   - File: `webapp/packages/api/user-service/routes.py:504,517,652,942,1023`
   - File: `webapp/packages/api/user-service/models/agent.py`
   - File: `webapp/packages/api/user-service/models/workspace.py` (existing 
membership model — see docstring)
   - Tracker: FIXES.md item #1
   ### Priority
   **Critical** - Pre-launch blocker for hosted multi-tenant deployment. 
Membership model already exists; only the filtering and authorization layers 
are missing. Substantial design work but no architectural unknowns.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to