Audit & Snapshots

Overview

coreX Platform tracks every configuration mutation as an audit event and creates config snapshots on each apply. This provides a complete change history with the ability to revert pending changes or roll back to any previous configuration.

Audit Events

Every POST, PUT, DELETE, and PATCH on /api/v1/* is logged as an audit event. GET requests and health checks are not logged.

Event Properties

PropertyDescription
actionSemantic label (e.g. create_backend, apply_config, login)
methodHTTP method
pathRequest path
resource_typeType of resource affected
resource_idID of the resource
payloadRequest body (truncated, secrets redacted)
snapshot_idConfig snapshot this event was bundled into
user_idID of the user who made the change
usernameUsername of the user
ip_addressSource IP of the request
status_codeResponse status code
config_changeWhether this event affects generated config (see below)
created_atTimestamp

Config Change Classification

Each audit event is classified as config_change=True or config_change=False:

  • config_change=True — the mutation affects a generated config file (HAProxy, Coraza, Varnish, MCP bundle, security-list files, risk-rules data). These events appear in the “Pending Changes” section until applied.
  • config_change=False — the mutation doesn’t affect any generated config (auth, user management, captcha keys, WAF snapshots, Vector operations, validation-only, cache flush, API Armor runtime, Page Protect observational data, MCP operational endpoints, SSL Labs scans, etc.). These events appear in the “Other Activity” section and don’t require an apply.

This classification prevents the “Pending Changes” banner from showing events that don’t need a config apply.

Action Derivation

Actions are auto-derived from the method and path:

  • POSTcreate_<resource>
  • PUTupdate_<resource>
  • DELETEdelete_<resource>
  • Special-case mappings for auth, config lifecycle, cert operations, WAF imports, feed refreshs, API Armor, MCP Gateway, SSL Labs, and more

Payload Handling

  • Auth paths (login, token, TOTP, logout, refresh) are never captured
  • POST /certificates (contains private keys) is never captured
  • MCP server and identity creation (contains secrets) is never captured
  • Vector sink creation/test (contains plaintext secrets) is never captured
  • Non-JSON content types are not captured
  • Payloads are truncated to 16KB (configurable via AUDIT_PAYLOAD_MAX_BYTES)
  • Truncated payloads are flagged with a _truncated marker

Config Status, Diff, and Preview

coreX Platform tracks whether there are unapplied changes by comparing the currently applied config files against freshly generated ones.

Compared Config Files

FileDescription
haproxy.cfgMain HAProxy configuration
varnish.vclVarnish VCL (only when disk cache is enabled)
MCP bundleMCP gateway config bundle (compared as decrypted plaintext — Fernet uses a random IV, so ciphertext comparison would always show a diff)
Vector configVector vector.toml (compared on full text for the unapplied flag, but only redacted text is surfaced in diffs so secrets never leak; skipped entirely when the pipeline is not configured)

Endpoints

EndpointDescription
GET /config/statusReturns {unapplied: bool} — true if any config file differs
GET /config/diffReturns a unified diff of all changed config files (redacted)
GET /config/previewReturns the generated HAProxy config (without applying)
GET /config/preview-allReturns all generated config files as {label: content}

The Dashboard shows an “Unapplied Changes” banner when config/status returns true.

Config Snapshots

When you click Apply Changes, coreX Platform:

  1. Generates the full HAProxy configuration (and Varnish VCL, MCP bundle, Vector config if enabled)
  2. Validates it
  3. Saves a ConfigSnapshot with the configuration stored on disk and a diff of what changed
  4. Stamps all pending (un-applied) audit events with the snapshot ID
  5. Applies the configuration to HAProxy

This links every audit event to the snapshot it was included in, showing which changes were bundled together.

Snapshot Properties

PropertyDescription
idUnique snapshot ID
commentOptional description
created_atTimestamp
created_byUser who applied
diffDiff of what changed in this apply
snapshot_pathPath to the full config file on disk

Max Snapshots

The maximum number of snapshots to retain is configurable:

  • GET /config/snapshots/max — read the current limit
  • PUT /config/snapshots/max — set the limit (default: 10)

When the limit is reached, the oldest snapshots are pruned. Audit events linked to pruned snapshots remain visible in the “Earlier applies” bucket.

Revert vs Rollback

coreX Platform has two distinct operations for undoing changes:

Revert (Discard Pending Changes)

POST /config/revert — reverts to the last applied config, discarding all pending (un-applied) changes. Use this when you’ve made changes but haven’t applied them yet and want to undo them.

  • Requires confirmation (confirmed: true)
  • No new snapshot is created (no apply happened)
  • Pending audit events remain visible but are no longer “pending”

Rollback (Restore a Previous Snapshot)

POST /config/snapshots/{id}/rollback — rolls back to a specific historical snapshot, restoring the full configuration from that point in time.

  • Creates a new snapshot for the rollback action (so rollbacks are themselves audited and can be rolled back)
  • HAProxy is reloaded with the reverted configuration
  • Any changes made after the snapshot will be lost
Rollback is a full restore

Rolling back restores the entire configuration from the snapshot, not just individual changes. Any changes made after the snapshot will be lost. Review the snapshot contents before rolling back.

Audit Log Frontend

The audit logs page (Observability > Audit Logs) shows:

  • Pending Changes (un-applied, config-affecting) at the top with an amber badge
  • Other Activity (non-config, no snapshot) — events that don’t require an apply
  • Applied Changes grouped by snapshot below, with expandable groups
  • Earlier applies bucket for events whose snapshot was pruned
  • Each event row has an expandable payload JSON viewer (with truncation indicator)
  • Filters: username, action, resource type, IP address (dropdowns populated from the API), date range, status (all/pending/applied), limit (50/100/250/500)

Export

Audit events can be exported as CSV via GET /audit-events/export. The export respects the current filters and date range. The downloaded filename includes the date range.

Step-by-Step: Review Pending Changes

  1. Navigate to Observability > Audit Logs
  2. Pending (un-applied) changes appear at the top with an amber badge
  3. Review each pending change:
    • Click “Show payload” to expand the request body
    • Check the action, resource, and user
  4. Decide whether to apply or revert before applying

Step-by-Step: Apply and Snapshot

  1. Make configuration changes (e.g. add a listener, update a backend)
  2. Navigate to the Dashboard
  3. Review pending changes in the audit log
  4. Click Apply Changes
  5. Optionally enter a comment for the snapshot
  6. coreX Platform generates, validates, and applies the config
  7. A new snapshot is created and all pending events are linked to it

Step-by-Step: Revert Pending Changes

  1. Navigate to the Dashboard
  2. If there are unapplied changes, the “Unapplied Changes” banner appears
  3. Click Revert (not Apply)
  4. Confirm the revert
  5. All pending changes are discarded — the config returns to the last applied state
  6. The audit events remain visible but are no longer “pending”

Step-by-Step: Rollback to a Previous Config

  1. Navigate to Observability > Audit Logs
  2. Find the snapshot group you want to roll back to
  3. Note the snapshot ID, or use GET /config/snapshots to browse all snapshots
  4. Click Rollback on the snapshot (or call POST /config/snapshots/{id}/rollback)
  5. Confirm the rollback
  6. A new snapshot is created for the rollback action
  7. HAProxy is reloaded with the reverted configuration

Step-by-Step: Preview and Diff Before Applying

  1. Make configuration changes
  2. Check the Dashboard for the “Unapplied Changes” banner
  3. Preview the generated config:
    curl -k https://localhost/api/v1/config/preview
  4. View the diff between applied and generated config:
    curl -k https://localhost/api/v1/config/diff
  5. Review the diff to confirm the changes are correct
  6. Apply or revert based on your review

Step-by-Step: Export Audit Events

  1. Navigate to Observability > Audit Logs
  2. Apply filters (optional): username, action, resource type, IP, date range
  3. Click Export CSV
  4. The file downloads with all matching events (filename includes the date range)

Verification

  1. Make a change and check the audit log:

    # Create a backend (via API or UI)
    curl -k -X POST https://localhost/api/v1/backends -H "Content-Type: application/json" -d '{"name":"test"}'

    Then check the audit logs page — the create_backend event should appear as pending.

  2. Check config status:

    curl -k https://localhost/api/v1/config/status

    Expect: {"unapplied": true} after making a change.

  3. Check config diff:

    curl -k https://localhost/api/v1/config/diff

    Expect: a unified diff showing the changes.

  4. Apply and verify snapshot:

    • Click Apply Changes
    • Check that the event is now linked to a snapshot
    • Verify the snapshot appears in the snapshots list (GET /config/snapshots)
  5. Rollback and verify:

    • Rollback to the previous snapshot
    • Verify the backend no longer exists
    • Check that a rollback event appears in the audit log

Next Steps