Skip to content

feat(audit): Implement retention policy for audit events#1025

Open
dexyk wants to merge 8 commits into
mainfrom
dk/audit/add_retention_policies
Open

feat(audit): Implement retention policy for audit events#1025
dexyk wants to merge 8 commits into
mainfrom
dk/audit/add_retention_policies

Conversation

@dexyk

@dexyk dexyk commented May 13, 2026

Copy link
Copy Markdown
Contributor

📝 Description

Applies the system-wide 400-day data retention policy to audit logs, reusing the same usage.apply_organization_policy event that Zebra and Plumber consume: a PolicyMarker consumer stamps events older than the cutoff with an expires_at (clamped to a hard 400-day minimum so retention can never be shortened below policy), and a periodic Deleter removes expired rows using an adaptive cadence to drain backlogs.

Processing is gated per organization by the new audit_logs_retention feature flag, off by default and fail-closed, so retention can be rolled out gradually without risking premature deletion.

Includes the supporting schema migrations (expires_at column and indexes) and dependency bumps to address CVEs.

✅ Checklist

  • I have tested this change
  • This change requires documentation update N/A

@github-project-automation github-project-automation Bot moved this to Backlog in Roadmap May 13, 2026
@dexyk
dexyk force-pushed the dk/audit/add_retention_policies branch from 9cf44bd to 2555837 Compare June 8, 2026 10:25
@skipi
skipi force-pushed the dk/audit/add_retention_policies branch from 93e0824 to 7d1b2aa Compare June 22, 2026 09:20
@dexyk
dexyk force-pushed the dk/audit/add_retention_policies branch from 7d1b2aa to 59c33a6 Compare July 3, 2026 09:14
@dexyk
dexyk marked this pull request as ready for review July 3, 2026 09:23
dexyk and others added 8 commits July 3, 2026 13:25
…pping

A cutoff newer than the min-retention floor (e.g. publisher window 300 < audit floor 400, a future date, or a misconfig) was refused outright, so the marker did nothing — audit events were never expired. Clamp such a cutoff back to the floor instead: still delete everything older than the floor, never expire anything younger. Removes the cross-repo equality coupling and the boundary clock-skew foot-gun. Metric renamed cutoff_too_recent → cutoff_clamped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dexyk
dexyk force-pushed the dk/audit/add_retention_policies branch from 59c33a6 to 519686d Compare July 3, 2026 11:29

@loadez loadez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things I want to flag before we enable the deleter in prod. None of them block the merge since everything is off by default.

1. Disabling the feature flag does not stop deletion after rows are marked.

check_feature_enabled only gates the marking. If we enable audit_logs_retention for the wrong org, the marker sets expires_at, and turning the flag off later does not unmark anything. The Deleter only checks expires_at <= now (deleter.ex:79 / queries.ex:135). So the 15 day grace is the only abort window, and the recovery is to null expires_at by hand in prod. Maybe re-check the org flag in the delete path? Or at least document that the flag only gates marking.

2. The initial marking sweep is unbounded inside one AMQP message.

batch_mark recurses the whole backlog of the org synchronously inside handle_message. The first sweep on a big org (400 days of events, batches of 1000) can pass the RabbitMQ consumer timeout, then the channel closes, the message is redelivered and the sweep restarts. With retry_limit: 10 this can repeat a few times. It is idempotent so we don't lose anything, but maybe cap the batches per message and requeue, or pace the marking through a worker like the Deleter already does.

The rest of the safety design looks good to me. The floor clamp, the changeset excluding expires_at, everything off by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

3 participants