A Security and Ownership Gate for AI-Generated Odoo Code

· ai · security · governance · odoo · licensing

As a team ships more AI-generated Odoo code, two risks appear that nobody owns: security review goes ad-hoc, and the AI contribution has no attributable form. The fix wasn't a memo but a committed, executable gate — and it forced a legal question about who owns AI-assisted code.

Once a team generates a meaningful share of its Odoo code with an assistant, two risks appear that no single person owns:

  • Security review of AI code goes ad-hoc. Whether a PR gets checked for the Odoo-specific failure modes — CSRF/SSRF, safe_eval, access control — depends on whether a reviewer remembers to look. No rule, no guarantee.
  • The AI contribution has no attributable form. It lives in file comments: unstructured, not timestamped, not machine-readable, impossible to aggregate for an audit.

The deeper problem underneath both is the same one that quietly rots most engineering policy: the decision lived as a verbal agreement, not as an executable gate. Something everyone nods at in a meeting is not something you can delegate to or hold anyone accountable for. Odoo is the running example throughout — the failure modes and the license are specific to it — but the gate-not-agreement problem, and the shape of the fix, are not.


The gate

A closed chain of four components, committed together so the policy is an artifact rather than a habit:

  1. A security-scan policy rule — OWASP Top-10 projected onto Odoo specifically: CSRF/SSRF, safe_eval, access control. Shipped with tests, not just a description of intent.
  2. A /sec-review skill + command — makes an Odoo security review cheap and reproducible for the whole team, instead of dependent on one reviewer’s memory on a given day.
  3. A policy guide — commit conventions, file markers, the audit trail, a pre-commit lint hook. The policy became an instruction document you can point at, not a thing you re-explain.
  4. An Assisted-by: commit trailer (tool + model) plus a one-time file marker. Now the AI contribution is attributable, timestamped, and machine-readable — you can aggregate it for an audit.

Why the gate is not theatre

The week the rule landed, an audit of generated code found a real defect the rule is built to catch: a data leak through an unvalidated sudo() / ACL path in a service that looked completely clean. That is the important part.

AI-generated code cannot be judged by looking clean. Its systematic blind spot is access control, because the generator optimises for working code, not for least-privilege code. The two are indistinguishable on a casual read and very different in production.

So the acceptance criterion that belongs next to the rule is not a style check — it is an empirical permissions test under a low-privilege login for any AI-generated PR. “It runs” is not “it is safe.”


From design to a standard

For two weeks the gate lived as a design — approved mechanisms with no organisational landing. That gap is not technical. It is the distance between “I designed a policy” and “the policy is a voiced team standard that people can be held accountable for.”

Closing it meant rolling out in the open, not by stealth:

  • Presenting the requirements to the team directly — the Assisted-by: marker in files and commits, mandatory OWASP Top-10 scanning of AI code including its tests, and disciplinary accountability for non-compliance.
  • Agreeing to move the scan into CI/CD and pre-commit (as a separate pipeline library; the harder question of wiring the model API into pipelines was deferred on purpose).
  • Telling the team, explicitly, “we’re starting.” That sentence is the moment a design becomes a standard.

The question it surfaced: who owns AI-assisted code?

Rolling the policy out in the open immediately exposed a gap the gate itself did not close. Someone raised it directly: does the Odoo Proprietary License (OPL1) conflict with a possible public-domain status of AI-generated code?

The question is real, not academic. If AI-generated code were public domain, then any module containing it could not be protected under OPL1 or held as company property — which breaks the commercial model. A policy with that hole open underneath it is not finished.

The right move was not to answer on the spot from memory, but to write a referenced analysis the team can point to the next time it comes up.


The ownership verdict

Three sources frame it:

  • US Copyright Office, Copyrightability report (2025). Purely machine-generated output with no human creative contribution is not protected. Output where a human exercises sufficient creative control over the expression is. AI as a tool does not destroy authorship — only the absence of human contribution does.
  • Ukrainian copyright law (№ 2811-IX, art. 33). Content generated “without the direct participation of a natural person” gets a separate, sui-generis regime. The contested point is whether prompt engineering, review, manual refinement, and architecture decisions count as direct participation.
  • EU practice — close to the above: protection requires an “author’s own intellectual creation.”

The question is therefore not “AI or human,” but “is there sufficient human contribution in our process.” In this workflow there is, at several levels: an engineer makes the architecture decisions, writes the prompts that set the logic, and the output passes code review, a security scan, and manual refinement before integration. That is instrumentally-assisted work — the assistant is a sophisticated tool, like an IDE with autocomplete, not an autonomous author.

So:

  1. Property rights belong to the company — but through different mechanisms in different jurisdictions, and it is worth not collapsing them into one word. Under US doctrine that is work made for hire. Under Ukrainian law (№ 2811-IX) it runs through the separate службовий твір (employee-work) regime, where the economic rights to work created in employment vest in the employer by default of the employment or contract terms. Different doctrine, same outcome here. Either way, OPL1 and the commercial model are not at risk as long as the human contribution — architecture, prompts, review, refinement — is preserved.
  2. The Assisted-by: trailer records provenance, not authorship status. It exists for audit and security tracking. That framing is written into the policy guide and the commit conventions themselves — not left as an after-the-fact reading — so the marker can never be turned against you as an admission that the code is “machine output.” The point is placement: the protection has to live in the repository, next to the risk, not only in an essay like this one.
  3. The human-contribution threshold is an operational invariant. A workflow where raw model output is committed as-is, unreviewed, could in theory fall outside protection. So the security gate and mandatory review are not only about quality and safety — they preserve the copyright status of the code. Security discipline and IP protection turn out to be the same discipline.

Alternatives that lost

“AI code is public domain — mark it as such.” Rejected: it contradicts the actual human contribution and would dismantle the OPL1 model with no legal basis for doing so.

“Wait for a formal legal opinion; hold no position meanwhile.” Rejected: it leaves the policy with an open hole for an indefinite period. A working position with a disclaimer is safer than a vacuum.

“Remove the Assisted-by: marker so there’s no trace of machine involvement.” Rejected: the marker is needed for audit and security. The interpretation risk is removed by explicit wording (point 2 above), not by deleting the evidence.


What it buys

  • Security review that does not depend on memory — a rule with tests, plus a reproducible command, plus an empirical permissions test for the blind spot AI code actually has.
  • An auditable trail of AI contribution — timestamped and machine-readable, not scattered across comments.
  • A defensible ownership position — a referenced, timestamped stance instead of a retold-from-memory answer, with the security gate doubling as the thing that keeps that position true.

Tradeoffs and open tails

  • Compliance is not yet measured. How many commits actually carry the trailer, how much AI code actually passes the scan — that baseline still has to be taken from CI over a few weeks. A gate you cannot measure adoption of is only half-built.
  • The Ukrainian art. 33 reading is interpretive. Until doctrinal or judicial clarity exists, the ownership position is a working one with a disclaimer, not a settled fact.
  • A fully-automatic commit workflow would need its own review. The verdict holds because humans stay in the loop. Remove them and the copyright status has to be reconsidered — which is one more reason the gate is not something to relax under deadline pressure.