Migrar permisos a Odoo 20: prueba el aislamiento entre empresas

Volver
Kevin Riedl

13 minutos de lectura · 5 nov 2026
Última revisión

Siguiente
Se crea en tu dispositivo, sin conectar con Instagram. Copiamos el enlace para su sticker de enlace.

En el ejemplo ficticio, el mismo usuario y registro pasan de acceso denegado a permitido tras una reescritura ingenua de permisos. La política de negocio no ha cambiado. Sí ha cambiado la forma de combinar las concesiones.

Acepta una migración de permisos a Odoo 20 solo cuando la matriz aprobada de roles y empresas supere operaciones permitidas y denegadas en la base actualizada. Verifica concesiones convertidas y restricciones globales. Prueba por separado las empresas activadas y los valores de la empresa actual. Instalar correctamente o recorrer las pantallas como administrador no aporta esa evidencia.

Investigación revisada: 5 de noviembre de 2026. Inspeccionamos documentación oficial de Odoo 19 y 20, la implementación de acceso 20.0 y su script de conversión. Ejecutamos dieciséis casos ficticios de política en Python. No ejecutamos Odoo, una actualización de base ni el convertidor oficial. La matriz nativa descargable sigue en NOT_RUN.

¿Qué cambió en el control de acceso de Odoo 20?

Odoo 20 reúne operaciones y dominios de registros en un mismo modelo de acceso. La migración debe revisar el significado combinado de las concesiones resultantes. Cargar un archivo de seguridad renombrado no basta. Conserva una referencia aprobada de la política y compara los resultados reales de cada rol afectado.

La referencia oficial de seguridad 20.0 define ir.access con grupo, operación y dominio. Las entradas con grupo conceden acceso; las que no tienen grupo lo restringen. La referencia 19.0 describe concesiones ACL de modelo separadas, seguidas por reglas de registro.

Inventaría los registros de seguridad personalizados y los métodos de negocio que dependen de ellos. Anota qué política aplica cada entrada: «el propietario lee sus casos de su empresa» y «el revisor lee todos los casos de las empresas activadas» son políticas diferentes, aunque ambos puedan abrir el mismo menú.

La guía de aceptación de migraciones a Odoo cubre registros y continuidad operativa. Aquí se decide el acceso. Un pedido migrado correctamente sigue siendo inaceptable si una identidad no autorizada puede recuperarlo.

¿Cómo se combinan concesiones de grupo y restricciones globales?

En una comprobación de acceso ordinaria, el registro necesita al menos una concesión de grupo coincidente y debe cumplir todas las restricciones globales aplicables. En el ejemplo, una concesión amplia expande los registros legibles, mientras la restricción global de empresa limita esa expansión. Una restricción sola no concede acceso. Prueba las combinaciones.

El modelo expresa la decisión así:

alguna concesión de grupo coincidente
Y
todas las restricciones globales aplicables

El grupo inventado own_reader solo permite registros propiedad del usuario 7. Una restricción global independiente limita el acceso a las empresas activadas. El usuario puede leer A-OWN, pero no A-OTHER. Añadir broad_reader vuelve legible el segundo porque aporta otra concesión coincidente.

Mantén ahora B inactiva. El grupo amplio sigue sin poder leer B-OWN mientras se aplique la restricción global. Elimina esa restricción en la configuración deliberadamente defectuosa del ejemplo y el registro será legible. La prueba expone el límite ausente; no afirma que Odoo lo omita por defecto.

Prueba también un registro legítimamente permitido. Dos restricciones globales contradictorias, una que exige A y otra B, lo deniegan en el modelo. Una batería que solo compruebe prohibiciones podría aprobar esa configuración rota. Cada denegación relevante necesita un control permitido que demuestre que el usuario puede trabajar.

¿Qué contexto de empresa debe registrar la prueba?

Registra por separado pertenencia, empresas activadas y empresa actual. Explican qué empresas puede seleccionar el usuario, qué alcance utiliza esta operación y qué empresa proporciona valores dependientes del contexto. Sin esos datos, un resultado de aceptación no puede explicar por qué un registro apareció o quedó oculto.

El evaluador de dominios de acceso 20.0 obtiene company_ids de env.companies.ids, las empresas activadas, y company_id de env.company.id. No sustituyas ese alcance por todas las empresas asignadas al usuario.

Entradas independientes del ejemplo ficticio de acceso
DimensiónEjemploPregunta de aceptación
Pertenencia autorizadaEl usuario 7 pertenece a A y B.¿Puede esta identidad seleccionar B?
Empresas activadasSolo A está activa para esta llamada.¿La operación limitada por empresa excluye registros de B?
Empresa actualA es la actual mientras A y B están activas.¿De qué empresa toma el valor la operación?
Empresa del registroB-OWN pertenece a B.¿El registro resultante pertenece a la empresa prevista?

La implementación del entorno valida empresas seleccionadas para usuarios ordinarios, aplica un valor de respaldo si la lista está vacía y omite las comprobaciones indicadas en modo sudo. Una lista vacía no significa denegar todo. Ejecutar con privilegios elevados no prueba el aislamiento del usuario ordinario.

El ejemplo muestra la diferencia. Con pertenencia a A/B y solo A activada, se deniega el registro propio de B. Al activar A/B, se permite. Un usuario asignado únicamente a A no puede activar B en el modelo. Mantén estos casos separados, en vez de resumirlos como «multiempresa funciona».

¿Por qué una conversión ingenua de ACL puede ampliar el acceso?

Puede conservar una antigua concesión amplia de modelo como concesión amplia de registros junto a otra más limitada. El contraejemplo asigna ambos grupos al usuario. La política antigua por capas deniega el registro ajeno; la nueva unión lo admite. Es una reescritura defectuosa ilustrativa, no un resultado del convertidor oficial de Odoo.

Contraejemplo de conversión deliberadamente pequeño
EtapaPolítica del ejemploRegistro ajeno de A
Ejemplo antiguo por capasUna ACL de modelo permite leer; una regla aplicable de registros propios filtra el resultado.Denegado
Nueva reescritura ingenuaSe combina una concesión amplia de registros con otra de registros propios.Permitido
Política objetivo aprobadaEl responsable sigue exigiendo acceso solo a registros propios para ese rol.Debe seguir denegado

El código oficial de conversión de acceso realiza inferencias teniendo en cuenta los grupos y advierte sobre ACL amplias que interactúan con reglas más limitadas. Sus avisos requieren revisión. Inspeccionamos el código, pero no lo ejecutamos.

Conserva la salida y los registros del convertidor como evidencia. Para cada aviso, identifica la combinación efectiva de grupos y la operación afectada. Después demuestra el resultado aprobado en la base actualizada. Un registro de conversión limpio también necesita pruebas de regresión de tu política.

El ejemplo no es una orden universal de borrar concesiones amplias. Otro rol puede necesitarlas legítimamente. Compara toda la matriz aprobada antes de modificar un grupo compartido, incluidos los usuarios que lo reciben a través de otro rol.

¿Qué mostraron los dieciséis casos locales?

Los dieciséis casos produjeron las observaciones esperadas. Ilustran cómo aislar una restricción ausente, una concesión adicional o un contexto de empresa equivocado. También separan visibilidad, selección de valores y coherencia de relaciones. Son observaciones de un modelo Python pequeño, no una evaluación de seguridad de una base Odoo.

Casos ficticios ejecutados el 5 de noviembre de 2026
CasoEsperadoObservado
Registro propio en A activaPermitirPermitido
Registro ajeno en A activaDenegarDenegado
B autorizada pero no activadaDenegar registro de BDenegado
B autorizada y activadaPermitir registro propio de BPermitido
Activar B sin pertenenciaRechazar contextoError de contexto
Añadir concesión amplia de grupoEl registro ajeno de A pasa a ser legiblePermitido
Grupo amplio con restricción global de empresaB inactiva sigue denegadaDenegado
Omitir restricción global de empresaLa configuración defectuosa expone B inactivaPermitido
Restricciones globales solo-A y solo-B contradictoriasBloquear registro legítimo de ADenegado
Registro compartido sin empresaPolítica estricta deniega; política compartida explícita permiteDenegado / permitido
Restricción global sin concesión de grupoDenegarDenegado
Rol de solo lectura del ejemploPermitir lectura; denegar escritura y borradoPermitido / denegado / denegado
Conversión ingenua de la política antigua por capasUna denegación se convierte en permiso no deseadoDenegado / permitido
Registro B visible con A o B como actualEl valor cambia: 100,00 frente a 120,00100,00 / 120,00
Registro A visible vinculado a un registro BAcceso válido; comprobación ilustrativa de relación fallaPermitido / incoherente
Entrada vacía de empresas activadasRecurrir a pertenencias A/BRegistro B legible

Descarga el modelo de permisos ejecutable y los resultados registrados. Con Python 3.10 o posterior, ejecuta:

python3 permission-model.py

El modelo recibe los grupos efectivos ya expandidos. No implementa herencia de grupos, dominios de Odoo, permisos de campo, cachés ni mecanismos nativos de creación o escritura. La relación se comprueba mediante una igualdad sencilla. No acredita el comportamiento de todos los campos compartibles o dependientes de empresa de un módulo real.

¿Qué debe incluir la matriz nativa de roles y empresas?

La matriz nativa necesita un resultado esperado aprobado para cada identidad, contexto y operación relevantes, seguido de evidencias del sistema actualizado. Empareja trabajo permitido con acceso denegado. En escrituras prohibidas, inspecciona el estado final y el error. Una captura de un menú ausente no demuestra la operación subyacente.

La matriz nativa propuesta empieza íntegramente en NOT_RUN. Sus expectativas son ejemplos que aprobar o reemplazar. Antes de decidir un lanzamiento, completa usuario y grupos efectivos, revisión de compilación, punto de entrada, identificadores, contexto empresarial y evidencias.

Evidencias que recoger en la base actualizada real
DimensiónContraste necesarioEvidencia
RolPropietario ordinario frente a revisor amplio aprobadoGrupos efectivos y conjunto esperado de registros por identidad
Alcance de empresaSolo A, A/B activadas y selección no autorizada de BContexto exacto y empresa del registro objetivo
OperaciónLectura o escritura permitida frente a cambio prohibidoRegistros devueltos, estado final y ausencia de cambios prohibidos
Punto de entradaAcción de usuario y cada integración o tarea relevanteIdentidad real de ejecución y operación invocada
Migración de políticaExpectativa antigua aprobada frente a nueva intenciónAviso del convertidor, cambio revisado y resultado nativo observado
Coherencia del negocioValor de empresa correcto y relación permitidaEvidencias del valor y relación, separadas de visibilidad

Utiliza identificadores directos junto con la navegación habitual. Define la observación esperada por entrada: una búsqueda prohibida puede no devolver registros ajenos, mientras una operación solicitada puede rechazarse. No aceptes un resultado demasiado amplio porque la interfaz oculte las filas sobrantes.

Ejecuta operaciones destructivas solo con registros controlados en el entorno de ensayo. Incluye cambios permitidos para impedir que apruebe una configuración que bloquea a todos. La guía de pruebas por estado del negocio extiende el principio a tareas completas de agentes, donde una respuesta plausible puede ocultar un registro incorrecto.

¿Por qué comprobar valores y relaciones después del acceso?

Superar el acceso acredita que la identidad puede realizar la operación probada bajo esa política. No demuestra que se utilizó el valor de la empresa prevista ni una relación compatible. El ejemplo puede leer B usando el valor de A. También puede permitir un registro cuya relación propuesta falla una comprobación independiente de empresa.

La guía oficial multiempresa vincula los valores dependientes de empresa con la empresa actual y describe controles relacionales configurados mediante _check_company_auto y check_company. Verifícalos en los modelos y campos concretos.

En el ejemplo se pueden leer ambas empresas. Elegir A como actual devuelve el valor ficticio 100,00; elegir B devuelve 120,00. Si la tarea corresponde a B, leer correctamente 100,00 puede ser un resultado comercial incorrecto. Registra la empresa esperada junto al valor esperado.

Para relaciones, elige un vínculo permitido y otro prohibido entre empresas. Inspecciona la operación que los asigna. Un campo de empresa visible o un dominio de acceso no prueban todas las relaciones personalizadas. La guía de auditoría de módulos personalizados cubre la revisión más amplia de implementación.

¿Qué evidencia debe bloquear o autorizar la migración?

Bloquea el alcance afectado si una identidad inesperada accede a un registro protegido, un usuario legítimo pierde trabajo necesario o no puede acreditarse el contexto probado. Libera solo cuando la matriz aprobada pase en la versión prevista, los cambios deliberados estén autorizados y las advertencias abiertas tengan una resolución concreta.

Conserva matriz esperada, grupos efectivos y revisión exacta del módulo junto a las observaciones. Un rol revisor más amplio puede ser válido, pero requiere un cambio explícito de política. Una denegación antigua no es siempre la regla futura correcta, ni un permiso antiguo es siempre seguro.

La lista de QA previa al lanzamiento sitúa estas evidencias en la decisión general. La guía de arquitectura de la API de Odoo mantiene el alcance de alojamiento y protocolos. Cambiar una ruta API no reemplaza controles nativos de acceso.

Para el servicio de calidad de software de Wavect, prepara un rol afectado, dos contextos de empresa y la salida de conversión del módulo. El primer entregable útil es una matriz acordada de permisos y denegaciones, con evidencias nativas reproducibles para ese alcance.

Preguntas sobre la migración de permisos a Odoo 20

¿Un menú oculto demuestra que el acceso está denegado?
No. La aceptación trata del registro y la operación a los que puede acceder una identidad. Prueba la ruta habitual y el punto de entrada directo relevante con registros controlados. Captura datos devueltos y estado final. La imagen de un menú documenta la interfaz, pero no demuestra que la operación protegida respetó la política aprobada.
¿Una lista allowed_company_ids vacía impide acceder a todas las empresas?
No. En la implementación 20.0 inspeccionada, una lista vacía recurre a las empresas del usuario. Define un contexto permitido explícito y prueba su resultado. Si la aplicación requiere un estado sin acceso, especifícalo como resultado de política y verifícalo. No dependas de una lista de contexto vacía para conseguirlo.
¿Cómo deben aceptarse los registros sin empresa?
Decide cuáles se comparten intencionadamente y cuáles necesitan propietario. El ejemplo prueba una política estricta y otra que permite registros compartidos de forma explícita; producen resultados distintos. Usa registros representativos de cada categoría aprobada, incluidas sus relaciones. Una empresa ausente no debe convertirse silenciosamente en permiso para compartir datos sensibles.
¿Cómo se tratan los grupos heredados y adicionales?
Revisa el conjunto efectivo de grupos de la identidad, incluidos los recibidos mediante otro rol. El modelo descargable lo recibe como entrada y no calcula herencia. Ejecuta las combinaciones reales, especialmente un rol limitado con otro revisor más amplio. Probar cada grupo por separado puede omitir su efecto combinado.
¿Los dieciséis casos del modelo prueban la seguridad de la base real?
No. Demuestran resultados concretos de política y contexto en un programa pequeño de Python con biblioteca estándar. No ejecutan Odoo, interpretan dominios nativos ni prueban métodos personalizados. Usa los contraejemplos para mejorar la aceptación y ejecuta después la matriz NOT_RUN en la revisión actualizada exacta y con la política aprobada.
¿Qué cambia para cuentas de servicio y tareas programadas?
Registra la identidad y el contexto empresarial de cada automatización y prueba sus operaciones aprobadas. No sustituyas esa vía por un recorrido de administrador. Incluye registros previstos y uno controlado que no deba tocar, e inspecciona los cambios. Una credencial amplia necesita justificación de negocio explícita y alcance de aceptación propio.
¿Toda diferencia con Odoo 19 debe bloquear el lanzamiento?
Una diferencia inexplicada debe detener el alcance afectado hasta entenderla. Puede aprobarse una corrección deliberada, incluso eliminar una concesión antigua demasiado amplia. Registra expectativa anterior, nueva regla deseada y responsable que la autorizó. Compara el sistema actualizado con ese objetivo aprobado, no solo con el comportamiento anterior.

Construye el producto, no solo el backlog

Si este artículo conecta con una decisión real de producto, Wavect puede ayudarte a definir, construir, endurecer o liderar el trabajo de software con criterio senior de founder.

Rutas de servicio útiles:

Tu bandeja, sin ruido

Sigue el trabajo que te importa

Recibe un correo breve cuando publiquemos algo nuevo. Sigue todo el blog o solo los temas que te interesan.

¿Qué quieres recibir?
Elige tus temas

Gratis, doble opt-in y sin píxeles de seguimiento.

Volver
Kevin Riedl

13 minutos de lectura · 5 nov 2026
Última revisión

Siguiente

Recibe la próxima nota de campo sobre Entrega y QA

Un correo breve cuando publiquemos. Sin píxeles de seguimiento ni contenido de relleno.

Gratis, doble opt-in y sin píxeles de seguimiento.