Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions content/api/enterprise-api-ref/audit-logs-api.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,20 @@ HTTP 200 OK
"Authentication",
]
```

## Permissions

All Audit log API endpoints require the `audit-log.view` RBAC permission. This
permission is granted to the `admin` role by default and can be assigned to
other roles via the [Web RBAC API](/api/enterprise-api-ref/web-rbac/).

## Retention

Audit log entries are stored in the `audit_log` table of the `cfsettings`
PostgreSQL database (see the
[schema reference](/api/enterprise-api-ref/sql-schema/cfsettings/)) and are retained
indefinitely. No automatic pruning is performed.

Operators are expected to apply their own retention policy. See
[Audit log retention](/web-ui/hub_administration/audit-log-retention/)
for inspection queries and pruning recipes.
18 changes: 11 additions & 7 deletions content/api/enterprise-api-ref/sql-schema/cfsettings.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ aliases:

Settings used by Mission Portal APIs, no reported data.

## Table: audit_logs
## Table: audit_log

Stores system logs about actions performed by users.

Expand All @@ -17,15 +17,19 @@ Stores system logs about actions performed by users.
The unique identifier of audit log event, generated from a sequence.
- **time** _(timestamp without a time zone)_
Time when an event happened.
- **action** _(text)_
What was done (e.g., updated, created, deleted, deployed).
- **object_type** _(text)_
Type of affected object (e.g., user, role, build project).
- **actor** _(text, not null)_
User who performed the action.
- **action** _(audit_log_action enum, not null)_
What was done.
- **object_type** _(audit_log_object_type enum, not null)_
Type of affected object.
- **object_id** _(text)_
Identifier of an affected object (e.g. user, role id, build project id), if applicable.
- **details** _(json)_
- **object_name** _(text)_
Name of the affected object (e.g. user name, role name, settings name).
- **details** _(jsonb)_
More details in the free-json format.
- **ip_address** _(boolean)_
- **ip_address** _(inet)_
IP address of the user who performed the action.

## Table: build_modules
Expand Down
29 changes: 29 additions & 0 deletions content/web-ui/_index.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,35 @@ All Events can be searched and viewed from the Event Log page.

<img src="web-ui-mission-portal-api-view-whole-system-events-rbac.png" alt="Mission Portal - Events View whole system events RBAC page" width="380px">

### Audit log

The Audit log records administrative actions performed in Mission Portal — for
example user, role, and settings changes, host and group edits, Build project
changes, and federated reporting configuration. Each entry captures the actor,
action, affected object, timestamp, and originating IP address.

The Audit log is distinct from the Event log: the Event log tracks
_system events_ like host bootstraps and alert state changes, while the Audit
log tracks _human actions_ against the administrative surface.

- Entries are queryable via the [Audit log API](/api/enterprise-api-ref/audit-logs-api/).
- Viewing the Audit log requires the `audit-log.view` RBAC permission (granted to `admin` by default).
- Entries are stored in the `audit_log` table of the `cfsettings` database and
are retained indefinitely unless pruned. See
[Audit log retention](/web-ui/hub_administration/audit-log-retention/) for
guidance on inspecting and managing table growth.

![](images/audit-log.png)

The log can be filtered by date range, actor, object type, and object
name to narrow down to specific activity.
Each row links to a detail view showing the full activity record and any
structured details captured for the action. For example, the configuration
fields changed in a settings update or the values associated with a created
object.

![](images/audit-log-entry.png)

### Newly bootstrapped hosts widget

The Newly bootstrapped hosts widget helps to visualize the number of hosts bootstrapped to CFEngine over time.
Expand Down
81 changes: 81 additions & 0 deletions content/web-ui/hub_administration/audit-log-retention.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
layout: default
title: Audit log retention
aliases:
- "/web-ui-hub_administration-audit-log-retention.html"
---

The Mission Portal [Audit log API](/api/enterprise-api-ref/audit-logs-api/)
records administrative actions (user, role, settings, host, group, Build
project, and federated reporting changes) in the `audit_log` table of the
`cfsettings` PostgreSQL database.

## Default retention

There is no automatic purging of audit log entries. Records are kept
indefinitely until manually removed.

This is intentional for compliance use cases where a long, complete history is
desirable, but it means the `audit_log` table will grow without bound on
long-running hubs. Operators are expected to apply their own retention policy.

## Inspecting current size

To see how many entries you have and how old they are:

```console
sudo -u cfpostgres /var/cfengine/bin/psql cfsettings -c \
"SELECT count(*) AS rows,
min(time) AS oldest,
max(time) AS newest,
pg_size_pretty(pg_total_relation_size('audit_log')) AS size
FROM audit_log;"
```

## Manually pruning old entries

To delete entries older than a chosen number of days, run as the `cfpostgres`
user on the hub:

```console
sudo -u cfpostgres /var/cfengine/bin/psql cfsettings -c \
"DELETE FROM audit_log WHERE time < NOW() - INTERVAL '180 days';"
```

The `idx_audit_log_timestamp` index ensures this is efficient even on large
tables. Adjust the interval to match your retention policy (regulatory
requirements often dictate 1, 3, or 7 years).

## Scheduling pruning with CFEngine policy

Deletion of old records can be accomplished via policy using a `commands` promise. For example:

```cf3
bundle agent audit_log_retention
# @brief Prune Mission Portal audit_log entries older than $(days) days
{
vars:
"days" string => "365";

commands:
policy_server::
"$(sys.bindir)/psql"
args => "cfsettings -c \"DELETE FROM audit_log WHERE time < NOW() - INTERVAL '$(days) day';\"",
contain => in_shell_and_silent,
action => if_elapsed_day,
handle => "audit_log_retention_prune",
comment => "Prune Mission Portal audit_log entries older than $(days) days";
}
```

## RBAC

Viewing the Audit log in Mission Portal or via the API requires the
`audit-log.view` RBAC permission, granted to the `admin` role by default.

## See also

- [Audit log API](/api/enterprise-api-ref/audit-logs-api/) &mdash; query the log programmatically
- [Database schema: `audit_log`](/api/enterprise-api-ref/sql-schema/cfsettings/) &mdash; column reference
- [Event log](/web-ui/#event-log) &mdash; a separate, automatically-pruned log of host
bootstraps, decommissions, and alert state changes
Binary file added content/web-ui/images/audit-log-entry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/web-ui/images/audit-log.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading