Odoo 20 Security Redefined: From Record Rules to Unified Access Control (ir.access)

A comparison graphic showing the transition from Odoo 19 to Odoo 20 unified access control, moving from combined ACL and Record Rules to a single ir.access system combining Model, Permission, Domain, and Group.

Odoo 20 introduces a major change in how access rights are defined and evaluated.

If you’ve worked with Odoo 19 or earlier, you already know the traditional security model:

  • Model-level permissions using ACLs (ir.model.access)
  • Record-level filtering using Record Rules (ir.rule)
  • Separate security definitions that can sometimes be difficult to debug

With the new security architecture, Odoo brings these concepts together using a single model:

ir.access

๐Ÿ”ฅ What Changed in Odoo 20?

Previously:

  • ir.model.access โ†’ Can the user access this model?
  • ir.rule โ†’ Which records can the user access?

Now:

  • ir.access โ†’ Model + CRUD operations + record domain + optional group

The new security definitions are primarily maintained through:

security/ir.access.csv

๐Ÿง  Understanding the Old Model

Before Odoo 20, security was split between ACLs and Record Rules. For example:

ACL:

Create = Yes
Read = Yes
Write = Yes
Delete = No

And a Record Rule could restrict the records:

[('user_id', '=', user.id)]

So the user could access the model, but only their own records.

๐Ÿš€ New ir.access Model

The same logic can now be defined together:

crm_rule_personal_lead,Personal Leads, crm.lead,sales_team.group_sale_salesman,cru,"['|',('user_id','=',user.id),('user_id','=',False)]"

This defines:

  • Model: crm.lead
  • Group: Salesperson
  • Operation: cru
  • Domain: user_id = current user

So the salesperson can:

  • Create leads
  • Read leads
  • Update leads
  • Access only their own leads

๐Ÿ”„ What Happened to CRUD?

The old ACL format used separate fields:

  • perm_read
  • perm_write
  • perm_create
  • perm_unlink

The new operation field combines them.

Old ACL New operation
perm_create c
perm_read r
perm_write u
perm_unlink d

For example:

cru

means:

Create + Read + Update

while:

crud

means full CRUD access.

๐Ÿ”„ What Happened to R?

Previously, a Record Rule could look like:

<record id="crm_rule_personal_lead"
    <field name="name">Personal Leads</field>
    <field name="model_id" ref="model_crm_lead"/>
    <field name="groups"
        eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
    <field name="domain_force">
        ['|',('user_id','=',user.id),('user_id','=',False)]
    </field>
</record>

In the new structure, the domain becomes

crm_rule_personal_lead,Personal Leads,crm.lead,sales_team.group_sale_salesman,cru,"['|',('user_id','=',user.id),('user_id','=',False)]"

So instead of maintaining:

ACL + Record Rule

the access definition contains:

Model + Group + Operation + Domain

๐Ÿง  Field Mapping

Odoo 19 Odoo 20 Meaning
ir.model.access ir.access Model access
ir.rule ir.access Record access
model_id model_id/id Model
groups group_id/id Security group
perm_create operation = c Create
perm_read operation = r Read
perm_write operation = u Update
perm_unlink operation = d Delete
domain_force domain Record filter

๐Ÿš€ Need Help Migrating Odoo 19 to Odoo 20?

Planning an Odoo 19 โ†’ Odoo 20 migration

We can help with:

  • Custom module migration
  • ir.model.access โ†’ ir.access
  • ir.rule migration
  • Python/API changes
  • XML & view migration
  • Migration testing and bug fixing

WhatsApp: +91 77779 09289

Email: info@codespheretech.in

๐Ÿ“ฉ Contact us if you want help reviewing custom Odoo 19 modules to Odoo 20.