Ir al contenido

ACL y record rules en Odoo: paso a paso con ejemplo real

Crear grupos, ir.model.access.csv y reglas por dominio
17 de junio de 2026 por
ACL y record rules en Odoo: paso a paso con ejemplo real
Aitor Atencia

Odoo · Seguridad · Permisos

La seguridad en Odoo tiene dos capas: ACL (¿puede este grupo crear/leer/escribir/borrar este modelo?) y record rules (¿qué registros concretos ve?). Configurarlas mal es la causa más frecuente de «el usuario no ve nada» o, peor, de fugas de datos entre clientes.

Logo Odoo Escudo seguridad
ACL = puerta del edificio. Record rules = llaves de cada habitación.

Panorama

Dos capas complementarias

CapaArchivo / modeloPregunta que responde
ACLsecurity/ir.model.access.csv¿El grupo tiene permiso CRUD sobre el modelo?
Record rulessecurity/*_rules.xmlir.rule¿Qué filas del modelo puede ver/modificar?
Grupossecurity/*_groups.xmlres.groups¿Quién es «Profesional», «Cliente», «Admin»?

Sin ACL, el modelo no existe para el usuario. Con ACL pero sin record rules, ve todos los registros del modelo. En datos sensibles (menores, salud, contratos), siempre necesitas ambas capas.

Paso 1

Definir grupos de seguridad

<!-- security/diagnostic_groups.xml -->
<record id="group_diagnostic_user" model="res.groups">
    <field name="name">Diagnostic User</field>
    <field name="category_id" ref="base.module_category_services"/>
</record>

<record id="group_diagnostic_professional" model="res.groups">
    <field name="name">Diagnostic Professional</field>
    <field name="category_id" ref="base.module_category_services"/>
    <field name="implied_ids" eval="[(4, ref('group_diagnostic_user'))]"/>
</record>

implied_ids hereda permisos: un profesional incluye automáticamente los del usuario base. Evita duplicar ACL para cada nivel.

Paso 2

ACL en ir.model.access.csv

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_diagnostic_test_user,diagnostic.test.user,model_diagnostic_test,group_diagnostic_user,1,0,0,0
access_diagnostic_test_prof,diagnostic.test.professional,model_diagnostic_test,group_diagnostic_professional,1,1,1,0
access_diagnostic_test_manager,diagnostic.test.manager,model_diagnostic_test,base.group_system,1,1,1,1

Convención de id: access_<modelo>_<grupo>. El model_id:id usa el prefijo model_ + nombre del modelo con puntos sustituidos por guiones bajos.

Paso 3

Record rules por dominio

Ejemplo: un cliente solo ve sus diagnósticos; un profesional solo los asignados:

<record id="diagnostic_test_rule_client" model="ir.rule">
    <field name="name">Diagnostic Test: client own records</field>
    <field name="model_id" ref="model_diagnostic_test"/>
    <field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
    <field name="groups" eval="[(4, ref('base.group_portal'))]"/>
    <field name="perm_read" eval="True"/>
    <field name="perm_write" eval="False"/>
    <field name="perm_create" eval="False"/>
    <field name="perm_unlink" eval="False"/>
</record>

<record id="diagnostic_test_rule_professional" model="ir.rule">
    <field name="name">Diagnostic Test: assigned professional</field>
    <field name="model_id" ref="model_diagnostic_test"/>
    <field name="domain_force">[('professional_id', '=', user.id)]</field>
    <field name="groups" eval="[(4, ref('group_diagnostic_professional'))]"/>
</record>
Configuración seguridad Odoo
Ajustes → Usuarios → Grupos: verifica que cada usuario tiene el grupo correcto.

Orden

Orden en __manifest__.py

'data': [
    'security/diagnostic_groups.xml',      # 1. Grupos primero
    'security/ir.model.access.csv',        # 2. ACL
    'security/diagnostic_rules.xml',     # 3. Record rules (referencian grupos)
    'views/diagnostic_test_views.xml',
],

Las record rules referencian group_id y model_id que deben existir. Cargar vistas antes que seguridad provoca errores de instalación o permisos temporales incorrectos.

Depuración

Checklist cuando «no ve registros»

SíntomaCausa probableAcción
Access Error al abrir menúSin ACL para su grupoAñadir línea en CSV
Lista vacía sin errorRecord rule demasiado restrictivaRevisar domain_force con ese usuario
Ve registros de otros clientesFalta record rule o dominio incorrectoAñadir regla para portal / multi-company
Admin ve todo, usuario nobase.group_system bypass rulesProbar con usuario de prueba real
Funciona en dev, falla en prodGrupos no asignados al usuarioVerificar res.users → grupos
# Shell de depuración (entorno de prueba)
user = env['res.users'].browse(UID)
env['diagnostic.test'].with_user(user).search([])  # ¿Qué ve realmente?

Multi-company

Reglas globales vs por grupo

Odoo aplica record rules con operador AND entre grupos del usuario y OR entre reglas del mismo grupo. En multi-compañía, la regla estándar ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] suele añadirse automáticamente.

Si defines reglas propias, no olvides incluir la restricción de compañía o podrías filtrar registros de forma inconsistente entre módulos.

Resumen

Crea grupos con herencia (implied_ids), define ACL restrictivos en CSV y añade record rules con dominios que reflejen el negocio real. Carga seguridad antes que vistas, prueba con with_user() y documenta qué ve cada rol. La combinación ACL + rules es la base de cualquier módulo con datos sensibles.

en Odoo
Mixins imprescindibles en Odoo: mail.thread, mail.activity.mixin y utm.mixin
Qué aporta cada mixin y cuándo no usarlos (enlace con SOLID)