Skip to main content

Audit Logs

Audit Logs record activity and changes across your organization for security, compliance, and troubleshooting. Each entry captures who did what, to which record, and when — including the before/after values for updates.

Overview

The Audit Logs page lets you:

  • Browse a paginated, time-ordered list of organization activity (newest first)
  • Filter entries by action type, entity type, and date range
  • Open any entry to see the full change detail, including before/after values
  • See the acting user (or System for automated actions), the source IP address, and the browser user agent

Go to AdminAudit Logs (/admin/audit-logs). This page is restricted to the Owner and Admin roles. Other roles receive a permission error.

Reading the log list

The log table shows the following columns:

ColumnDescription
TimestampRelative time (e.g. "2 hours ago") plus the time of day
UserThe person who performed the action (name and email), or System for automated/background actions
ActionThe action performed, shown as a colored badge with an icon
EntityThe record type affected (e.g. Ticket, Client), with the record's name when available
IP AddressThe source IP of the request, when recorded
ActionsA Details button that opens the full entry

The card header shows the total number of matching entries, and pagination controls (Previous / Next) appear below the table when there is more than one page.

Filtering

Filters appear above the table. Adjusting any filter resets the list to the first page.

FilterOptions
Action TypeAll Actions, Create, Update, Delete, Login, Logout
Entity TypeAll Types, Client, Contact, Ticket, Invoice, Payment, Asset, User, Organization, Integration
Start DateEarliest date to include
End DateLatest date to include

Use Clear Filters to reset all filters at once. The current filters are kept in the page URL, so a filtered view can be bookmarked or shared with another admin.

Action types

Each entry has an action. The most common actions appear with a dedicated badge:

ActionMeaning
CreateA record was created
UpdateA record was modified
DeleteA record was removed
LoginA user signed in
LogoutA user signed out
ViewA record was accessed
RevealA credential's secret (password / OTP secret / live 2FA code) was revealed to a user — distinct from a generic view so credential reveals are directly answerable. The secret value itself is never stored in the log.
SyncData was synchronized (e.g. an integration)
PurgeEntries older than the retention window were archived and removed (see Retention policy)

Other action values are also recorded by the system — including archive, restore, failed login, export, import, access, and permission changes — and display with a generic badge using the raw action name.

Entity details

The Entity column identifies the type of record an action affected. Audit entries can reference many record types, including clients, contacts, tickets, invoices, payments, assets, users, the organization itself, integrations, contracts, projects, documents, domains, certificates, credentials, software, vendors, locations, networks, products, tags, racks, quotes, and opportunities. When the affected record still exists, its name (or number, for invoices and quotes) is shown; otherwise the entry shows a shortened record ID.

Entry detail view

Click Details on any row to open the full entry. The detail dialog shows:

FieldDescription
TimestampThe exact date and time of the action
ActionThe action badge
EntityThe affected record's type and name (or ID)
UserThe acting user's name and email, or System
IP AddressSource IP, when recorded
User AgentThe browser/client string, when recorded
ChangesA field-by-field Before / After comparison for the action

The Changes section only lists fields whose values actually changed. To protect sensitive information, values are cleaned up before an entry is recorded, so they are never exposed in full in the before/after comparison:

  • Secrets — passwords, MFA secrets, API keys, and encrypted values are fully redacted and shown as [REDACTED].
  • Binary data — file contents and similar binary values are replaced with [BINARY DATA].
  • Personal data — fields such as email addresses, phone numbers, government identifiers (for example SSN, tax/VAT, passport), and postal/street data are masked rather than shown in full. Enough is kept to recognize that the field changed — for example an email appears as b***@example.com and a phone number as ***-4567 — without storing the complete personal detail. Security-relevant fields such as the source IP address and user agent are kept in full.

Exporting audit logs

Admins can download a copy of the organization's audit log — for example, to hand to an auditor as evidence or to analyze events outside the app.

Use the Export button at the top of the Audit Logs page, then choose a format:

FormatBest for
Export as CSVOpening in a spreadsheet (Excel, Google Sheets) for filtering and review. One row per event with the core columns: timestamp, action, entity type, entity, the acting user (name and email), and source IP.
Export as JSONMachine processing or a complete record. Includes everything in the CSV plus the browser/client user agent and the full before/after change detail for each event.

The export honors the filters currently applied on the page. If you've set an action type, entity type, user, or a start/end date, only the matching events are included — so to export everything, clear the filters first. The downloaded file is named audit-log-<date>.csv or audit-log-<date>.json.

A single export returns up to 50,000 events in chronological order (oldest first), so it reads as a timeline. If your date range would exceed that, narrow the range (or other filters) and export in batches.

As with the on-screen detail view, sensitive fields (passwords, MFA secrets, API keys, encrypted values) are already redacted in the stored entries, so they are never present in an export.

Exports are themselves logged

Running an export is a security-relevant action, so it is recorded in the audit log as an Export event. The entry captures who performed the export, the date range and filters used, the chosen format, and how many events were included — giving you a complete, tamper-evident record of who accessed audit data and when.

Retention policy

By default Ascent keeps audit entries for 365 days (one year). To change how long they are stored — for example, to meet a data-retention or storage-limitation requirement, or to keep them forever — you can adjust the retention window.

The Retention policy card near the top of the Audit Logs page (visible to Owner and Admin roles) shows the current window and lets you change it:

SettingMeaning
A number of days (e.g. 365)Entries older than this many days are archived and removed from the live log. The supported range is 30–3650 days.
0Retention is disabled — entries are kept forever.

A background job runs once a day. For each organization, it takes every entry older than your window, copies it into a separate cold-storage archive, and then removes it from the live log. The archive preserves the original entries (including their tamper-evidence hash) as evidence — nothing is silently destroyed:

  • The purge itself is recorded as a Purge entry in the log, capturing the cutoff date and how many entries were retired.
  • Because archived entries keep their hash, the integrity check can still tell a legitimate retention purge apart from an unauthorized deletion — removing entries outside the retention policy still shows up as tampering.

Changing the retention window is itself recorded as an Update audit entry, so policy changes are traceable.

High-risk event alerts

Beyond keeping a record, Ascent can watch the audit trail for anomalous activity and notify admins the moment a signal crosses a threshold. The High-risk event alerts card on the Audit Logs page (visible to Owner and Admin roles) tunes the monitor. A master Enable high-risk event monitoring toggle turns the whole feature on or off; each signal below also has its own switch.

The defaults are conservative — chosen so the monitor is safe to leave on without flooding admins — and each threshold is a count within a rolling window (in minutes):

SignalWhat it watchesDefault
Mass deletionsA single user deleting many records in a short burstAlert after 20 deletes within 10 min
Permission/role changesA flurry of permission or role editsAlert after 5 changes within 10 min
Repeated failed sign-insMany failed sign-ins for one member (possible password attack)Alert after 5 failures within 15 min
Audit-log integrity failuresThe tamper-evidence hash chain is checked on a schedule and an alert fires if it ever fails to verifyChecked every 60 min

A shared Re-alert cooldown (default 60 min) suppresses duplicate alerts for the same signal so a single ongoing incident doesn't page repeatedly. When a signal fires, the alert is delivered to admins through the normal notification channels (in-app and, where enabled, email) and links straight to the relevant audit entry.

Integrity verification and external anchoring

Every audit entry is part of a tamper-evidence hash chain: each row is cryptographically linked to the one before it, so a silent edit or deletion made directly in the database — bypassing the application — breaks the chain at a detectable point. The Audit-log integrity failures signal above runs this verification automatically on a schedule, and the chain can also be checked on demand through the admin-only GET /api/audit/verify-integrity endpoint, which reports whether the chain is intact and, if not, the first broken link.

For higher-assurance environments, operators can additionally enable external anchoring ("genesis trust"). When turned on (an operator sets AUDIT_ANCHOR_SINK=database; it is disabled by default), a daily job publishes each organization's current chain head to an append-only, write-once store. The integrity check then cross-checks those anchors and raises a distinct anchor-mismatch finding if a previously anchored head has vanished — the signature of a wholesale log rewrite that an internally consistent chain alone can't catch. Anchoring is defense-in-depth layered on top of the database-level append-only protections, and it is fully compatible with the retention policy — a routine purge never raises a false alarm. See the Trust & Security overview for the full audit-integrity model.

Viewing the logs is itself recorded

Looking at the audit log is a security-relevant action, so opening the Audit Logs page is recorded in the audit log as an Access event attributed to the admin who viewed it. This answers the auditor question "who looked at the logs?".

To keep the trail readable, access is recorded coarsely: paging through results or refreshing the page does not add a new entry each time — at most one Access event is written per admin per hour. To find these entries, filter the Action Type to Access (or the Entity Type to Audit Log Access). These meta-events are scoped to your own organization, just like every other entry.

What gets logged

Audit entries are written automatically as actions occur throughout the application. They are not editable, and individual entries cannot be deleted from this page — the only way entries leave the live log is the retention policy above, which archives them first. Background and integration processes (for example, email sync) are attributed to System rather than a specific user.

Payments are captured however they are recorded: manual payments entered in the app, and online card payments taken through Stripe — whether the customer paid through the public invoice link or the payment was reconciled by a Stripe webhook (such as a refund). Because online and webhook-driven payments are not tied to a signed-in user, they appear as Payment Create entries attributed to System.

Tips

  • Combine the Action Type and Entity Type filters with a date range to narrow an investigation quickly — for example, Delete actions on Ticket records within a specific week.
  • Use the Details view to confirm exactly which fields changed during an Update, rather than relying on the list alone.
  • Because filter state lives in the URL, you can save a frequently used filtered view as a browser bookmark.
  • If a record's name is missing in the Entity column, the underlying record has likely been deleted; the entry still preserves the change history.