Sitemap
veera nagaraja sankar Inti

veera nagaraja sankar Inti

Odoo 20 Security Explained: Understanding the New ir.access Model with Examples

6 min readOct 15, 2026

--

From model permissions and record rules to a unified security approach.

Security is a fundamental part of every ERP implementation. In Odoo, it determines who can access customer information, create sales orders, modify invoices, or manage warehouse operations.

With the introduction of the ir.access model in Odoo 20, developers need to understand how security configurations are structured and how existing custom modules may be affected.

In this article, we will explore the concepts using a practical sales-order example, configuration snippets, diagrams, and a migration checklist.

1. Understanding Odoo’s Traditional Security Model

In earlier Odoo versions, access control was primarily managed through two mechanisms.

ir.model.access — Model-level permissions

Controls whether a user can perform these operations on a model:

  • Create
  • Read
  • Update
  • Delete

ir.rule — Record-level restrictions

Controls which specific records a user can access using domain expressions.

For example, a salesperson might have permission to read sales orders but should only see orders assigned to them.

The ACL grants the operation, while the record rule limits the records.

Diagram 1: Traditional security architecture

flowchart TD
A[Odoo User] --> B[ir.model.access]
B --> C{Operation Allowed?}
C -- No --> D[Access Denied]
C -- Yes --> E[ir.rule]
E --> F{Record Matches Domain?}
F -- No --> D
F -- Yes --> G[Access Granted]

This separation works well, but developers must maintain and troubleshoot two sets of security definitions.

2. What Changes with ir.access?

The new security approach brings operation permissions and record-level domains into a unified configuration model.

Instead of defining model access in one place and record filtering in another, developers can express these requirements through an access definition.

The goal is to make security configurations easier to manage while retaining control over which operations and records are accessible.

Diagram 2: Unified security configuration

flowchart TD
A[Odoo User] --> B[ir.access]
B --> C[Operation Permissions]
B --> D[Record Domain]
C --> E{All Applicable Security Conditions}
D --> E
E --> F[Effective Access Decision]

The important distinction is that unifying the configuration does not eliminate the need for careful security design. Developers must still understand group assignments, domain evaluation, and applicable restrictions.

Version note: Verify the availability and exact behavior of ir.access against the specific Odoo 20 source branch you are using before applying these examples in production.

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

3. Example 1: Giving Salespeople Access to Sales Orders

Imagine a company with three salespeople:

UserSales ordersRaviSO001, SO002PriyaSO003, SO004ManagerAll team orders

The business requirement is straightforward:

  • Ravi can access his own orders.
  • Priya can access her own orders.
  • The manager can access all orders within the manager’s permitted scope.

Traditional Odoo configuration

An ACL can grant salespeople read and update permissions:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_order_user,Sale Order User,model_sale_order,sales_team.group_sale_salesman,1,1,1,0

This grants the specified group create, read, and update permissions on the sales-order model. It does not, by itself, restrict users to their own orders.

A record rule can apply that restriction:

<record id="sale_order_own_rule" model="ir.rule">
<field name="name">Own Sales Orders</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="domain_force">
[('user_id', '=', user.id)]
</field>
<field name="groups"
eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
</record>

The domain checks the order's assigned salesperson.

Diagram 3: How record filtering works

flowchart TD
A[Ravi Opens Sales Orders] --> B[Check Model Permissions]
B --> C[Read Operation Allowed]
C --> D[Apply Salesperson Domain]
D --> E{Assigned User Is Ravi?}
E -- Yes --> F[Show Order]
E -- No --> G[Hide Order]

For this example, Ravi sees SO001 and SO002 but not Priya’s orders.

The exact outcome depends on the user’s complete security configuration and the actual records in the database.

4. Example 2: Understanding Operation Permissions

Consider a warehouse employee who should be able to read stock records but must not create or delete them.

In a traditional ACL, the configuration might look like this:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_stock_user,Stock User,model_stock_picking,stock.group_stock_user,1,0,0,0

This grants read permission while denying write, create, and delete through this ACL.

Under the proposed unified format, the equivalent operation representation might be:

id,name,model_id,group_id/id,operation,domain
access_stock_user,Stock User,stock.picking,stock.group_stock_user,r,

Here, r represents read access.

Other common operation combinations are:

OperationMeaningrReadruRead and updatecruCreate, read, and updatecrudCreate, read, update, and delete

These strings illustrate the operation mapping described for the new model. Confirm the supported values and schema against your target Odoo 20 implementation.

5. Example 3: Restricting Access by Company

Multi-company access is especially important in enterprise implementations.

Get veera nagaraja sankar Inti’s stories in your inbox

Join Medium for free to get updates from this writer.

Suppose an organization operates two companies:

  • Company A — India
  • Company B — UAE

Users from Company A should not be able to access Company B’s records unless explicitly authorized.

A traditional record domain might look like this:

[('company_id', 'in', company_ids)]

The exact variables available to a domain depend on the rule evaluation context. This snippet illustrates the business logic rather than a complete, universally valid configuration.

Diagram 4: Company-level data isolation

flowchart TD
A[User from Company A] --> B[Request Business Records]
B --> C[Evaluate Company Restrictions]
C --> D{Record Belongs to an Allowed Company?}
D -- Yes --> E[Access Permitted]
D -- No --> F[Access Restricted]

When migrating company-specific rules, preserve the original scope and verify behavior with users who have access to multiple companies.

Important: A company domain is only one layer of protection. It should be validated alongside model permissions, group membership, and the application’s supported multi-company security mechanisms.

6. How Permissions and Restrictions Interact

A subtle but important part of access control is how multiple rules combine.

Conceptually, the security evaluation can be represented as:

(Permission A OR Permission B) AND Restriction A AND Restriction B

This means that a user may qualify for access through multiple applicable permissions, while mandatory restrictions continue to constrain the final result.

For example:

  • A sales team permission allows access to team orders.
  • A company restriction limits access to the user’s authorized companies.
  • The resulting access must satisfy the applicable security conditions.

Diagram 5: Effective access evaluation

flowchart TD
A[User Requests Record] --> B{Any Applicable Permission Matches?}
B -- No --> C[Access Denied]
B -- Yes --> D{All Applicable Restrictions Satisfied?}
D -- No --> C
D -- Yes --> E[Access Granted]

This is a conceptual illustration, not a replacement for the target version’s exact security evaluation logic.

Developers should test overlapping rules rather than assume that adding a new permission will override an existing restriction.

7. Migrating Custom Modules to Odoo 20

For teams maintaining custom addons, the migration should be handled systematically.

Step 1: Inventory existing security definitions

Find all relevant files and records:

  • security/ir.model.access.csv
  • XML definitions using ir.rule
  • Custom user groups
  • Company-specific domains
  • Integration-user permissions

Step 2: Convert the configuration

Map each existing permission and record rule to the new configuration format supported by the target branch.

Do not perform a blind search-and-replace of model names or filenames.

Step 3: Update the module manifest

If the new security file is named ir.access.csv, update the manifest accordingly:

'data': [
'security/ir.access.csv',
]

Confirm the expected filename and loading order in the actual implementation.

Step 4: Validate the domain

Check that every migrated domain preserves the original business requirements.

Pay special attention to salesperson ownership, company boundaries, warehouse access, and manager permissions.

Step 5: Test each operation

Validate read, create, update, and delete operations independently.

A user who can read a record should not automatically be assumed to have permission to modify it.

Step 6: Test integrations

Verify API users, scheduled jobs, imports, and external integrations under their actual execution identities.

Step 7: Deploy through staging

Complete functional and security regression testing before production deployment.

8. Security Testing Checklist

Use this checklist during migration:

  • Salespeople can access only their permitted orders.
  • Managers have the intended team-level access.
  • Warehouse users have the correct stock permissions.
  • Users cannot access unauthorized company records.
  • Create, read, update, and delete permissions behave as expected.
  • API integrations continue to work under their configured users.
  • Scheduled jobs execute with the intended access rights.
  • Negative tests confirm that restricted records remain inaccessible.
  • Staging validation is completed before production release.
Press enter or click to view image in full size

Conclusion

The introduction of a unified ir.access model represents a significant security configuration change for Odoo developers.

Understanding the relationship between operations, record domains, user groups, and restrictions is essential when maintaining custom modules or upgrading enterprise environments.

The best approach is to start with a clear inventory of existing security definitions, migrate them carefully, and validate the effective access of real users.

Remember: a successful security migration is not simply one that installs without errors. It is one that preserves the intended permissions and prevents unauthorized access to business data.

--

--