Odoo Custom Module Development Part 3 - Security and Access Rights

This is the third article in the Odoo custom module development series.

In Part 2, we created our models and fields. In this article, we will add security so the models can be used by real users in a controlled way.

Security is not optional in Odoo. A model without proper access rights will either be inaccessible or dangerously open.

What we will add

We will create:

  • module category
  • user groups
  • access rights with ir.model.access.csv
  • an example record rule

1. Create a security XML file for groups

Create this file:

estate/security/estate_security.xml

Add the following content:

<odoo>
<record id="module_category_estate" model="ir.module.category">
<field name="name">Estate</field>
<field name="description">Estate application roles</field>
<field name="sequence">30</field>
</record>

<record id="group_estate_user" model="res.groups">
<field name="name">Estate User</field>
<field name="category_id" ref="estate.module_category_estate"/>
</record>

<record id="group_estate_manager" model="res.groups">
<field name="name">Estate Manager</field>
<field name="category_id" ref="estate.module_category_estate"/>
<field name="implied_ids" eval="[(4, ref('estate.group_estate_user'))]"/>
</record>
</odoo>

What this does:

  • creates a dedicated category on the user form
  • creates a normal estate user role
  • creates an estate manager role that automatically includes estate user rights

2. Create the access control CSV file

Create:

estate/security/ir.model.access.csv

Add this content:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_estate_property_user,estate.property.user,model_estate_property,estate.group_estate_user,1,1,1,0
access_estate_property_manager,estate.property.manager,model_estate_property,estate.group_estate_manager,1,1,1,1
access_estate_property_type_manager,estate.property.type.manager,model_estate_property_type,estate.group_estate_manager,1,1,1,1

This means:

  • estate users can read, create, and edit properties, but cannot delete them
  • estate managers can do everything on properties
  • only estate managers can manage property types

3. Load security files from the manifest

Update __manifest__.py and add these files to the data list:

{
'name': 'Estate',
'version': '1.0',
'summary': 'Real estate management training module',
'sequence': 10,
'description': 'Custom training module for learning Odoo development.',
'category': 'Tutorials',
'author': 'Your Name',
'depends': ['base'],
'data': [
'security/estate_security.xml',
'security/ir.model.access.csv',
],
'installable': True,
'application': True,
'license': 'LGPL-3',
}

Order matters here. Load groups before ir.model.access.csv because the CSV references those groups.

4. Upgrade the module

Run:

cd ~/odoo-dev/odoo
source .venv/bin/activate
python3 odoo-bin -c ~/odoo-dev/odoo.conf -d odoo19 -u estate --stop-after-init

If the CSV or XML contains invalid references, Odoo will fail during module upgrade.

5. Assign users to groups

In Odoo:

  1. Open Settings.
  2. Open Users & Companies > Users.
  3. Open a test user.
  4. Under access rights, assign either Estate User or Estate Manager.

Using separate test users is strongly recommended. Do not test everything with the administrator account because admin bypasses many practical permission scenarios.

6. Add a simple record rule

Access rights decide what operations a user can perform on a model. Record rules decide which records they can access.

Create another file:

estate/security/estate_rules.xml

Add this rule:

<odoo>
<record id="estate_property_rule_user_visibility" model="ir.rule">
<field name="name">Estate properties visible to estate users</field>
<field name="model_id" ref="model_estate_property"/>
<field name="groups" eval="[(4, ref('estate.group_estate_user'))]"/>
<field name="domain_force">[]</field>
</record>
</odoo>

This rule does not restrict anything yet because the domain is empty, but it gives you a correct starting point for understanding the structure of a record rule.

Add it to the manifest after the groups file:

'data': [
'security/estate_security.xml',
'security/estate_rules.xml',
'security/ir.model.access.csv',
],

Upgrade the module again.

7. When to use ACLs and when to use record rules

Use access rights when you want to answer:

  • can this group read this model?
  • can this group create records on this model?
  • can this group delete records on this model?

Use record rules when you want to answer:

  • which records can this user see?
  • which records can this user edit?

They solve different problems and are often used together.

8. Common security mistakes

Putting everyone in the same powerful group

This defeats the purpose of role-based access control. Keep user and manager roles separate.

Forgetting to load the security files in the manifest

If the files are not in data, Odoo will never load them.

Wrong XML or CSV order in the manifest

Referenced records must be loaded before the file that uses them.

Testing only with admin

The administrator account can hide real security problems. Always test with a non-admin user.

9. Safe next steps

As the module grows, you can add more restrictive rules, for example:

  • agents only see properties assigned to them
  • only managers can delete sold properties
  • some fields are only visible to managers

Odoo also supports field-level group restrictions when needed.

Final words

Your module now has a basic but correct security layer.

In the next article, we will make the module usable by adding menus, actions, list views, and form views.

Previous article: Part 2 - Models and Fields

Next article: Part 4 - Menus, Actions, and Views

Related posts

Md. Monirul Alom

Md. Monirul Alom

I am a Full Stack Web developer. I love to code, travel, do some volunteer work. Whenever I get time I write for this blog