Skip to main content
Hiro CRM uses a role-based access control (RBAC) system designed specifically for hospitality organizations in Spain. This guide explains how to configure and manage user roles and permissions.

Available User Roles

Hiro includes 6 built-in roles, each with specific permissions:

Super Admin

Full system access
  • Complete control over all modules
  • User management
  • System settings
  • All location access

CEO

Executive dashboard access
  • View all operations
  • Executive analytics
  • All modules except user management
  • Read-only settings

Marketing

Customer & campaign management
  • Customer database
  • Marketing campaigns
  • Segments and automations
  • Basic operations access

Operaciones

Daily operations management
  • Reservations
  • Customer interactions
  • Tickets and service
  • No marketing or HR access

RRHH

Human resources management
  • Employee management
  • HR tools
  • Limited customer access
  • No operations access

PR Comunicación

Public relations & media
  • Media center
  • Press kit
  • VIP management
  • Limited operational access

Permission Matrix

Here’s what each role can access:
ModuleSuper AdminCEOMarketingOperacionesRRHHPR Comunicación
Dashboard
Tickets
Operaciones (Reservations)
Clientes (CRM)
Marketing
RRHH (HR)
Ejecutivos (Analytics)
Grupo (Media Center)
User Management
Settings✅ (read)
See frontend/lib/roles.ts:20-93 for the complete permission definitions.

Role-Based Code Implementation

Role Type Definition

export type UserRole = 
  | 'super_admin' 
  | 'ceo' 
  | 'marketing' 
  | 'operaciones' 
  | 'rrhh' 
  | 'pr_comunicacion';

export const ROLES: Record<string, UserRole> = {
  SUPER_ADMIN: 'super_admin',
  CEO: 'ceo',
  MARKETING: 'marketing',
  OPERACIONES: 'operaciones',
  RRHH: 'rrhh',
  PR_COMUNICACION: 'pr_comunicacion',
};
From frontend/lib/roles.ts:1-18

Checking Permissions

export function hasPermission(
  role: UserRole, 
  permission: keyof typeof PERMISSIONS['super_admin']
) {
  const rolePermissions = PERMISSIONS[role];
  if (!rolePermissions) return false;
  return rolePermissions[permission] || false;
}
From frontend/lib/roles.ts:95-99

Managing User Roles

Creating a New User

1

Access User Management

Only Super Admin can create users.Navigate to Settings > Team (or use the admin script).
2

Add User Details

Provide:
  • Email address
  • Full name
  • Role assignment
3

Assign Role

Select the appropriate role based on the user’s responsibilities:
Use Operaciones for:
  • Restaurant managers
  • Reservation coordinators
  • Front-of-house staff
  • Service supervisors
4

Send Invitation

The user receives an email invitation to set their password and access Hiro.

Changing User Roles

Changing a user’s role immediately affects their access. Ensure the change is intentional.
1

Navigate to User Management

Go to Settings > Team
2

Select User

Find the user whose role you want to change
3

Update Role

Select the new role from the dropdown
4

Save Changes

Confirm the role change. The user’s access updates immediately.

Authorization System

Server-Side Authorization

Hiro uses server-side checks to enforce permissions:
import { requireAuth, requirePermission } from '@/lib/authz';

// Require authentication only
export async function getCustomers() {
  const { supabase, user, role } = await requireAuth();
  // ... fetch customers
}

// Require specific permission
export async function createCampaign() {
  const { supabase, user, role } = await requirePermission('canAccessMarketing');
  // ... create campaign
}
From frontend/lib/authz.ts:5-51

Authorization Flow

1

User Attempts Action

User clicks a button or navigates to a page
2

Authentication Check

System verifies user is logged in:
const { data: { user }, error } = await supabase.auth.getUser();
if (error || !user) {
  throw new Error("UNAUTHENTICATED");
}
3

Role Lookup

System fetches user’s role from profile:
const { data: profile } = await supabase
  .from("profiles")
  .select("role")
  .eq("id", user.id)
  .single();

const role = profile.role || 'marketing';
4

Permission Check

System verifies role has required permission:
const rolePermissions = PERMISSIONS[role];
if (!rolePermissions?.[permission]) {
  throw new Error("FORBIDDEN");
}
5

Action Allowed or Denied

  • Allowed: Action proceeds
  • Denied: Error returned, user redirected

Role-Based UI Customization

Dashboard Customization

Different roles see different dashboard greetings and features:
const isExecutive = user?.role === 'super_admin' || user?.role === 'ceo';
const isMarketing = user?.role === 'marketing';
const isOperational = user?.role === 'operaciones';
const isHR = user?.role === 'rrhh';
const isCommunication = user?.role === 'pr_comunicacion';

// Different messages per role
{isExecutive && 'Vista ejecutiva de todas las operaciones'}
{isMarketing && 'Clientes y campañas pendientes'}
{isOperational && 'Control de reservas y servicio de hoy'}
{isHR && 'Resumen de gestión de recursos humanos'}
{isCommunication && 'Portal de comunicación y VIPs'}
From frontend/components/dashboard/CustomizableDashboard.tsx:162-424 Menu items are hidden based on role:
// Example: Marketing menu only visible to marketing role
{hasPermission(role, 'canAccessMarketing') && (
  <NavLink href="/features/marketing-campaigns">
    Marketing
  </NavLink>
)}

Common Role Scenarios

Recommended Role: operacionesCan access:
  • View reservations across all locations
  • Manage daily operations
  • Handle customer service tickets
  • Access customer profiles
Cannot access:
  • Marketing campaigns
  • Executive analytics
  • HR functions
  • System settings
Recommended Role: marketingCan access:
  • Customer database and segments
  • Create and manage campaigns
  • Set up automated workflows
  • View basic operational data
Cannot access:
  • HR functions
  • Executive-level analytics
  • Detailed operations (reservations)
Recommended Role: ceoCan access:
  • Executive dashboard with all KPIs
  • Cross-location analytics
  • All operational modules (read-only)
  • Strategic insights
Cannot access:
  • User management
  • System configuration
Recommended Role: pr_comunicacionCan access:
  • Media center and press kit
  • VIP customer management
  • Group resources
  • Tickets and basic operations
Cannot access:
  • Marketing campaigns
  • Operations/reservations
  • HR functions
  • Analytics

Platform Admin vs Regular Roles

Platform Admin (Super Admin)

The super_admin role has unrestricted access:
const isPlatformAdmin = role === 'super_admin';

if (isPlatformAdmin) {
  return { supabase, user, role, isPlatformAdmin };
}
Super Admin capabilities:
  • Create and delete users
  • Modify system settings
  • Access all modules
  • Configure integrations
  • Manage locations and brands
From frontend/lib/authz.ts:28-40

Regular Roles

All other roles follow permission-based access:
  • Access is explicitly granted per module
  • Cannot modify users or settings
  • Limited to their functional area

Best Practices

Principle of Least Privilege

Assign the minimum role needed:
  • Don’t give ceo role just for analytics
  • Use operaciones for daily staff
  • Reserve super_admin for IT/owners

Regular Access Reviews

Review user roles quarterly:
  • Remove access for departed employees
  • Update roles for promoted staff
  • Verify permissions are still appropriate

Document Role Assignments

Keep a record of:
  • Who has which role
  • Why they were assigned that role
  • Date of last review

Separate Operational & Strategic

  • Operational staff: operaciones, marketing
  • Strategic staff: ceo
  • Specialized: rrhh, pr_comunicacion
  • System admin: super_admin

Troubleshooting

  1. Verify their role in Settings > Team
  2. Check the permission matrix above
  3. Ensure the module is enabled for that role
  4. If needed, change their role to one with appropriate access
The user’s role lacks the required permission:
// Error thrown when permission check fails
throw new Error("FORBIDDEN");
Solutions:
  • Upgrade their role if justified
  • Use a different user account with appropriate role
  • Contact a Super Admin to adjust permissions
Check:
  1. User received invitation email
  2. User completed password setup
  3. Profile was created with correct role
  4. Account is not deactivated
If issue persists, use admin script to verify user:
npm run verify-user <email>
Hiro’s roles are fixed in code. For custom needs:
  1. Choose the closest existing role
  2. Use feature flags or settings to fine-tune access
  3. For major customization, contact support
Do not modify frontend/lib/roles.ts without developer assistance.

Next Steps

Set Up Locations

Configure multi-location access for your team

Configure Automations

Set up automated workflows based on user roles

API Authentication

Learn how to authenticate API requests with roles

Architecture Overview

Understand Hiro’s architecture and security model

Build docs developers (and LLMs) love