|
| 1 | +--- |
| 2 | +layout: default |
| 3 | +title: Audit log retention |
| 4 | +aliases: |
| 5 | + - "/web-ui-hub_administration-audit-log-retention.html" |
| 6 | +--- |
| 7 | + |
| 8 | +The Mission Portal [Audit log API](/api/enterprise-api-ref/audit-logs-api/) |
| 9 | +records administrative actions (user, role, settings, host, group, Build |
| 10 | +project, and federated reporting changes) in the `audit_log` table of the |
| 11 | +`cfsettings` PostgreSQL database. |
| 12 | + |
| 13 | +## Default retention |
| 14 | + |
| 15 | +There is no automatic purging of audit log entries. Records are kept |
| 16 | +indefinitely until manually removed. |
| 17 | + |
| 18 | +This is intentional for compliance use cases where a long, complete history is |
| 19 | +desirable, but it means the `audit_log` table will grow without bound on |
| 20 | +long-running hubs. Operators are expected to apply their own retention policy. |
| 21 | + |
| 22 | +## Inspecting current size |
| 23 | + |
| 24 | +To see how many entries you have and how old they are: |
| 25 | + |
| 26 | +```console |
| 27 | +sudo -u cfpostgres /var/cfengine/bin/psql cfsettings -c \ |
| 28 | + "SELECT count(*) AS rows, |
| 29 | + min(time) AS oldest, |
| 30 | + max(time) AS newest, |
| 31 | + pg_size_pretty(pg_total_relation_size('audit_log')) AS size |
| 32 | + FROM audit_log;" |
| 33 | +``` |
| 34 | + |
| 35 | +## Manually pruning old entries |
| 36 | + |
| 37 | +To delete entries older than a chosen number of days, run as the `cfpostgres` |
| 38 | +user on the hub: |
| 39 | + |
| 40 | +```console |
| 41 | +sudo -u cfpostgres /var/cfengine/bin/psql cfsettings -c \ |
| 42 | + "DELETE FROM audit_log WHERE time < NOW() - INTERVAL '180 days';" |
| 43 | +``` |
| 44 | + |
| 45 | +The `idx_audit_log_timestamp` index ensures this is efficient even on large |
| 46 | +tables. Adjust the interval to match your retention policy (regulatory |
| 47 | +requirements often dictate 1, 3, or 7 years). |
| 48 | + |
| 49 | +## Scheduling pruning with CFEngine policy |
| 50 | + |
| 51 | +Deletion of old records can be accomplished via policy using a `commands` promise. For example: |
| 52 | + |
| 53 | +```cf3 |
| 54 | +bundle agent audit_log_retention |
| 55 | +# @brief Prune Mission Portal audit_log entries older than $(days) days |
| 56 | +{ |
| 57 | + vars: |
| 58 | + "days" string => "365"; |
| 59 | +
|
| 60 | + commands: |
| 61 | + policy_server:: |
| 62 | + "$(sys.bindir)/psql" |
| 63 | + args => "cfsettings -c \"DELETE FROM audit_log WHERE time < NOW() - INTERVAL '$(days) day';\"", |
| 64 | + contain => in_shell_and_silent, |
| 65 | + action => if_elapsed_day, |
| 66 | + handle => "audit_log_retention_prune", |
| 67 | + comment => "Prune Mission Portal audit_log entries older than $(days) days"; |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +## RBAC |
| 72 | + |
| 73 | +Viewing the Audit log in Mission Portal or via the API requires the |
| 74 | +`audit-log.view` RBAC permission, granted to the `admin` role by default. |
| 75 | + |
| 76 | +## See also |
| 77 | + |
| 78 | +- [Audit log API](/api/enterprise-api-ref/audit-logs-api/) — query the log programmatically |
| 79 | +- [Database schema: `audit_log`](/api/enterprise-api-ref/sql-schema/cfsettings/) — column reference |
| 80 | +- [Event log](/web-ui/#event-log) — a separate, automatically-pruned log of host |
| 81 | + bootstraps, decommissions, and alert state changes |
0 commit comments