User Guide
How to use Restrict Delete & Export, screen by screen.
Where it lives
Settings → Access Restrictions
Two entries: Restriction Rules (what is restricted) and Blocked Attempts (who was refused).
It sits inside Settings rather than as its own app because it is configured once and then left alone.
Creating your first rule
The most common one, and a good place to start: stop people deleting contacts.
- Restriction Rules → New
- Model: Contact
- Tick Delete
- Allowed groups: add Contact Creation (or whichever group should keep the right)
- Message: > Contacts are not deleted. Archive the contact instead, or ask a Contact > Manager if it really must go.
- Save.
That is it. Anyone outside the allowed groups now sees your message instead of deleting a contact, and every attempt is recorded.
Choosing what to restrict
| Operation | Restrict it when |
|---|---|
| Delete | Records must be kept for audit, accounting or history |
| Export | The data should not leave in bulk — customers, employees, prices |
| Documents carry pricing or terms not everyone should circulate | |
| Archive | People archive to hide records they were told not to delete |
| Duplicate | Copying creates near-identical records that corrupt reporting |
Each is independent. Restricting delete does not restrict anything else.
Archive deserves attention. Block delete alone and users archive instead — it looks the same to them and the record leaves the list. If your intent is "this record stays visible", tick both.
Choosing who is allowed
This is an allow-list: once a rule restricts an operation, only the listed groups and users may perform it.
Prefer groups over users. A user list becomes stale the moment someone changes role. Use the user list for genuine one-offs — the person covering a leave, the consultant with a two-week engagement.
An empty allowed list means nobody, except those who bypass restrictions entirely. That is legitimate for records that should truly never be deleted by anyone.
Writing the message
The message is the whole user experience of this module. A good one says what to do instead:
Good: "Invoices are never deleted. Credit-note it instead — Accounting → Customer Invoices → Add Credit Note."
Bad: "Access Denied."
The second one produces a support ticket. The first does not.
Two placeholders are available: %(verb)s becomes the operation, %(model)s becomes the model name. A typo in a placeholder is safe — the message is shown as written rather than raising an error.
Leave it empty for the default, which names the operation and the model and tells the user where to ask.
Reading the blocked-attempt log
Blocked Attempts shows who was refused, when, which operation, which records, and from which address.
The most useful thing to do with it is group by user. Then ask:
- One person, many blocks, same rule — they have a legitimate need the rule does not cover. Add their group, or add them as a user exception.
- Many people, same rule — the rule is too broad. Reconsider it.
- One person, many rules — either they are exploring, or their role changed and their groups did not.
- Nothing at all — either the rule is working as a deterrent, or nobody ever wanted to do that thing. Both are fine.
A rule that blocks the same person ten times a day is usually a rule that is wrong, not a person who is wrong.
Settings
Settings → Access Restrictions
| Setting | Default | Meaning |
|---|---|---|
| Enable Restrictions | On | Master switch. Turn off to check whether a refusal came from this module. |
| Settings Users Bypass | On | Anyone in the Settings group ignores every restriction. |
| Log Blocked Attempts | On | Global switch; each rule also has its own. |
| Keep Attempts For | 180 days | 0 keeps them indefinitely. |
About the Settings bypass
On by default because an administrator who cannot delete a test record on their own database is an administrator who uninstalls the module.
Turn it off only once you are certain your own account is on the allowed list of the rules you need. The superuser bypass remains either way, so the database is never unrecoverable — but recovering may mean shell access.
When something is unexpectedly blocked
- Is it this module? The message will be yours, or the module's default mentioning Access Restrictions. Odoo's own "You are not allowed to modify this document" is a different thing — that is access rights, not this.
- Check Blocked Attempts. The refusal will be there with the rule that caused it.
- Open the rule. Is the user's group on the allowed list?
- Still puzzling? Turn off the master switch briefly. If the operation then works, it was this module; if not, look at Odoo's access rights.
When something is unexpectedly not blocked
- Is the rule active? Archived rules are hidden by default.
- Is the master switch on?
- Is the user in the Settings group? They bypass by default.
- Is it the superuser? Always bypasses, by design.
- Is it an export through something other than the standard button? The API and custom controllers are not covered — see the limitations in the README.
A sensible starting configuration
For most businesses, three rules cover the majority of the risk:
| Model | Restrict | Allowed |
|---|---|---|
| Contact | Delete, Archive | Contact Creation group |
| Invoice | Delete | Accounting Manager |
| Product | Delete, Export | Inventory Manager |
Add export restrictions to Contact once you have watched the blocked-attempt log for a week and know who genuinely exports.
Start narrow. A restriction that blocks real work gets switched off entirely, and then you have nothing. One rule that sticks is worth five that get reverted.