Ecosire Access Management
This is the installation and configuration guide for Ecosire Access Management. Everything on this page describes the ecosire_access_management module exactly as it ships today — the facts below were read out of the released build, not from a roadmap.
| Technical name | ecosire_access_management |
| Odoo versions | 19.0 (Community or Enterprise) |
| Current shipped version | 19.0.1.9.2 |
| Price | $499 USD — one-time, per Odoo version |
| Odoo module licence | OPL-1 |
| Category | Technical / Access Rights |
| Depends on | base, web, mail |
Ecosire policies can only remove access. Existing Odoo ACLs, groups and record rules stay authoritative — nothing here can grant a permission that native Odoo denies. That is the whole safety model, and break glass respects it too.
Requirements
| Requirement | Detail |
|---|---|
| Odoo | 19.0, Community or Enterprise. Self-hosted or Odoo.sh — Odoo Online (SaaS) cannot install third-party modules |
| Odoo apps | base, web, mail — Odoo installs any that are missing |
| Python packages | None beyond a standard Odoo install |
| Recovery administrators | At least two users who are genuine Odoo system administrators (base.group_system) |
Installation
- Copy the
ecosire_access_managementfolder into your Odoo addons path. - Restart Odoo, then update the apps list.
- Search for Ecosire Access Management and install it.
Before you write your first policy, designate your recovery administrators (see Break-glass recovery). The module refuses to put a policy live while fewer than two capable recovery administrators exist — that check is what stops you locking yourself out.
Roles
| Group | What it can do |
|---|---|
| Access Governance Approver | Validate and approve submitted policy versions |
| Access Governance Administrator | Everything an approver can do, plus author policies and manage configuration |
| Protected Access Recovery Administrator | Additionally participates in break-glass recovery |
The author of a version can never be its approver. That separation is enforced on the server, not just hidden in the interface.
Authority is re-checked at every transition
Holding the record role is not enough at the moment you act — the module re-checks that you still hold the Access Policy Author or Access Governance Administrator group at the point of every governed transition (submitting a policy version or role assignment, submitting an internal API route, submitting, applying or rolling back a workforce event, and opening or closing a certification review).
This closes a small but real gap: a user whose group was revoked still matches the record's
author or approver field, and a browser tab opened before the revocation still shows the
buttons. Now the transition itself refuses.
The policy lifecycle
A policy is never edited in place. Each change creates a version that moves through a fixed path:
- Draft — the author adds deny rules and subjects.
- Submitted — the version becomes immutable and is fingerprinted with a content hash.
- Validated — preflight checks run and record their evidence.
- Approved — an independent approver signs off.
- Live — the version takes effect and a receipt is written.
If the content changes after approval, the hash no longer matches and the version cannot go live. You resubmit it for review instead.
Rollback returns the policy to the exact previous version and restores prior group membership precisely. It reuses the same approval path, so a rollback is as auditable as a rollout.
What you can deny
| Deny type | Covers |
|---|---|
| Model CRUD | Create, read, write, unlink on a model |
| Field | Read or write on a single field |
| Record condition | A domain that narrows which records are covered |
| Method / button | Web dataset calls and object buttons |
| Chatter | Reading or posting messages |
| Menu | Hiding a menu also blocks loading or running its linked action |
| Action, view, report | Server-side denial of the corresponding request |
| Import / export | Checked before the write, and on exported values |
A field-read deny removes the field from form and list architecture, from metadata, and from supported export values. Archive, duplicate, delete, chatter and direct button requests are all enforced on the server and preserve denied business state.
Method and button enforcement covers Odoo web dataset calls. XML-RPC, JSON-2 and direct server-side ORM calls are deliberately not claimed by this build. If you need those covered, treat it as a separate requirement rather than assuming it works.
Typed masking
Masking applies on supported read, export and standard QWeb report paths. It is typed — a masked date stays a date and a masked number stays a number — so downstream views and reports keep rendering instead of breaking on a placeholder string.
Multi-company
Policies are company-scoped. Every governed model carries a record rule, so a policy written in one company never evaluates against another company's records or users.
Separation of duties, and joiner / mover / leaver
Conflict packs describe combinations of governed roles that must not coexist. A submission that would breach one is either blocked outright or requires an attributable, digest-bound risk acceptance — there is no silent override.
Workforce events (joiner, mover, leaver) apply only the governed role changes they declare, and leave unrelated native groups untouched. Each event is independently approved.
Temporary access and what happens when a revocation fails
A governed role assignment can carry an expiry. Expiry is enforced at request time — the moment the user acts, an elapsed grant no longer applies — and a scheduled worker (Ecosire Access: Reconcile Expired Temporary Access) then reconciles the records so the history is accurate.
That worker processes one grant at a time, in its own transaction savepoint. If one record cannot be revoked, only that record is left alone: every other expired grant in the same run is still revoked. This matters more than it sounds — an uncontained worker would abort on the first bad record and silently leave every later expired grant active until the next tick.
When a revocation does fail, you are told. The module schedules a To-Do activity on your Access Governance Administrators, naming the role, the user and the reason it failed. The activity is deduplicated per grant and per administrator, so a problem that repeats every tick produces one open item rather than a flood.
Where to look: the activity appears in the administrator's Odoo activity list, on the governed role assignment itself. Resolve the underlying cause, then either re-run the scheduled action or revoke the assignment manually; the activity is yours to close.
The commonest cause of a failed revocation is a group or user record that another customisation has made read-only. If several activities appear at once, look for a shared cause before treating them individually.
Before-and-after comparison
The comparison screen is read-only and subject- and company-aware. It names what becomes newly allowed, what becomes newly denied, and what stays denied — so you can see the effect of a version before it goes live rather than discovering it afterwards.
Break-glass recovery
Break glass exists so a mistaken policy cannot permanently lock out administration.
- Both participants must be designated recovery administrators and genuine Odoo system administrators.
- The two participants must be different people.
- A reason is mandatory, and the session lasts at most one hour.
- Expiry is enforced at request time, and both the start and the expiry are immutable audit events.
Break glass bypasses Ecosire overlay denies only. It never grants a permission that native Odoo ACLs, groups or record rules already deny.
Governed uninstall
Uninstall stays blocked until an administrator downloads and explicitly confirms a digest-bound, database-wide governance recovery package. That is deliberate: it guarantees you can reconstruct who could do what before the governance layer is removed.
Audit integrity
Every material action appends a hash-chained audit event. Verification detects application-level mutation of that chain.
Audit verification is not presented as protection against a database administrator with direct SQL access. It detects tampering through the application, which is a different and narrower guarantee.
Activation failures are recorded too. A failed rollout rolls back every governed write it made, so the attempt is written through an independent connection that commits separately — otherwise a failed activation would leave no trace at all.
HTTP endpoints
This module does not add a public API for you to integrate with. It overrides existing Odoo endpoints so that governed denials are enforced on the server rather than only in the browser, and adds two of its own.
| Endpoint | Auth | Why the module touches it |
|---|---|---|
/web/dataset/call_kw | user | Enforces model, field, method and record denies on ORM calls |
/web/dataset/call_kw/<path:path> | user | Same route with the path form used by the web client |
/web/dataset/call_button | user | Enforces button/method denies |
/web/dataset/call_button/<path:path> | user | Same route with the path form used by the web client |
/web/action/load | user | Blocks loading an action whose menu is denied |
/web/action/run | user | Blocks running a denied action |
/mail/thread/messages | user | Applies chatter read denies |
/mail/message/post | public | Applies chatter write denies. This is Odoo's own route and keeps Odoo's public auth — the module adds a denial check, it does not widen who may reach it |
/ecosire/access/api/invoke | user | The single governed ingress described below |
/ecosire/access/request/guidance | user | Returns the fixed, translated "ask a reviewer" payload shown to a denied user. It never returns policy structure |
The governed ingress
/ecosire/access/api/invoke accepts independently approved keys and dispatches only to a fixed set of built-in handlers, each scoped to a native group. It cannot be pointed at arbitrary models or methods — the handler list is part of the build, not configuration.
Troubleshooting
A user still sees data I denied. Confirm the version is live, not merely approved, and that the policy's company matches the user's active company. A version that is approved but not live has no effect by design.
I cannot put a policy live. The preflight refuses while fewer than two capable recovery administrators exist. Designate them first.
Break glass is refused. Both participants must hold base.group_system in addition to being designated. Designation alone is not enough.
A denied user is confused. Point them at the guidance panel. It deliberately tells them who to ask without revealing which rule denied them.
Support
- Documentation: docs.ecosire.com
- Email: [email protected]