Quick Answer
Odoo security has 4 layers: Groups define who users are, Access Rights (ACL) control CRUD operations on models, Record Rules filter which specific records are visible, and Field-Level Security hides sensitive fields. Always follow "Least Privilege"—users see only what they need.
Introduction: Why ERP Security is Non-Negotiable
Imagine this: A sales intern accidentally views everyone's salary. A warehouse worker deletes critical inventory records. A competitor gets access to your product costs.
Security in an ERP is not optional.
One wrong click can expose sensitive payroll data or allow a junior employee to delete a critical customer record. As a Sysadmin or IT Lead, your job is to build a "Least Privilege" environment—where users see exactly what they need to do their job, and nothing more.
This guide decodes the three layers of Odoo Security: Groups, Access Rights (ACL), and Record Rules, ensuring your database remains secure without blocking productivity.
Layer 1: Security Groups (The "Who")
The Foundation of Access.
Odoo manages permissions via Groups. A user belongs to a group, and the group has rights. Never assign rights to a specific user directly.
Best Practice Strategy:
✓ Use Standard Groups First: Odoo comes with "User" and "Administrator" groups for almost every app (Sales, Accounting, Inventory). Use these before creating custom ones.
✓ Inheritance: Groups can inherit rights. Example: The "Sales Manager" group inherits everything from the "Sales User" group, plus extra power.
How to Create a Custom Group
If the standard groups don't fit your needs (e.g., you need a "Billing Only" accountant), create a custom group:
| Step | Action |
|---|---|
| 1 | Activate Developer Mode: Go to Settings → General Settings → Activate Developer Mode |
| 2 | Navigate to Groups: Go to Settings → Users & Companies → Groups |
| 3 | Create New Group: Click "Create" and name it (e.g., "Invoice Viewer") |
| 4 | Add Users: In the "Users" tab, add the employees who belong to this group |
Layer 2: Access Rights (ACL) (The "What")
Access Control Lists (ACL) are the most basic permission: Can this group see this model?
An ACL defines the CRUD permissions:
C
Create
Add new records
R
Read
View records
U
Update
Edit records
D
Delete
Remove records
⚠️ Important Rule: If a user belongs to any group that has "Read" access to the account.move model (Invoices/Bills), they can read ALL invoices and bills, regardless of who created them.
How to Configure an Access Right
| Step | Action |
|---|---|
| 1 | Navigate to Access Rights: In the Groups form (e.g., your "Invoice Viewer" group), go to the Access Rights tab |
| 2 | Add a New Rule: Click "Add a line" |
| 3 | Define Model: Select the target model (e.g., account.move for Invoices) |
| 4 | Set Permissions: For "Invoice Viewer," check only the Read permission |
✅ Result: Users in this group can now view all invoices, but they cannot create new ones, edit existing ones, or delete any.
Layer 3: Record Rules (The "Which")
Record Rules are the most powerful layer. They restrict which specific records within a model a group can see.
ACL says:
"You can read Invoices."
Record Rule says:
"You can read only Invoices where the Customer is in your Sales Territory."
Record Rules are applied as a Domain (a filter) to all database queries.
Example: Limiting Sales Reps to Their Own Opportunities
Goal: A Sales User should only see Opportunities/Leads assigned to them. They should not see their colleague's pipeline.
| Step | Action |
|---|---|
| 1 | Activate Developer Mode |
| 2 | Navigate to Record Rules: Settings → Technical → Security → Record Rules |
| 3 | Create New Rule: Click "Create" |
| 4 | Rule Name: Sales: Only My Opportunities |
| 5 | Model: crm.lead |
| 6 | Apply to Groups: Select the "Sales / User" group |
| 7 | Domain (The Filter): Set the domain filter |
[('user_id', '=', user.id)]
💡 Explanation: user.id is a dynamic variable that grabs the ID of the currently logged-in user. The domain ensures only records where the user_id field matches the logged-in user's ID are visible.
✅ Result: The Sales User's opportunity pipeline shrinks to only their assigned deals, securing the rest of the company's data.
Layer 4: Field-Level Security (Hiding Data)
Sometimes, you want a group to see a record (e.g., a Product Card) but hide one specific, sensitive field (e.g., the cost price).
Method A: Odoo Studio (No Code)
Goal: Hide the "Cost Price" field from Sales Managers.
| Step | Action |
|---|---|
| 1 | Open the View: Navigate to the Product form |
| 2 | Open Studio: Click the Studio icon |
| 3 | Click on the "Cost" field |
| 4 | In the sidebar, check "Limit visibility to groups" |
| 5 | Select the group that should see it (e.g., "Purchase Managers") |
💡 Least Privilege Note: You select the group that should see the field. If you select Purchase Managers, only users in that group will see it. The field vanishes for everyone else.
Method B: Python (For Developers)
Add the groups attribute to the field in XML:
<field name="standard_price" groups="base.group_system"/>
✅ Result: This hides the cost price for everyone except the Super Admin (base.group_system).
Security Layers Quick Reference
| Layer | Question | Controls | Example |
|---|---|---|---|
| Groups | Who is this user? | Role assignment | Sales User, Manager |
| ACL | What can they do? | CRUD on models | Read invoices, no delete |
| Record Rules | Which records? | Domain filters | Only my opportunities |
| Field Security | Which fields? | Visibility toggle | Hide cost price |
Frequently Asked Questions
Can I reset access rights to default?
Yes. If you mess up, you can simply upgrade the base module (e.g., sale_management). This reloads the standard security XML files and restores the default groups and rules.
What is the "Superuser" (ID 1) risk?
The Administrator (ID 1) bypasses ALL record rules and access rights. You should never use this account for daily operations. Create a separate "System Admin" user with normal admin rights for daily work.
How do I audit who changed a permission?
Enable "Audit Logs" (Enterprise feature or third-party module). Odoo tracks changes to the "Groups" and "Access Rights" models, so you can see if an employee elevated their own privileges.
What's the difference between global and per-group record rules?
Global rules (no group assigned) apply to ALL users and are AND-combined. Per-group rules only apply to users in that group and are OR-combined with other per-group rules. Use global rules sparingly.
Can record rules affect performance?
Yes. Complex domain filters on large tables can slow down queries. Always test record rules on a staging database with production-like data volumes. Index the fields used in your domain filters.
Conclusion: "Least Privilege" is Best
Security is a balance between protection and friction. Too much security, and people can't do their jobs. Too little, and you risk a data breach.
Start with Odoo's standard groups. Only customize when a specific business risk demands it.
Worried Your Database is Exposed?
Let Braincuber's security experts run a penetration test on your Odoo configuration. We'll identify vulnerabilities and lock down your system.
Schedule a Security & Permission Audit
Get a comprehensive review of your Odoo access rights, record rules, and security groups. We'll find the gaps before hackers do.
Comprehensive audit • Penetration testing • Lock it down
