BFBambooForge Labs

Audit Log & Audit Trail for Odoo

Audit log and audit trail with field-level tracking, hash chaining, anomaly detection, alerts, PII masking, retention and a compliance PDF.

Buy on the Odoo Apps StoreOpen the live demoExtra Tools€407Community & Enterprise

Available for Odoo 16.0, Odoo 17.0, Odoo 18.0, Odoo 19.0. Technical name bambooforge_audit_pro.

Odoo 16.0Odoo 17.0Odoo 18.0Odoo 19.0
Full walkthrough on a live Odoo 19.0 database, with subtitles. It ends with what this app deliberately does not do.

Audit Log & Audit Trail for Odoo

A complete audit trail for Odoo 18: log every create, write, delete and read on the models you choose, watch logins, raise alerts on suspicious activity, gate sensitive edits behind an approval workflow, push alerts to Slack/Discord/Teams, and archive logs off-system before they are purged — all from one Audit app.

This page is the complete manual. If you follow it top to bottom you can install, choose what to audit, read the logs, wire up alerts and approvals, ship logs out, and fix the common issues without contacting support.

Overview

Audit Pro hooks the Odoo ORM so that operations on the models you subscribe are recorded, then layers compliance tooling on top. It covers:

  • Audit trail of record changes — create, write, delete and (optionally) read events on any model you pick, with a per-field before/after diff.

  • Login tracking — every successful, failed and blocked login is recorded with IP, user agent and a hashed session token, automatically, with no rule setup.

  • Anomaly rules — raise an alert when too many events of one kind happen in a short window (for example a single user doing hundreds of writes or deletes in minutes).

  • Approval workflows — writes that touch fields you mark Sensitive are intercepted and parked as approval requests until an approver in the configured group accepts them.

  • Alerts, email & webhooks — alert rules match a slice of the trail and notify by email and/or HTTP webhook (Slack, Discord, Microsoft Teams, or generic JSON).

  • Archive targets & retention — ship logs to a local file, syslog or S3-compatible storage before a retention cron deletes them.

  • Dashboard & timeline — a KPI dashboard over a date window, plus a single chronological stream that merges record events and field changes.

  • Tamper-evidence & privacy — each log is chained to the previous one with a hash you can verify, PII fields are masked at capture, and logs can be anonymized for GDPR.

Everything lives under one top-level Audit menu, grouped into Audit Logs, Security, Alerts and Configuration.

Requirements

Item

Detail

Odoo

18.0, Community or Enterprise.

Python

xlsxwriter (used by Export Logs to write XLSX). It is the only extra dependency. The S3 archive backend also needs boto3, but only if you actually configure an S3 target — it is never required at install.

Depends

base, web, mail (all standard). No third-party Odoo modules.

Access rights

The Auditlog User group can read logs, dashboard and timeline. The Auditlog Manager group can configure rules, approvals, webhooks and archives, and may anonymize logs. Odoo Administration / Settings users (base.group_system) get Manager automatically.

Network

Outbound HTTPS is only needed if you use webhooks or the S3 archive backend. Webhook URLs must be public — internal/loopback/private hosts are refused (SSRF guard).

Installation

  1. Copy bambooforge_audit_pro into your Odoo addons path.

  2. Restart the Odoo service.

  3. Open Apps, click Update Apps List, search for Audit Pro, and press Activate / Install. The dependencies install automatically.

  4. After install, an Audit application appears in the main app drawer. A post-install hook re-applies any active audit rules so logging starts immediately.

A guided Getting Started wizard is available under Audit ▸ Configuration ▸ Getting Started: three steps that subscribe a few rules, optionally wire one notification channel, and set a retention window. You can skip it and configure everything by hand using the sections below.

Access snapshots and reviews

Audit ▸ Security ▸ Access Snapshots freezes what every internal user may do: their groups, a fingerprint of those groups, and whether they hold administrator rights. Take one on demand or leave the scheduled action to do it, then open a later snapshot and press Compare to see who gained rights, who lost them, who joined and who left — users whose fingerprint is unchanged are deliberately not listed.

Audit ▸ Security ▸ Access Reviews turns a snapshot into the evidence an auditor asks for: one decision per user — keep or revoke — each stamped with the reviewer and the moment they answered. A campaign cannot be completed while a user is unanswered. Apply revocations strips only the groups the reviewer refused (leave the group list empty to remove everything the user held at snapshot time), records who applied it, and refuses to let a reviewer revoke their own access in a campaign they are signing.

Configuration

All configuration lives under the Audit app. The menu groups are:

Menu group

Contains

Audit Logs

Logs, Log Lines, Timeline, Export Logs.

Security

Login Events, Anomaly Rules.

Alerts

Alerts, Alert Rules.

Configuration

Getting Started, Rules, Audit Models, Compliance Presets, Webhooks, Webhook Queue, Archive Targets. Approvals sit directly under Audit.

Step 1 — Choose what to audit (audit rules)

Open Audit ▸ Configuration ▸ Rules and create a record (one rule per model — the model is unique across rules).

Audit rule form — model, operations, exclusions and the Phase B tabs

Field

What it does

Model

The model to track. Locked once the rule is Subscribed.

Type

Full log makes a before/after diff of every field (richer, slower); Fast log records only the values passed to create/write (less detail, faster).

Log Reads / Writes / Deletes / Creates

Which operations generate logs. Writes, Deletes and Creates are on by default; Reads is off (it is the noisiest).

Capture Record

On Full log + Log Deletes, keep a snapshot of a record's values when it is deleted.

Users to Exclude

Operations by these users are never logged (for example an integration user).

Fields to Exclude

Fields that never appear in the diff.

The rule form also carries three tabs:

  • PII MaskingFields to Mask (PII). Values of these fields are masked when stored in audit lines (emails become a***@b***.c, phone numbers keep the country code and last two digits, everything else becomes ***).

  • Approval WorkflowSensitive Fields (require approval), Approver Group and Approval Timeout (hours) (default 72). See Step 4.

  • Retention & ArchiveRetention Days (0 = use the global autovacuum, 180 days by default) and Archive Target. See Step 6.

Click Subscribe in the header to activate the rule. The state moves to Subscribed and an Audit History shortcut is added to the Action menu of the audited model's form. Click Unsubscribe to stop logging; you must unsubscribe before changing the model, operations or masking/sensitive fields.

Faster starts:

  • Audit Models (Configuration ▸ Audit Models) subscribes several models at once with the same settings.

  • Compliance Presets (Configuration ▸ Compliance Presets) bootstraps GDPR, SOX or PCI-DSS in one click — it creates and subscribes the right rules with masking, sensitive fields and retention already filled in, and skips models that are not installed on your database.

Step 2 — Anomaly rules

Open Audit ▸ Security ▸ Anomaly Rules. An anomaly rule raises an alert when the number of matching audit events crosses a threshold inside a time window.

Anomaly rule form — scope, threshold and window

Field

What it does

Model

Scope to one model. Empty = all models.

Method

Scope to Create / Write / Read / Delete. Empty = all.

User

Scope to one user. Empty = any user.

Threshold (events)

Raise an alert when this many matching events occur within the window (default 100).

Window (minutes)

The rolling window length (default 10).

Severity

Low / Medium / High / Critical (labelling only).

Alert channel

The alert rule whose email + webhook channels fire on a breach. Leave empty and one is auto-created on the first breach.

A cron (Audit anomaly — evaluate thresholds, every 5 minutes) walks the active rules. The Last evaluation fields show the last run time and event count. Breaches are deduplicated so you do not get repeat alerts inside the same window.

Step 3 — Alert rules, email and webhooks

An Alert Rule (Audit ▸ Alerts ▸ Alert Rules) matches a slice of the trail and raises an Alert. Combine Model, User, Method, Field and Keyword (the alert fires only when the changed values contain that keyword) to narrow it.

On the alert rule, the Notification Channels section controls how a match is shipped:

  • Send Email — uses an email template (defaults to the bundled audit-alert template) and an optional comma-separated Email Recipients override. Mail is queued, not sent inline, so a slow SMTP server never blocks the user write that triggered the alert.

  • Webhooks — one or more webhook records to call. Dispatch is queued (see Step 5).

To create a webhook, open Audit ▸ Configuration ▸ Webhooks.

Webhook form — backend, URL, headers and HMAC secret

Field

What to enter

Backend

Slack, Discord, Microsoft Teams or Generic JSON. This shapes the payload to the receiver's expected format.

URL

The incoming webhook URL. Must be a public host — internal/loopback/private addresses are rejected.

Timeout

Per-call timeout in seconds (default 5).

Extra Headers (JSON)

Optional JSON object merged into the request headers, e.g. {"Authorization": "Bearer xxx"}.

HMAC Signature Secret

If set, each request carries an X-BFAudit-Signature: sha256=… header so the receiver can verify the body was not altered.

Use the Send Test button to POST a synthetic payload and confirm connectivity before attaching the webhook to an alert rule. The form shows the last status, last call time and call count.

Step 4 — Approval workflow

Approvals turn a risky edit into a reviewed action. On an audit rule's Approval Workflow tab, add fields to Sensitive Fields (require approval), pick an Approver Group and set an Approval Timeout (hours).

From then on, when any user tries to write one of those fields, the write is blocked and a bf.audit.approval.request is created instead. Approvers find pending requests under Audit ▸ Approvals.

Approval request form — side-by-side current vs requested diff

The request shows a side-by-side Current vs Requested diff. An approver in the group clicks Approve to apply the change for real, Reject to discard it, or Open Record to inspect the target. Requests left pending past the rule's timeout are auto-expired by an hourly cron (Audit approval — expire pending). If applying an approved change fails (the record was deleted, the value is invalid…), the request moves to Apply Error with the reason recorded.

Step 5 — Webhook queue

Webhook dispatch is asynchronous: when an alert fires, each webhook call is enqueued in Audit ▸ Configuration ▸ Webhook Queue and a cron (Audit webhook — drain queue, every minute) sends it with retry/back-off. This guarantees a slow or failing endpoint can never block the user write that triggered the alert. Each queue row shows its state (pending / sending / sent / failed), retry count and last error; Retry Now forces an immediate attempt.

Step 6 — Archive targets & retention

Logs are deleted on a schedule; archive targets let you keep a durable copy first. Create a target under Audit ▸ Configuration ▸ Archive Targets, then set it as the Archive Target on the relevant audit rule.

Archive target form — file, syslog or S3 backend

Backend

What to configure

Local File

File Path — a directory on the Odoo host. One JSON-Lines file is written per batch. For safety the path must sit inside the base directory set by the bambooforge_audit_pro.archive_base_dir system parameter (defaults to <data_dir>/bf_audit_archive); paths outside it are rejected.

Syslog

Syslog Host, Port (514) and Facility (local0–local7).

S3 / S3-compatible

Bucket, Prefix, Region, optional Endpoint URL (for MinIO / Wasabi / R2), and access/secret keys. Requires the boto3 package.

Use Send Test to ship one synthetic record and confirm the target works; the form records the last status, time and shipped count.

Retention is driven by two crons:

Cron

Default

What it does

Auto-vacuum audit logs

daily, off

Deletes logs, HTTP requests, HTTP sessions, login events and old webhook-queue rows older than 180 days. Disabled out of the box — enable it to use the global window.

Audit per-rule retention vacuum

daily, on

Deletes logs older than each subscribed rule's Retention Days (0 = skip).

Audit approval — expire pending

hourly, on

Auto-expires approval requests past their timeout.

Audit webhook — drain queue

every minute, on

Sends queued webhook calls with retry/back-off.

Audit anomaly — evaluate thresholds

every 5 min, on

Evaluates anomaly rules.

Both vacuums ship logs to their rule's archive target before deleting them, so a configured archive is always durable first.

Usage

Dashboard

Open Audit ▸ Dashboard. Pick a From / To window; the KPIs recompute live: Total Logs, Field Changes, Active Users, Triggered Alerts, Open Alerts, Pending Approvals, Logins OK and Logins Failed, plus the Top Model and Top User for the window.

Audit dashboard — KPI tiles and highlights over a date window

The action bar drills into the same window: Open Logs, Timeline, Alerts and Approvals. Refresh reloads the figures.

Logs

Audit ▸ Audit Logs ▸ Logs lists every captured operation (default filter: last 7 days). Each row is one operation on one record; open it to see the Changed Fields tab with the before/after value of each field and a per-field diff preview.

Audit logs list with method, model, user and resource columns

Group by User, Model, Method, Type, User session or HTTP Request to slice the trail. The log form also links to its Alerts and a record-scoped Timeline. From the list, two server actions are available in the Action menu: Anonymize (GDPR) (managers only — wipes field values to *** but keeps the envelope) and Verify Hash Chain (confirms the tamper-evidence chain is intact). Log Lines (Audit Logs ▸ Log Lines) is the same data flattened to one row per field change. Export Logs writes a filtered range to XLSX.

Login events

Audit ▸ Security ▸ Login Events records every authentication attempt with IP, user agent, a hashed session token and (on failure) the reason — no rule needed. Rows are colour-coded: green for success, red for failed, amber for blocked.

Login events list, colour-coded by success / failed / blocked

Default filter is the last 7 days; filter by Success / Failed / Blocked or group by User, State or IP.

Timeline

Audit ▸ Audit Logs ▸ Timeline merges record events and individual field changes into one chronological stream. Each entry shows the time, user, method, model, the changed field (if any) and a summary with a change type of Added, Removed or Changed.

Activity timeline — record events and field changes in one stream

Use the Field Changes / Record Events filters to focus, or switch to the pivot view to chart events by day and model.

Customization

  • Field coverage — override auditlog.rule.get_auditlog_fields to change which fields a rule captures (by default all stored, non-computed/related fields).

  • Generic webhooks — set a webhook's backend to Generic JSON to receive the full alert payload, and use Extra Headers and HMAC Signature Secret to integrate with any HTTP receiver.

  • SIEM / log shipper pull — a read endpoint at GET /api/bf_audit/logs streams logs as JSON Lines for Splunk, ELK/Logstash, Datadog, Loki or Grafana Agent. It accepts since, limit (default 1000, max 10000) and model query parameters. Authenticate with the X-Audit-API-Key header, matching either the bambooforge_audit_pro.api_key system parameter (full export) or a per-user key set under a user's Audit API tab (results are then scoped to that user's access rights).

  • Compliance presets — the GDPR / SOX / PCI-DSS presets are a starting point; after applying one, edit the generated rules to fit your data model.

Troubleshooting

Symptom

Cause and fix

Nothing is logged

The rule is still in Draft. Open it and click Subscribe. Logging only starts once the state is Subscribed.

A specific operation is not logged

The matching Log Reads / Writes / Deletes / Creates toggle is off, the acting user is in Users to Exclude, or the field is in Fields to Exclude. Reads are off by default.

Too much is logged / the system feels slow

Full log and especially Log Reads are heavy. Switch the rule to Fast log, turn Reads off, exclude noisy fields/users, and scope anomaly rules tightly. The dashboard's Top Model / Top User show where the volume comes from.

Logs grow without bound

Retention is opt-in. Set Retention Days per rule (the per-rule cron is on), or enable the Auto-vacuum audit logs cron for the global 180-day window.

A webhook never fires

Check the alert rule actually lists the webhook, that the Webhook Queue row is not stuck in failed (read its last error), and that the Audit webhook — drain queue cron is active. Use Send Test on the webhook to isolate connectivity.

Saving a webhook is refused

The URL points at an internal/loopback/private host. Webhooks must use a public http(s):// endpoint (SSRF guard). Slack/Discord/Teams cloud URLs are fine.

An approval is stuck / a user "cannot save"

The field is marked Sensitive; the write became an approval request under Audit ▸ Approvals. An approver in the rule's Approver Group must Approve or Reject. Requests past the timeout auto-expire hourly. If approval shows Apply Error, the target record changed — re-do the edit.

Approve/Reject buttons do nothing for me

You are not in the rule's Approver Group. Add yourself, or have an Auditlog Manager decide.

"Permission denied" on Anonymize

Anonymizing requires the Auditlog Manager group.

The API endpoint returns 401 / 403

401 = missing or wrong X-Audit-API-Key (check the system parameter or the per-user key). 403 = a per-user key whose user lacks audit-log read rights, or whose Audit API scope is empty.

S3 archive test fails with a boto3 error

The S3 backend needs the boto3 package installed in the Odoo environment. Install it, or use the Local File or Syslog backend instead.

A user sees fewer logs than expected

Logs are multi-company isolated: a user only sees logs of companies they belong to (company-less logs stay visible to all).

Frequently asked questions

Does this slow Odoo down? Logging adds work to each audited operation, so only subscribe the models and operations you need. Fast log is lighter than Full log, and Log Reads is the heaviest option (off by default). Webhooks and alert emails are queued, never inline.

Can I audit reads, not just changes? Yes — turn on Log Reads on the rule. Expect high volume; reserve it for sensitive models.

How do I prove the logs were not tampered with? Every log is hash-chained to the previous one. Select logs and run Verify Hash Chain from the Action menu to confirm the chain is intact.

How do I comply with a GDPR erasure request? Select the relevant logs and run Anonymize (GDPR) (managers only). Field values become *** while the date/user/method/model envelope is kept for forensic integrity. You can also mask PII at capture time via the rule's PII Masking tab.

Can alerts go to Slack / Teams / Discord? Yes. Create a webhook with the matching backend, test it, and attach it to an alert rule's Webhooks field. Generic JSON covers any other HTTP receiver.

Where do archived logs go? To the archive target on each rule: a local JSON-Lines file, syslog, or an S3-compatible bucket. Archiving happens before the retention cron deletes the rows.

What support and refund policy do I get? Every request is answered within 24 hours, setup help included. If you report a bug within 2 months of purchase and it is not resolved within 15 days, you are entitled to a full money-back refund.

Data, privacy & limits

  • What is stored — for each audited operation: the model, record id, method, acting user, timestamp, HTTP request/session reference, and (for Full log) a before/after value per field. Login events store the attempted login, user, state, IP, user agent and a hashed session token. PII fields you mark are masked at capture.

  • Where data goes — audit data stays in your Odoo database unless you configure an archive target (file/syslog/S3) or expose the pull API. Webhooks send only the alert summary payload to the URL you configure.

  • Multi-company — logs are isolated by company; users see only the companies they belong to.

  • In scope — change/login auditing, anomaly rules, approval workflow, alerts with email + Slack/Discord/Teams/generic webhooks, archive targets, retention, hash-chain verification, GDPR anonymization, XLSX export, JSON-Lines pull API.

  • Out of scope — the approval workflow intercepts write on sensitive fields, not create or delete. The S3 backend needs boto3. Webhook URLs must be public.

Support & updates

  • Support: support@bambooforge.dev — answered within 24 hours, setup help included.

  • Refund: report a bug within 2 months of purchase; if unresolved within 15 days, full refund.

  • Full source is included. Updates track the supported Odoo 18 line.

Upgrading & version compatibility

This build targets Odoo 18.0. Each Odoo major series (17.0, 18.0, 19.0) has its own dedicated build of this module — always install the build that matches your Odoo version. Mixing a build with a different Odoo series is not supported.

Patch upgrades (same series, e.g. 18.0.1.0.0 → later)

  1. Back up your database and filestore first.

  2. Replace the module folder with the newer build.

  3. Restart Odoo with the module updated:

    ./odoo-bin -c your.conf -u bambooforge_audit_pro -d your_db
  4. Odoo applies any schema/data changes automatically. Your existing records and configuration are preserved.

Cross-version migration (e.g. Odoo 17 → 18)

Upgrading Odoo itself is a database migration handled by Odoo's standard upgrade tooling. When you migrate the database to the next Odoo series, install the matching build of this module for that series. Data created by this module carries over with the database migration.

After any upgrade the module's scheduled actions resume on their normal cadence — no manual re-activation is required.

Uninstallation

You can remove this module at any time from Apps → (this module) → Uninstall, or from the command line. Uninstalling is clean and reversible by reinstalling — but note what is and is not deleted.

What is removed

  • The module's own tables and every record in them (17 models, prefixed auditlog.*) — this is the data this module created.

  • The menus, actions, views and reports this module installed.

  • Its scheduled actions (cron jobs) — they stop immediately on uninstall.

  • The security groups this module defined (user assignments to them are dropped).

What is preserved

  • Your standard Odoo data (partners, products, sales, invoices, inventory moves) is not deleted — this module only reads and annotates it; the underlying records stay.

  • Attachments and chatter messages on standard records are kept.

As always, take a database backup before uninstalling in production.

Changelog

18.0.5.5.0

Current release for Odoo 18.0. This build includes:

  • Contextual anomaly detection, one-click GDPR/SOX compliance attestation PDF and a daily tamper tripwire on top of hash-chained audit logs, alerts, webhooks, PII masking, approval workflow, retention policy and external archiving.

Feature additions and fixes ship as new builds on the Odoo Apps store; this page and the module's version reflect the current published release. Always keep the build matched to your Odoo series (see Upgrading & version compatibility).

Screens

Access review - bambooforge_audit_pro
Access review
Access snapshot - bambooforge_audit_pro
Access snapshot
Anomaly rule form - bambooforge_audit_pro
Anomaly rule form
Approval form - bambooforge_audit_pro
Approval form
Archive target form - bambooforge_audit_pro
Archive target form
Dashboard - bambooforge_audit_pro
Dashboard
Demo - bambooforge_audit_pro
Demo
Icon 96 - bambooforge_audit_pro
Icon 96
Login events - bambooforge_audit_pro
Login events
Logs - bambooforge_audit_pro
Logs
Rule form - bambooforge_audit_pro
Rule form
Timeline - bambooforge_audit_pro
Timeline
Video poster - bambooforge_audit_pro
Video poster
Webhook form - bambooforge_audit_pro
Webhook form