fix(agent): revise agent permission model for visibility and mentions

- ListAgents: private agents are now visible to all workspace members
  (previously hidden from non-owner members)
- Mentions: private agents can only be @mentioned by the agent owner or
  workspace admin/owner; regular members' mentions of private agents are
  silently ignored
- Settings (update/delete/skills) and assign were already correctly
  restricted in previous PRs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-04-02 12:45:31 +08:00
parent f05f3face3
commit 68da1efd74
2 changed files with 24 additions and 16 deletions

View file

@ -142,8 +142,7 @@ func taskToResponse(t db.AgentTaskQueue) AgentTaskResponse {
func (h *Handler) ListAgents(w http.ResponseWriter, r *http.Request) {
workspaceID := resolveWorkspaceID(r)
member, ok := h.workspaceMember(w, r, workspaceID)
if !ok {
if _, ok := h.workspaceMember(w, r, workspaceID); !ok {
return
}
@ -153,9 +152,6 @@ func (h *Handler) ListAgents(w http.ResponseWriter, r *http.Request) {
return
}
userID := requestUserID(r)
isAdmin := roleAllowed(member.Role, "owner", "admin")
// Batch-load skills for all agents to avoid N+1.
skillRows, err := h.Queries.ListAgentSkillsByWorkspace(r.Context(), parseUUID(workspaceID))
if err != nil {
@ -172,21 +168,15 @@ func (h *Handler) ListAgents(w http.ResponseWriter, r *http.Request) {
})
}
// Filter private agents: only visible to owner_id or workspace admin
var visible []AgentResponse
// All agents (including private) are visible to workspace members.
visible := make([]AgentResponse, 0, len(agents))
for _, a := range agents {
if a.Visibility == "private" && !isAdmin && uuidToString(a.OwnerID) != userID {
continue
}
resp := agentToResponse(a)
if skills, ok := skillMap[resp.ID]; ok {
resp.Skills = skills
}
visible = append(visible, resp)
}
if visible == nil {
visible = []AgentResponse{}
}
writeJSON(w, http.StatusOK, visible)
}