Audit Logs
How TMA Cloud records audit events and how to query them.
How TMA Cloud records audit events and how to query them.
Overview
TMA Cloud records authentication, file, sharing, document, admin, and account events in the audit_log table.
Recording an event never slows a request down. Each process (the API and the worker) hands its events to an in-memory buffer, and a writer task saves them in batches: up to 200 events in one insert, at least every half second. Events still in the buffer are written when the process shuts down normally.
If a batch fails, its events are retried one at a time, so one bad row does not lose the others. An event whose user was deleted in the meantime is saved without the user. If the buffer is full (10,000 events waiting), new events go to the application log instead and a warning is logged.
Configuration
There is nothing to configure and no separate process to run: audit writing is part of tma-server serve and tma-server worker. Retention is handled by the daily audit log cleanup; see Background Workers.
Audit Events
Audit Events is the complete catalog with metadata fields. The summary below groups them by area.
Authentication Events
auth.signup,auth.login,auth.login.failureauth.logout,auth.logout_allauth.session_revoked,auth.other_sessions_revokedauth.password_change
File Events
file.upload,file.upload.bulkfile.download,file.download.bulkfile.update- contents replaced in placefile.delete,file.restore, and.queuedvariants for work handed to the workerfile.rename,file.move,file.copy.queued,file.delete.permanent.queuedfile.star,file.unstarfile.lock,file.unlock- editing locks
Folder Events
folder.create,folder.download
Share Events
share.create,share.deleteshare.access- anonymous view of a share linkshare.download- download through a share link
Document Events (OnlyOffice)
document.open,document.save
Admin Events
admin.settings.update,admin.settings.readadmin.user.list,admin.user.updateadmin.orphans.scan,admin.orphans.delete
Account Events
account.sub_user.create,account.sub_user.update,account.sub_user.deleteaccount.permission_denied- Sub-user attempted something it was not grantedaccount.owner_action_denied- Sub-user attempted an owner-only action
Identifying the Actor
Events are written to the audit_log table. Three columns describe who acted:
user_id- The login that performed the action. For a sub-user this is its own ID, never the owner's.account_owner_id- The account the action happened under. Equalsuser_idfor account owners.actor_role-ownerorsub_user.
The audit_activity view resolves these to names and emails, which is usually easier to read than raw IDs.
SELECT created_at, actor_email, actor_role, action, status
FROM audit_activity
WHERE account_email = 'owner@example.com'
ORDER BY created_at DESC
LIMIT 100;Querying Audit Logs
View User Activity
SELECT action, status, metadata, created_at
FROM audit_log
WHERE user_id = 'user_abc123'
ORDER BY created_at DESC;View Everything Under One Account
Includes the owner and all of its sub-users.
SELECT created_at, user_id, actor_role, action, resource_id
FROM audit_log
WHERE account_owner_id = 'user_abc123'
ORDER BY created_at DESC;View Failed Operations
SELECT action, user_id, metadata, created_at
FROM audit_log
WHERE status = 'failure'
ORDER BY created_at DESC;View Permission Denials
Useful when a sub-user reports that something is missing from their interface.
SELECT created_at, actor_email, metadata->>'permission' AS permission,
metadata->>'path' AS path
FROM audit_activity
WHERE action = 'account.permission_denied'
ORDER BY created_at DESC;View File Operations
SELECT action, user_id, metadata->>'fileName' as file_name, created_at
FROM audit_log
WHERE resource_type = 'file'
AND action LIKE 'file.%'
ORDER BY created_at DESC;Search by Metadata
-- Find operations on specific file
SELECT * FROM audit_log
WHERE metadata @> '{"fileId": "file_123"}'::jsonb
AND created_at >= NOW() - INTERVAL '30 days'
ORDER BY created_at DESC;
-- Find large file uploads
SELECT user_id, metadata->>'fileName' as file_name,
(metadata->>'fileSize')::bigint as size, created_at
FROM audit_log
WHERE action = 'file.upload'
AND created_at >= NOW() - INTERVAL '30 days'
AND (metadata->>'fileSize')::bigint > 10485760
ORDER BY created_at DESC;
-- Find bulk uploads (e.g. folder uploads)
SELECT user_id,
metadata->>'fileCount' as file_count,
metadata->>'parentId' as parent_id,
created_at
FROM audit_log
WHERE action = 'file.upload.bulk'
AND created_at >= NOW() - INTERVAL '30 days'
ORDER BY created_at DESC;metadata has no general GIN index because the application does not filter on arbitrary JSON fields. Constrain administrative searches by indexed columns such as action, user_id, account_owner_id, or created_at before inspecting metadata.
Checking That Events Are Written
audit_last_processed_timestampandaudit_events_processed_totalon/metricsshow the last write and the total.audit_events_failed_totalcounts events that could not be saved.- Failures are logged as
Audit batch failed; retrying row by rowandFailed to write audit event. - A full buffer is logged as
Audit queue unavailable, event logged to application log only.
Related Topics
- Logging - Application logging
- Monitoring - System monitoring
- Reference: Audit Events - Complete event list
- Database Schema -
audit_logcolumns and theaudit_activityview
Last updated on