Skip to content

Team-based resource ownership via team-as-creator-user (plan of action for #158 / alternative to #400) #401

@granludo

Description

@granludo

Context

#158 asks for collaborative ownership of resources (starting with write-shared Knowledge Bases for teacher groups). #400 proposes solving it by adding a team_id ownership dimension to six resource tables and teaching every permission path about teams.

This issue proposes an alternative that solves the same problems with a much smaller blast radius: model a team as a special creator-user rather than as a new ownership dimension. Full rationale and the side-by-side trade-off live in #400; this issue is the concrete plan of action.

Principle

A team is an owner, not a new kind of ownership. It is a Creator_users row scoped to one organization, with a real email, a real organization_id, and a backing OWI user. Because it satisfies every existing invariant — owner-email resolves to a creator-user-with-an-org — the completion pipeline, RAG, org-config resolution, OWI publication and group gating all keep working unchanged. The team can own assistants / KBs / rubrics / libraries, and can share and be shared with, exactly like any user.

Two access modes:

  • Edit team resources → "access as team T", a scoped and audited identity switch. No changes to can_access_*().
  • Use team resources → normal sharing (team-published assistants shared with members; OWI group membership synced on join/leave).

Plan of action

Phase 0 — prerequisites (fix existing gaps)

  • Close Bug: Missing Auth Guards on Protected Routes #260 (missing auth guards on protected routes); the update_assistant_proxy write path must be guarded before we build on it.
  • Wire up the OWI un-share path: _remove_users_from_owi_group() exists in assistant_sharing_service.py but is never called, and _sync_assistant_to_owi_group() only adds users. Removing a share must evict the user from the OWI group. Needed regardless of teams.

Phase 1 — team entity (backend, no UI)

  • teams satellite table (user_id PK → Creator_users.id, name, description, organization_id, timestamps) and team_members (team_id, user_id, role, joined_at).
  • Team creation provisions a Creator_users row (user_type = 'team' or an explicit flag), a synthetic namespaced email, no password login (auth_provider = 'team'), and a backing OWI user — promoted from the current best-effort mirror to fatal/retried, since a team without an OWI user cannot publish.
  • Team CRUD + membership management, scoped to org admins (and team admins for membership ops).

Phase 2 — "access as team" auth

  • POST /creator/teams/{id}/assume: verify the caller's membership server-side, mint a short-TTL scoped JWT with email = team_email and on_behalf_of = <real_user_id>.
  • Thread on_behalf_of into request logging so every as-team action records the real actor.
  • Frontend: a team switcher that stashes the member's own token, swaps in the team token, and shows a persistent "acting as Team T — back to me" control.

Phase 3 — membership → sharing fan-out

  • When a team publishes an assistant, share it with all current members; on member add/remove, add/remove the share (reuses assistant_sharing_service + the Phase 0-fixed OWI sync).
  • Same mechanism for any other resource type we decide should auto-share to members.

Phase 4 — LTI + polish

  • Verify the LTI activity configure flow surfaces team assistants for members (it should already, via the owned-or-shared list) and that student-launch completions resolve org correctly via the team owner.
  • Org-admin "Teams" view: teams, members, resources.

What this explicitly does NOT touch

  • No team_id columns on resource tables.
  • No changes to can_access_*().
  • No changes to the RAG / completion / org-config path.

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions