Summary
Extend assistant sharing to support permission levels so that assistant creators can grant edit access to specific people. This enables collaborative assistant building by teams, not just individuals.
Motivation
Currently, sharing an assistant only grants read/chat access. If a team wants to co-manage an assistant — updating instructions, uploading documents, tweaking settings — only the original creator can do it. This is a bottleneck for departments, research groups, and course teams that want to build and maintain assistants together.
Current Sharing Model
Share records in DynamoDB are flat with no permission level:
PK: AST#{assistantId}
SK: SHARE#{email}
GSI3_PK: SHARE#{email}
GSI3_SK: AST#{assistantId}
assistantId, email, createdAt, firstInteracted
- All write operations (
update_assistant, delete_assistant, share_assistant, unshare_assistant) require owner_id match
get_assistant_with_access_check grants shared users read access only
- Share/unshare endpoints only allow the owner to manage shares
Proposed Changes
Permission Levels
| Permission |
Can Chat |
Can View Config |
Can Edit |
Can Manage Shares |
Can Delete |
viewer (default) |
✅ |
❌ |
❌ |
❌ |
❌ |
editor |
✅ |
✅ |
✅ |
❌ |
❌ |
owner (implicit) |
✅ |
✅ |
✅ |
✅ |
✅ |
Editor can:
- View and update assistant settings (name, description, instructions, tags, starters, emoji, visibility, image, strictness, citation toggles)
- Upload, delete, and manage knowledge base documents
- Use the test chat
- View the share list (read-only — cannot add/remove shares)
Editor cannot:
- Delete the assistant
- Add or remove shared users
- Transfer ownership
Data Model Changes
DynamoDB Share Record
Add a permission attribute to share records:
PK: AST#{assistantId}
SK: SHARE#{email}
GSI3_PK: SHARE#{email}
GSI3_SK: AST#{assistantId}
assistantId, email, createdAt, firstInteracted
permission: "viewer" | "editor" ← NEW (default: "viewer")
Existing share records without a permission attribute are treated as viewer (backward compatible).
Backend Models
ShareAssistantRequest — add optional permission field:
class ShareAssistantRequest(BaseModel):
emails: List[str] = Field(..., min_length=1)
permission: Literal["viewer", "editor"] = Field("viewer", description="Permission level for shared users")
AssistantSharesResponse — return permission per user:
class ShareEntry(BaseModel):
email: str
permission: Literal["viewer", "editor"] = "viewer"
class AssistantSharesResponse(BaseModel):
assistant_id: str = Field(..., alias="assistantId")
shared_with: List[ShareEntry] = Field(..., alias="sharedWith")
AssistantResponse — add the requesting user's permission level:
class AssistantResponse(BaseModel):
# ... existing fields ...
user_permission: Optional[Literal["owner", "editor", "viewer"]] = Field(
None, alias="userPermission",
description="Requesting user's permission level on this assistant"
)
Backend Changes
Access Check Updates (service.py)
get_assistant_with_access_check — return the permission level alongside the assistant so callers know what the user can do. Currently returns Optional[Assistant]; extend to also populate user_permission on the response.
check_share_access — currently returns bool. Change to return the permission level (or None if no share):
async def check_share_access(assistant_id: str, user_email: str) -> Optional[str]:
# Returns "viewer", "editor", or None
Write Endpoint Authorization
update_assistant (routes.py) — currently checks owner_id match. Extend to also allow users with editor permission:
# Current: only owner can update
updated_assistant = await update_assistant(assistant_id=assistant_id, owner_id=user_id, ...)
# New: owner OR editor can update
assistant = await get_assistant_by_id(assistant_id) # no owner check
permission = resolve_permission(assistant, user_id, user_email)
if permission not in ("owner", "editor"):
raise HTTPException(403, "Edit access required")
Apply the same pattern to:
PUT /assistants/{id} — allow editor
POST /assistants/{id}/test-chat — allow editor
- Document upload/delete endpoints for the assistant — allow editor
DELETE /assistants/{id} — owner only (no change)
POST/DELETE /assistants/{id}/shares — owner only (no change)
GET /assistants/{id}/shares — owner and editor (read-only for editor)
Share Management
share_assistant — write the permission field to the share record:
table.put_item(Item={
"PK": f"AST#{assistant_id}",
"SK": f"SHARE#{email}",
# ... existing fields ...
"permission": permission, # "viewer" or "editor"
})
New: Update share permission — allow the owner to change an existing share's permission level without removing and re-adding:
PATCH /assistants/{assistant_id}/shares
Body: { "email": "user@example.com", "permission": "editor" }
Frontend Changes
Share Dialog
- When sharing, add a permission dropdown/toggle next to each email: Can view | Can edit
- Default: "Can view"
- In the share list, show the current permission level per user with the ability to change it
- Owner can upgrade viewer → editor or downgrade editor → viewer inline
Assistant Edit Page
- Editors see the full edit form (same as owner)
- Hide the "Delete Assistant" button for editors
- Hide the share management section for editors, or show it read-only
- Show a subtle indicator that the user is editing as a collaborator, not the owner (e.g., "Shared by {ownerName}" badge)
Assistant List
- Shared assistants with edit permission could show a small "Editor" badge to distinguish from view-only shares
Migration
- Existing share records have no
permission attribute
- Backend treats missing
permission as "viewer" — fully backward compatible, no data migration needed
- All existing behavior is preserved; this is purely additive
Out of Scope
- Ownership transfer
- Group/team-based sharing (share with a role or department)
- Granular per-field edit permissions
- Edit history / audit log of who changed what
- Real-time collaborative editing (conflict resolution)
Summary
Extend assistant sharing to support permission levels so that assistant creators can grant edit access to specific people. This enables collaborative assistant building by teams, not just individuals.
Motivation
Currently, sharing an assistant only grants read/chat access. If a team wants to co-manage an assistant — updating instructions, uploading documents, tweaking settings — only the original creator can do it. This is a bottleneck for departments, research groups, and course teams that want to build and maintain assistants together.
Current Sharing Model
Share records in DynamoDB are flat with no permission level:
update_assistant,delete_assistant,share_assistant,unshare_assistant) requireowner_idmatchget_assistant_with_access_checkgrants shared users read access onlyProposed Changes
Permission Levels
viewer(default)editorowner(implicit)Editor can:
Editor cannot:
Data Model Changes
DynamoDB Share Record
Add a
permissionattribute to share records:Existing share records without a
permissionattribute are treated asviewer(backward compatible).Backend Models
ShareAssistantRequest— add optional permission field:AssistantSharesResponse— return permission per user:AssistantResponse— add the requesting user's permission level:Backend Changes
Access Check Updates (
service.py)get_assistant_with_access_check— return the permission level alongside the assistant so callers know what the user can do. Currently returnsOptional[Assistant]; extend to also populateuser_permissionon the response.check_share_access— currently returnsbool. Change to return the permission level (orNoneif no share):Write Endpoint Authorization
update_assistant(routes.py) — currently checksowner_idmatch. Extend to also allow users witheditorpermission:Apply the same pattern to:
PUT /assistants/{id}— allow editorPOST /assistants/{id}/test-chat— allow editorDELETE /assistants/{id}— owner only (no change)POST/DELETE /assistants/{id}/shares— owner only (no change)GET /assistants/{id}/shares— owner and editor (read-only for editor)Share Management
share_assistant— write thepermissionfield to the share record:New: Update share permission — allow the owner to change an existing share's permission level without removing and re-adding:
Frontend Changes
Share Dialog
Assistant Edit Page
Assistant List
Migration
permissionattributepermissionas"viewer"— fully backward compatible, no data migration neededOut of Scope