This document outlines the comprehensive security measures implemented in the NextSaaS admin system to ensure enterprise-grade protection against unauthorized access and security threats.
Problem: Any authenticated user could access admin functions due to improper authorization checks.
Solution:
- Implemented proper
isUserSystemAdminfunction from@nextsaas/auth/middleware/admin-middleware - All admin API endpoints now verify both authentication AND system admin privileges
- Added database-backed admin privilege verification using
system_adminstable
Problem: Direct Supabase imports violated the unified client pattern, causing session conflicts.
Solution:
- Replaced all direct
@supabase/supabase-jsimports with unified@nextsaas/supabaseclient - Ensures consistent session handling across the entire application
- Prevents authentication state conflicts between admin and user interfaces
Problem: High-privilege service role credentials were used inappropriately in API routes.
Solution:
- Removed all inappropriate service role key usage
- Replaced direct user creation with proper invitation flow requirements
- Implemented secure user management patterns
-- System admin flag for quick identification
ALTER TABLE users ADD COLUMN IF NOT EXISTS is_system_admin BOOLEAN DEFAULT FALSE;
CREATE INDEX idx_users_is_system_admin ON users(is_system_admin) WHERE is_system_admin = TRUE;CREATE TABLE system_admins (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
granted_by UUID REFERENCES users(id),
granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
revoked_at TIMESTAMP WITH TIME ZONE,
permissions JSONB DEFAULT '[]',
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id)
);CREATE TABLE system_admin_audit (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
admin_user_id UUID NOT NULL REFERENCES users(id),
action VARCHAR(100) NOT NULL,
target_type VARCHAR(50),
target_id UUID,
details JSONB DEFAULT '{}',
ip_address INET,
user_agent TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);admin:access_dashboard- Basic admin dashboard accessadmin:manage_users- Full user management capabilitiesadmin:view_users- Read-only user accessadmin:suspend_users- User suspension capabilitiesadmin:impersonate_users- User impersonation for debuggingadmin:delete_users- User deletion capabilitiesadmin:manage_organizations- Organization managementadmin:view_organizations- Read-only organization accessadmin:delete_organizations- Organization deletionadmin:view_analytics- Analytics dashboard accessadmin:export_data- Data export capabilitiesadmin:manage_billing- Billing system managementadmin:view_billing- Read-only billing accessadmin:manage_email- Email campaign managementadmin:view_email_campaigns- Email campaign viewingadmin:send_emails- Email sending capabilitiesadmin:manage_security- Security settings managementadmin:view_audit_logs- Audit log accessadmin:view_security_events- Security event monitoringadmin:manage_system- System configurationadmin:view_system_health- System health monitoringadmin:manage_settings- Platform settingsadmin:manage_features- Feature flag managementadmin:manage_announcements- System announcements
- Session Verification: All admin routes verify valid user session
- System Admin Check: Verify
users.is_system_admin = TRUE - Active Admin Record: Confirm active record in
system_adminstable withrevoked_at IS NULL - Permission Validation: Check specific permissions for granular access control
- Audit Logging: Log all admin actions for compliance and security monitoring
export async function adminAPIMiddleware(
request: NextRequest,
requiredPermissions: string[] = []
): Promise<{ success: boolean; session?: any; supabase?: any; error?: string; status?: number }>Features:
- Consistent authentication across all admin endpoints
- Permission-based access control
- Automatic security event logging for unauthorized attempts
- Rate limiting protection
- Comprehensive audit trail
export async function GET(request: NextRequest) {
const authResult = await adminAPIMiddleware(request, [ADMIN_PERMISSIONS.VIEW_USERS])
if (!authResult.success) {
return NextResponse.json({ error: authResult.error }, { status: authResult.status })
}
// Proceed with authenticated admin user
const { session, supabase } = authResult
}-- Only system admins can view system admin records
CREATE POLICY "system_admins_select_policy" ON system_admins
FOR SELECT USING (is_system_admin(auth.uid()));
-- Only existing system admins can manage other system admins
CREATE POLICY "system_admins_insert_policy" ON system_admins
FOR INSERT WITH CHECK (is_system_admin(auth.uid()));-- Only system admins can view audit logs
CREATE POLICY "system_admin_audit_select_policy" ON system_admin_audit
FOR SELECT USING (is_system_admin(auth.uid()));
-- System can insert audit records (functions, triggers)
CREATE POLICY "system_admin_audit_insert_policy" ON system_admin_audit
FOR INSERT WITH CHECK (true);CREATE OR REPLACE FUNCTION is_system_admin(user_uuid UUID)
RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (
SELECT 1 FROM users u
JOIN system_admins sa ON u.id = sa.user_id
WHERE u.id = user_uuid
AND u.is_system_admin = TRUE
AND sa.revoked_at IS NULL
);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;CREATE OR REPLACE FUNCTION log_system_admin_action(
admin_id UUID,
action_name VARCHAR,
target_type VARCHAR DEFAULT NULL,
target_id UUID DEFAULT NULL,
action_details JSONB DEFAULT '{}',
ip_addr INET DEFAULT NULL,
user_agent_str TEXT DEFAULT NULL
) RETURNS UUID AS $$- Admin users receive only the minimum permissions required for their role
- Granular permission system allows fine-tuned access control
- Regular permission audits ensure appropriate access levels
- Multiple layers of security checks (session, admin flag, active record, permissions)
- Rate limiting prevents abuse
- Comprehensive audit logging for security monitoring
- All admin routes require explicit security verification
- Default deny for all admin operations
- Secure session handling through unified Supabase client
- All admin actions are logged with full context
- Security events are tracked for unauthorized access attempts
- IP addresses and user agents logged for forensic analysis
- RLS policies prevent unauthorized data access
- Secure database functions with proper privilege levels
- No sensitive credentials exposed in API routes
# Apply the admin system migration
npx supabase db reset-- Update the email in packages/database/seeds/001_create_super_admin.sql
-- Then run the seed scriptEnsure proper environment variables are set (no service role key exposure):
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
# No SUPABASE_SERVICE_ROLE_KEY in API routes- Test admin access with proper credentials
- Verify non-admin users cannot access admin functions
- Check audit logs are being created properly
- Unauthorized admin access attempts
- Failed authentication attempts on admin endpoints
- Unusual admin activity patterns
- Permission escalation attempts
- High-frequency admin API calls
- Multiple failed admin login attempts
- Admin access from new IP addresses
- Admin privilege grants/revocations
- Large data exports
- System configuration changes
- Comprehensive audit logging
- Access control documentation
- Security monitoring capabilities
- Data protection measures
- Data export capabilities
- User deletion functionality
- Comprehensive audit trails
- Privacy controls
- Access logging and monitoring
- User activity tracking
- Secure data handling
- Administrative safeguards
- Immediately revoke admin privileges in
system_adminstable - Set
revoked_attimestamp - Review audit logs for suspicious activity
- Reset affected account credentials
- Notify security team
- Review system admin audit logs
- Check for unauthorized permission changes
- Verify all admin actions are legitimate
- Implement additional monitoring if needed
- Restore from backup if data compromise suspected
- Re-apply security patches
- Audit all admin accounts and permissions
- Update security procedures based on incident
The NextSaaS admin security system now provides enterprise-grade protection with:
- ✅ Proper authentication and authorization
- ✅ Comprehensive audit logging
- ✅ Granular permission system
- ✅ Row-level security
- ✅ Rate limiting and monitoring
- ✅ Secure API design patterns
All critical security vulnerabilities have been resolved, and the system follows security best practices for SaaS applications.