Permission Levels
Permissions are defined as an enum in the database schema and enforce a clear hierarchy:Permission Hierarchy
The hierarchy follows this order (from lowest to highest):types.ts:33 enforces this:
View Permission
What View users can do:- Read email threads and messages
- View service configurations
- See categories and workspace members
- Browse all sections of the interface
- Edit drafts or thread properties
- Generate AI drafts
- Send emails
- Modify service settings
- Manage workspace members
View permission is ideal for stakeholders who need visibility into customer communications without the ability to respond.
Edit Permission
What Edit users can do:- Everything View users can do
- Edit draft content
- Use “Talk to Draft” to refine drafts with AI
- Translate drafts
- Change thread categories
- Mark threads as read/unread
- Archive threads
- Send emails (drafts remain unsent)
- Generate new AI drafts from scratch
- Modify service settings
- Manage workspace members
Edit permission is perfect for team members who prepare responses but require approval before sending.
Send Permission
What Send users can do:- Everything Edit users can do
- Generate AI drafts
- Send emails to customers
- Bulk send multiple drafts
- Create or modify services
- Connect Gmail accounts
- Manage workspace members
- Change service documents or signatures
Send permission is for frontline support agents who handle customer communications end-to-end.
Admin Permission
What Admin users can do:- Everything Send users can do
- Create and configure services
- Connect Gmail accounts via OAuth
- Manage service documents and signatures
- Create and edit categories
- Add, modify, and remove workspace members
- Trigger manual syncs
- Access all API endpoints
Managing Workspace Members
Workspace members are users who have access to DelightBridge but aren’t configured as admin emails.Adding Members
Admins can add members through the Settings modal or the API:workspace_members table:
Updating Member Permissions
To change a member’s permission level:- Find the member in the list
- Select a new permission level from the dropdown
- Changes apply immediately
Permission changes take effect on the user’s next request. They may need to refresh their browser to see updated capabilities.
Removing Members
To revoke access:workspace_members. They will be unable to log in on their next attempt.
Admin Emails vs Workspace Members
DelightBridge supports two types of admins:Admin Emails (Environment-based)
Configured in.env.local:
- Hardcoded access that cannot be revoked through the UI
- Always have admin permission, even if added to
workspace_memberswith a lower level - Automatically upgraded to admin during login
- Cannot be removed from the members list in the UI
Workspace Member Admins
Added through the members management interface with admin permission: Characteristics:- Can be promoted to admin by existing admins
- Permission can be changed or revoked
- Appear in the members list
- Have identical capabilities to environment-based admins
Which should I use?
Which should I use?
Use Admin Emails for:
- Permanent administrators
- System owners
- Users who should never lose access
- Temporary administrators
- Team leads whose role may change
- Users whose access might need to be revoked
Permission Enforcement
Permissions are enforced at multiple levels:API Route Protection
API routes check permissions before processing requests:session.ts:33:
Frontend UI Restrictions
The UI conditionally renders features based on permissions:Frontend restrictions are for UX only. All authorization is enforced on the backend to prevent bypassing through browser tools.
Permission-Specific API Endpoints
Admin-Only Endpoints
POST /api/services- Create servicePATCH /api/services/{id}- Update serviceDELETE /api/services/{id}- Delete servicePOST /api/services/{id}/connect- Connect GmailPOST /api/services/{id}/sync- Trigger syncGET /api/members- List membersPOST /api/members- Add memberPATCH /api/members/{email}- Update memberDELETE /api/members/{email}- Remove member
Send-Level Endpoints
POST /api/threads/{id}/send- Send emailPOST /api/draft/generate- Generate AI draft
Edit-Level Endpoints
PATCH /api/threads/{id}- Update thread (category, status, isRead)PATCH /api/drafts/{threadId}- Update draft contentPOST /api/draft/talk- Talk to DraftPOST /api/draft/translate- Translate draft
View-Level Endpoints
GET /api/threads- List threadsGET /api/threads/{id}- Get thread detailsGET /api/services- List servicesGET /api/drafts/{threadId}- Get draft
Best Practices
Start with minimum permissions
Start with minimum permissions
Grant the lowest permission level needed for each user’s role. You can always promote them later if needed.
Use workspace members for team leads
Use workspace members for team leads
Even for admins, prefer workspace member admins over environment-based admin emails unless the access should be permanent.
Regular permission audits
Regular permission audits
Periodically review workspace members to ensure permissions are still appropriate and remove users who no longer need access.
Document permission decisions
Document permission decisions
Keep a record of why specific users have certain permission levels, especially for send and admin permissions.
Test with limited permissions
Test with limited permissions
When developing new features, test with view and edit permissions to ensure proper enforcement.
Troubleshooting
User cannot see Settings button
User cannot see Settings button
Cannot send emails despite having send permission
Cannot send emails despite having send permission
Verify:
- The Gmail service is connected
- The thread has a draft ready
- No API errors in browser console
- User session is valid (try refreshing)
Admin in ADMIN_EMAILS appears with wrong permission
Admin in ADMIN_EMAILS appears with wrong permission
This is a display issue. Environment-based admins always have admin permission regardless of what’s shown. The session callback enforces this.
Cannot remove a workspace member
Cannot remove a workspace member
If the member is also in
ADMIN_EMAILS, they cannot be removed through the UI. Remove them from the environment variable instead.