go-auditGo Audit

Changelog

Release notes for Go Audit.

adapters/gorm v1.1.2

Patch release for the GORM adapter only — core v1.1.0 is unchanged.

Bug fixes (correctness)

  • adapters/gorm (issue #1, "A2b"): a parent Update that still carries its loaded HasMany associations no longer double-audits the children as create. Calling db.Model(&order).Update(...) while order.Items is still attached makes GORM re-upsert the children (ON CONFLICT DO UPDATE), which runs the create-callback chain a second time — so each child was recorded as create again (order_items/create == 4 instead of 2). Because this happens in the Update's transaction (separate from the original Create), the v1.1.1 transaction-scoped dedup could not see it.

    The adapter now distinguishes a genuine insert from an association re-save: a re-saved child already has a non-zero primary key before the statement runs, and the operation's root is an update/delete rather than a create. Such rows are skipped for create auditing. Genuinely new children added during an update (PK still zero) and all top-level / nested creates remain fully audited.

    Workaround on v1.1.1 and earlier: db.Model(&order).Omit("Items").Update(...).

Upgrade

go get github.com/gopackx/go-audit/adapters/gorm@v1.1.2

adapters/gorm v1.1.1

Patch release for the GORM adapter only — core v1.1.0 is unchanged.

Bug fixes (correctness)

  • adapters/gorm: nested Create no longer double-audits child rows on GORM ≥ v1.31 (the "2 items → 4 rows" report). The v1.1.0 dedup was scoped to a single GORM statement, but on GORM ≥ v1.31 one db.Create(&parent) runs the child create-callback chain twice within its auto-transaction — an initial INSERT and an FK-backfill upsert, in two separate statements — so the per-statement set never caught the repeat. Dedup is now scoped to the transaction, shared across every statement of one logical write, with a depth counter so it is freed when the outermost operation completes (no leak) and two explicit sequential writes of the same row are each still audited.

Upgrade

go get github.com/gopackx/go-audit/adapters/gorm@v1.1.1

If you installed adapters/gorm@v1.1.0, upgrade to pick up this fix. No schema change and no core upgrade required.

v1.1.0

Bug fixes (correctness)

  • adapters/gorm: db.Where("…").Update/Delete no longer emits WHERE WHERE … (PostgreSQL 42601, which previously cancelled the user's write). The pre-write snapshot SELECT now unwraps the clause.Where expression so the SQL builder writes exactly one WHERE.
  • adapters/gorm: Create with nested associations no longer duplicates child audit rows (2 items → was 4 rows). The callback keeps a per-statement (entity_type, entity_id) dedup set.
  • core: old_values on create is now persisted as SQL NULL instead of the literal JSON token "null". Affected callers that passed a typed-nil map[string]any.

New

  • APIEntry.ResponseHeaders (map[string]string) — redacted using the same RedactHeaders list as RequestHeaders, persisted into a new response_headers column on audit_api_logs.
  • RedactBodyFields now redacts struct and pointer payloads, not only map[string]any. The auditor JSON-round-trips the value first; matching is on JSON tag names.

Docs

  • README pulled to parity with the docs site: ExcludeEntities, SkipOldValues, per-table OnError, gorm.Session{SkipHooks: true}, adapter pseudo-version install, and a dedicated *sql.DB production tip.

AI integration

  • Claude Skill (skills/go-audit/SKILL.md) — drop into ~/.claude/skills/go-audit/ and Claude Code knows how to integrate go-audit from a cold prompt. See Claude Skill.
  • MCP server (mcp/) — read-only Model Context Protocol server exposing query_data_logs, query_api_logs, query_by_transaction, snapshot_entity, and recent_changes so AI hosts can investigate audit history conversationally. See MCP Server.

⚠️ Migration

AutoMigrate uses CREATE TABLE IF NOT EXISTS, so the new response_headers column is only created on fresh installs. Existing deployments must run a one-shot ALTER TABLE per dialect — see audit_api_logs → Upgrading from v1.0.x.

v1.0.0

  • Initial stable release
  • Core auditor backed by database/sql; zero network dependencies
  • Auto-diff on UPDATE — only changed fields stored
  • Manual entry point (RecordDataChange) for raw-SQL code paths
  • API call logging with header and JSON body redaction
  • Body truncation marker for oversized payloads
  • Transaction correlation via transaction_id and context helpers
  • Snapshot and Restore — reconstruct entity state at a past time
  • Retention via Purge(ctx, before)
  • Configurable error modes (ErrorFailLoud / ErrorFailSilent)
  • Custom table names for both audit tables
  • Field and entity exclusion
  • Dialects: PostgreSQL, MySQL, SQLite (with RegisterDialect for custom)
  • GORM adapter — full auto-hooks, soft-delete detection
  • Bun adapter — QueryHook with snapshot via WHERE-clause parsing
  • Ent adapter — mutation hook with single-row old-values
  • Query builder with typed filters (DataFilter, APIFilter)
  • In-memory Store for tests

On this page