Security is a vital component in any ERP system. In the case of Odoo ERP, there are numerous users who work with business information like sales orders, invoices, products, and employees. It is important to ensure that users can only work with the relevant business information. This is done using a security feature in Odoo known as Access Control Lists (ACLs).
The main purpose of using ACLs in Odoo is to ensure that users can work with specific models and can perform specific actions on those models. It is important to ensure that ACLs are implemented correctly in any system for the sake of integrity.
In this article, we will discuss some of the best practices that developers should always consider when working with ACLs in Odoo.
Understanding ACLs in Odoo
In Odoo, the Access Control Lists determine if the user is allowed to read, write, create, or delete data on the model.
The Access Control Lists are configured in the file:
security/ir.model.access.csv
Each entry in this file defines the permissions for a given security group on the model.
Example:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_student_user,student.user,model_student,base.group_user,1,1,1,0
In this example:
- Users in base.group_user can read, write, and create records.
- They cannot delete records because perm_unlink is set to 0.
This allows developers to precisely control how users interact with the model.
Always Assign ACLs to Security Groups
ACLs should always be assigned to specific security groups rather than being left open.
The bad practice in this code is that ACLs are not assigned to specific security groups:
access_student,student,model_student,,1,1,1,1
The group_id field should not be left empty, as this access will be granted to all users, including the public user.
It should be assigned to the group.
Example group definition in security.xml:
<record id="group_student_user" model="res.groups">
<field name="name">Student User</field>
</record>
Then reference this group in the ACL file:
access_student_user,student.user,model_student,my_module.group_student_user,1,1,1,0
This ensures that only users belonging to that group receive the permissions.
Follow the Principle of Least Privilege
When setting access rights, users should only be granted the rights they actually need.
For instance, an employee may only need to read and update records. However, if he or she is also given the right to delete, he or she may accidentally delete important business data.
A better ACL setting may be:
access_employee_record,employee.record,model_employee_record,base.group_user,1,1,1,0
In this setting, users are allowed to read, edit, and create records, but not delete them.
If managers require additional privileges, you can define a separate ACL:
access_employee_record_manager,employee.record.manager,model_employee_record,my_module.group_manager,1,1,1,1
This way, only managers can delete records.
Combine ACLs with Record Rules
This is because ACLs can only be used to restrict access to models. However, in some cases, one might need to restrict access to specific records. For instance, employees should be restricted to viewing their records only.
This can be done by using record rules.
Example record rule:
<record id="employee_own_record_rule" model="ir.rule">
<field name="name">Employee Own Records</field>
<field name="model_id" ref="model_employee_record"/>
<field name="domain_force">[('user_id','=',user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
This rule ensures that users only see records where the user_id matches the logged-in user.
Using ACLs together with record rules provides much stronger access control.
Keep Security Files Organized
Security configuration should be structured clearly inside the module.
A typical module structure looks like this:
my_module/
¦
+-- models/
+-- views/
+-- security/
¦ +-- ir.model.access.csv
¦ +-- security.xml
The security.xml file is usually used to define groups and record rules, while ir.model.access.csv defines the ACL permissions.
Keeping security logic in one place makes the module easier to maintain.
Avoid Hardcoding User IDs in Security Logic
Developers sometimes write conditions using specific user IDs, which is not recommended.
Bad example:
if self.env.uid == 2:
# allow action
This approach is fragile because user IDs may change across databases.
Instead, check user groups.
Better approach:
if self.env.user.has_group('my_module.group_manager'):
# allow actionUsing groups ensures the code remains flexible and maintainable.
Test Access Rights Thoroughly
Having set up the ACLs and the rules for the records, the next thing that is of great importance is the testing.
It is essential to test the functionality with different user roles.
It is also essential to set up different users and assign them different roles, then check if the users are able to access the models and perform the actions.
It is also essential to activate the developer mode and then check the Access Rights on the user form.
Access Control Lists are a key feature of the overall security infrastructure of Odoo. Access Control Lists are essentially a list of users who have access to a certain model, as well as the operations that the users can perform on the model.
If Access Control Lists are configured correctly, it becomes possible to safeguard sensitive information of the business, as well as ensure that users are only allowed to access the parts of the system that are relevant to them.
By correctly configuring Access Control Lists, assigning Access Control Lists to security groups, and ensuring that the Access Control Lists are configured according to the principle of least privilege, as well as combining Access Control Lists with record rules, it becomes possible to create a secure and stable Odoo application.
The configuration of the overall security infrastructure of the application is crucial, as it can help improve the stability of the application.
To read more about Overview of Access Control Lists (ACLs) in Odoo 19, refer to our blog Overview of Access Control Lists (ACLs) in Odoo 19.