Security
What AI Assistant for Odoo can read and write, what it stores, and what leaves your instance.
The design in one paragraph
Every read goes through env[model].with_user(the person asking). Enforcement is Odoo's own model access and record rules - the same code that protects the web client. There is no privileged query path in this module and none can be added from configuration.
The two boundaries
Exposure is the outer one: company-wide, set by a manager, empty on install. It says which models are in scope at all.
The asking user's own access rights are the inner one, and they are authoritative.
Both exist because "they may read it" and "it may leave the building" are different decisions. An accountant can read your user list; that is no reason for a question about invoices to ship it to a model vendor. Exposure is a data-egress decision. Access rights are a permission decision.
What is never sent to a vendor
Regardless of configuration:
- fields whose name contains password, passwd, secret, token, api_key, apikey, private_key, access_key, credential, otp, totp, session, signature
- binary and image fields
Query safety
A language model composes the filter arguments, so they are validated before a query is built:
- Operators are an allow-list. inselect and not inselect take raw SQL and are not on it.
- No dotted field paths. A join walks into another model whose record rules are not reliably applied to it, so the whole form is refused rather than judged case by case.
- No filtering or sorting on a field you cannot read. password like 'a%' would otherwise be an oracle.
- A hard row ceiling above whatever an exposure permits.
Read-only by construction
There is no write, create, unlink or method call in the tool layer. An assistant that can act on an ERP is a different product with a different risk profile.
The API key
Stored in Odoo's encrypted ir.config_parameter store, written only by a system administrator through a transient wizard, and never displayed again.
No field on any model in this module holds it, and test_no_field_on_any_model_holds_the_key asserts that across every model the module defines - so a later release that adds a convenient api_key field somewhere fails the build rather than a customer's backup.
The audit trail
Every tool call is recorded: model, operation, record ids, count, duration, and refusals. A refusal is the enforcement working and is kept for exactly that reason. Tool calls and messages are immutable through the UI.
What leaves your server
Only what a tool returned, and only to the vendor you configured. On the simulated provider, nothing leaves at all - which is the honest way to evaluate the module before choosing a vendor.
Reporting a vulnerability
info@technovision.dev. Please include the Odoo version, the module version and enough detail to reproduce.