Odoo Developer Guide: Data Security & Access Controls in Odoo
Odoo Developer Guide: Data Security & Access Controls in Odoo Blogs September 14, 2026 Moossa M. Alavi Technical Analyst at Techbot ERP Moossa M. Alavi is the Founder & CEO of Techbot ERP and Altamyz Advertising. He is a certified Odoo consultant with more than 27 years of experience in business, advertising, and ERP software. Moossa started his career in the UAE in 1997 with a well-known group in Abu Dhabi. Over the years, he built his own companies to help other businesses work better using technology. Moossa helps with customized ERP implementation for various industries, including manufacturing, insurance, supercar rental, and logistics, through Techbot ERP. He resolves these issues with Odoo ERP and supports businesses in growing with the right assets and guidance. Moossa has received many awards for his work, including the Arabian Best of Best Award and the Industry Leader Award from BNI UAE. He is also a BNI Ambassador and mentors other business owners. He believes in giving back to the community and helping others grow, following the “Givers Gain” principle. About This Guide This guide breaks down how Odoo protects your data and controls user permissions across your business. It explains how roles, permissions, and security rules work together to ensure employees only see and manage the specific records they need—keeping your business information safe and organized. What You Will Learn User Roles & Access Control: How to set up job roles and assign specific read, edit, or delete permissions across your business modules. Row-Level Security: How to automatically restrict record visibility so users only view data relevant to their role or branch. Field Privacy: How to hide sensitive information (like private medical notes or financial data) from unauthorized team members. Best Practices: How to avoid common configuration mistakes and keep your overall system safe from unintended access. Odoo provides two main data-driven mechanisms to manage or restrict access to data without writing custom hardcoded logic. Both mechanisms link to users through User Groups (res.groups): a user belongs to any number of groups, and security mechanisms are attached to groups to govern permissions. This guide provides a comprehensive breakdown of Odoo security architecture using a Hospital Management (custom_hospital_management) module as an example. Group Architecture (res.groups) User groups define roles and serve as the foundation for both Access Rights and Record Rules. Model Attributes (res.groups) tname: Serves as user-readable identification for the group (spells out the role or purpose of the group, e.g., “Doctor”, “Patient Administrator”). category_id: The module category. Associates groups with an Odoo App (a set of related business models) and converts them into an exclusive selection box on the User setup form. implied_ids: Other groups to assign to the user alongside this one. This acts as a convenience pseudo-inheritance relationship (e.g., a “Hospital Manager” group implies the “Hospital User” group). It remains possible to explicitly remove implied groups from a user without removing the main group. comment: Additional technical notes or descriptions detailing the purpose of the group. Access Rights (ir.model.access) Access Control Lists (ACLs) grant access to an entire model for a given set of operations (Create, Read, Update, Delete). If no access right matches an operation on a model for a user (through their assigned groups), the user is denied access. Core Properties Additive Nature: Access rights are cumulative. A user’s total access is the union of access rights from all groups they belong to.Example: If Group A grants Read and Create, and Group B grants Update, a user in both groups has Read, Create, and Update access. Default Behavior: Unmatched operations default to denied access. Model Attributes (ir.model.access) name: Descriptive purpose or role of the access control record. model_id: The target model whose access the ACL controls (formatted as model_<model_name_with_underscores>). group_id: The res.groups record to which access is granted. Leaving group_id empty grants access to every user (including non-employees such as portal or public users). CRUD Attributes (perm_*): Grant the corresponding operation when set to 1 (True). All permissions are unset (0 / False) by default: perm_read: Read/View records. perm_create: Create new records. perm_write: Modify existing records. perm_unlink: Delete records. Implementation Example: Hospital Management File location: custom_hospital_management/security/ir.model.access.csv Code snippet id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_hospital_patient_user,access.hospital.patient.user,model_hospital_patient,base.group_user,1,1,1,0 In this configuration, standard internal users (base.group_user) can Read, Write, and Create patient records (hospital.patient), but cannot Delete (perm_unlink = 0) them. Record Rules (ir.rule) Record rules are row-level conditions evaluated record-by-record after Access Rights pass. While Access Rights grant access to the table, Record Rules filter which individual rows inside that table a user can see or modify. Core Properties Default-Allow: If Access Rights grant permission and no record rule applies to the operation/model for the user, access is allowed. Operation Selection: Unlike ir.model.access, setting perm_* flags on an ir.rule determines which operations the rule actively filters. If an operation is unset (False), the rule ignores that operation and permits it freely. All operations are selected (True) by default. Model Attributes (ir.rule) name: Description of the rule. model_id: The model to which the rule applies. groups: The res.groups to which the rule applies. If no group is specified, the rule is marked as Global. global: Computed field indicating whether the rule applies globally across all users. domain_force: A domain predicate (Python expression). Records matching the domain are allowed; non-matching records are forbidden. CRUD Operation Flags: perm_read, perm_write, perm_create, perm_unlink. Available Domain Evaluation Context When writing expressions inside domain_force, Odoo provides the following evaluation variables: user: The current user record (as a singleton recordset). company_id: The user’s currently active company ID (integer). company_ids: All company IDs accessible to the user (list of integers). time: Python’s native time module. Global Rules vs. Group Rules Rule Type Composition Behavior Technical Rule Global Rules (groups empty) Intersection (AND) Adding global rules always restricts access further. All global rules must be satisfied simultaneously. Group Rules (groups specified) Unification (OR) Adding group rules expands access. If any group rule matches, access is granted. Combined Evaluation Intersection (AND) Global rulesets and Group rulesets intersect. The user must pass ALL Global rules AND at
