This document provides a comprehensive overview of the Row Level Security (RLS) policies in the AIaW Supabase database. RLS is used to control which records users can access, ensuring proper data isolation and security.
- Entities and Tables
- Core Security Functions
- Permission Model
- RLS Policies by Table
- Data Relationships
- Triggers and Automation
- Security Considerations
- Recent Schema Changes
- profiles: User profiles with basic information
- user_data: Key-value storage for user preferences and settings
- user_plugins: Plugins installed by users
- user_assistants: AI assistants configured by users, with sharing capabilities
- custom_providers: Custom LLM providers configured by users
- subproviders: Provider configurations for custom providers
- user_workspaces: Direct mapping between users and their accessible workspaces
- dialogs: Conversations between users and assistants
- dialog_messages: Individual messages in dialogs
- message_contents: Content of messages (text/tools)
- stored_items: Files, images, and quotes stored from conversations
- artifacts: Files and code created or modified during conversations
- chats: Chat channels (workspace, private)
- chat_members: Users who are members of chats
- messages: Messages sent in chats
- workspaces: Containers for collaboration
- workspace_members: Users who are members of workspaces with roles
- user_workspaces: Denormalized table for quick user-to-workspace access lookups
auth.uid(): Supabase function that returns the ID of the authenticated user
get_workspace_role(workspace_id, user_id): Gets the role of a user in a workspaceis_workspace_admin_or_owner(workspace_id_param): Checks if user is admin or owner of workspaceis_workspace_member(workspace_id_param): Checks if user is a member of workspace (any role)is_workspace_owner(user_id): Checks if user owns any workspacessync_user_workspaces(): Trigger function to keep user_workspaces in sync with workspace_members
is_chat_member(chat_id_param): Checks if user is a member of chatis_chat_owner(chat_id_param): Checks if user is the owner of a chatcan_manage_chat(chat_id_param): Checks if user can manage a chat (owner or workspace admin)start_private_chat_with(target_user_id, current_user_id): Creates a private chat between two users
can_manage_assistant(assistant_id_param): Checks if user can manage an assistant (owner or workspace admin for shared assistants)
add_workspace_owner_as_member(): Trigger function to add workspace owner as admin membercreate_profile_on_signup(): Trigger function to create profile when user signs updebug_workspaces(): Utility function to help debug workspaces
- owner: Full control (creator of workspace)
- admin: Administrative access
- member: Standard access
- guest: Read-only access
- workspace: Chats associated with a workspace, accessible to workspace members
- private: Direct message chats between users
- Public workspaces:
- Visible to anyone
- Anyone can join as a member
- Content readable by anyone
- Private workspaces:
- Only visible to members
- Must be invited by admin or owner
- Content only accessible to members
Any user can create a workspace: Any authenticated user can create workspacesPublic workspace can be read by anyone: Public workspaces are visible to allPrivate workspace can only be read by members: Private workspaces only visible to membersAdmin or owner can update workspace: Only admin or owner can update workspaceOwner can delete workspace: Only owner can delete workspace
- SELECT policy: Can read member lists if admin/member OR workspace is public
- Admins and owners can always view workspace members
- Current workspace members can view other members
- Anyone can view members of public workspaces
- INSERT policy: Can join if admin OR self-joining public workspace
- Admins and owners can add anyone to the workspace
- Users can add themselves to public workspaces as members
- UPDATE policy: Only admin/owner can change roles
- Only workspace admins and owners can modify member roles
- DELETE policy: Admin/owner can remove anyone, users can leave
- Admins and owners can remove any member
- Users can remove themselves (leave the workspace)
Workspace members can create workspace chats: Only workspace members (admin/member) can create workspace chatsAdmin can CRUD any workspace chat: Workspace admins have full control of workspace chatsChat owner or workspace admin can delete chat: Owner or admin can delete chatsAnyone can read public workspace chats: Public workspace chats are readable by anyoneMembers can read private workspace chats: Private workspace chats only visible to workspace membersAnyone can create private chats: Any user can create private chatsChat members can update private chats: Only members can update private chatsChat members can read private chats: Only members can read private chatsChat owner can delete private chats: Only owner can delete private chats
Anyone can join public chats: Users can join public chats without invitationChat owner can manage members: Chat owner or workspace admin can manage chat members
Messages inherit chat permissions: Message access follows parent chat permissionsAdmin can CRUD any workspace message: Admins have full control of messages in workspace chatsChat members can create messages: Only chat members can create messagesMessage sender can update own messages: Users can edit their own messagesMessage sender or chat manager can delete messages: Sender, chat owner, or admin can delete messages
Anyone can read profiles: Profiles are publicly readableUsers can update their own profile: Users can only update their own profile
User can read own stored reactives: Users can read their own dataUser can insert own stored reactives: Users can create their own dataUser can update own stored reactives: Users can update their own dataUser can delete own stored reactives: Users can delete their own data
- Various owner-based policies for CRUD operations
- Access limited to dialog creator
User can insert own artifact: Users can create artifactsUser can update own artifact: Users can update their artifactsUser can delete own artifact: Users can delete their artifacts
Users can view their own assistants: Users can view assistants they createdUsers can view global shared assistants: Anyone can view globally shared assistantsWorkspace members can view workspace shared assistants: Workspace members can view assistants shared to their workspaceWorkspace admins can manage workspace shared assistants: Workspace admins can edit assistants shared to their workspaceUsers can update their assistants: Users can update their own assistantsUsers can delete their assistants: Users can delete their own assistants
- Standard owner-based policies limiting access to creator
- Workspaces can have parent-child relationships
- Assistants can have parent-child relationships through parent_id
- Chats can belong to workspaces
- Dialog messages belong to dialogs
- Message contents belong to dialog messages
- Chat members link users to chats
- Workspace members link users to workspaces
- User workspaces provide a denormalized view of user-to-workspace relationships
The database uses ON DELETE CASCADE extensively to maintain referential integrity:
- When a workspace is deleted, all its chats, members, dialogs, etc. are deleted
- When a chat is deleted, all its messages and members are deleted
- When a dialog is deleted, all its messages and message contents are deleted
add_workspace_owner_as_member_trigger: Automatically adds workspace owner as admin membersync_user_workspaces_insert_triggerandsync_user_workspaces_delete_trigger: Maintain user_workspaces table- When a workspace is created, the owner is automatically added as an admin member
- When users are added to workspace_members, a record is automatically added to user_workspaces
- When users are removed from workspace_members, the corresponding record is removed from user_workspaces
- User profiles are automatically created when users sign up
All permission-checking functions use SECURITY DEFINER and execute with row security disabled to prevent RLS from interfering with permission checks.
Functions use clear parameter naming (workspace_id_param, chat_id_param) to avoid column ambiguity in function bodies.
All content access is validated through chains of ownership:
- User owns dialog → Dialog contains messages → Messages contain content
- User is member of chat → Chat contains messages → User can access messages
- Added
parent_idandis_sharedto user_assistants table for inheritance and sharing - Created
assistant_sharing_typeENUM with 'global' and 'workspace' values - Added
can_manage_assistantfunction to handle complex assistant permissions - Created
user_workspacestable for fast user-workspace relationship lookups - Added triggers to maintain user_workspaces data automatically
- Enhanced RLS policies for shared assistants (global and workspace-level)
- Added
is_workspace_admin_or_ownerfunction to centralize permission checks - Added
is_workspace_memberfunction for membership verification - Enhanced chat access control with
can_manage_chatfunction - Implemented clear distinction between workspace and private chats
- Improved parameter naming in functions to avoid ambiguity
- Simplified chat types from three values (workspace, group, private) to two (workspace, private)
- Updated chat-related RLS policies to use workspace membership for access control
- Enhanced workspace public/private access model with is_public flag