Audit logs
In an environment where human team members, transactional agents, automation scripts, Sati, and external AI agents via Remote MCP operate simultaneously on business tables, immutable traceability is a core governance pillar.
1. The platform_audit_logs Table (Single Source of Truth for Auditing)
Whenever a record is created (CREATE), updated (UPDATE), deleted (DELETE), or restored (RESTORE) in the workspace, database triggers automatically record an immutable entry in platform_audit_logs.
Strict Permissions on platform_audit_logs:
- Read-Only (
SELECT) & Immutable: Neither Sati nor the MCP server (nor any user or automation script) hasinsert,update, ordeletepermissions onplatform_audit_logs. - RBAC Scope: Queryable by users with role
Owner,Admin, orStaffmembers granted read permission on the'settings'module.
Exact Column Schema of platform_audit_logs:
| Column | Type | Description |
|---|---|---|
id | uuid | Unique audit event ID. |
actor_type | text | Actor type that executed the action: 'human' (user in Web/Mobile UI), 'agent' (Sati, MCP, or transactional agent), 'automation' (script in automation_scripts), or 'system'. |
actor_id | uuid | UUID of the actor that executed the operation (user_id when 'human', agent_id when 'agent', script_id when 'automation'). |
prompted_by | uuid (nullable) | UUID of the authenticated human user who instructed the action when executed by Sati or via Remote MCP (Human + AI co-authorship). |
batch_id | uuid (nullable) | Unique batch identifier grouping all rows created or modified within a single tool execution. |
action | text | Executed operation: 'CREATE', 'UPDATE', 'DELETE', or 'RESTORE'. |
entity_slug | text | Affected table or entity slug (e.g., 'pedidos', 'clientes', 'productos', 'satia_docs', 'agent', 'channel'). (Note: the column name is entity_slug; there is NO entity_type column). |
record_id | uuid | UUID of the specific record that was created, modified, deleted, or restored. (Note: the column name is record_id; there is NO entity_id column). |
reason | text (nullable) | Human instruction or reason that originated the change (e.g., "[MCP: Cursor MacBook] Update order status to confirmed"). |
changes | jsonb | Exact before-and-after diff of the operation: {"old": {...}, "new": {...}}. On 'CREATE', contains {"new": {...}}; on 'DELETE', contains {"old": {...}}. (Note: the column name is changes; there is NO metadata column). |
created_at | timestamptz | Exact UTC timestamp of the event. |
Key entity_slug Values:
- Business tables: Use the business table's
slugdirectly (e.g.,'clientes','pedidos','productos','citas'). - Knowledge documents (Satia Docs): Logged under
entity_slug = 'satia_docs'. - Agents and Channels: Logged under
entity_slug = 'agent'andentity_slug = 'channel'.
2. Co-Authorship (prompted_by), Batch Correlation (batch_id), and user_prompt
- Human + AI Co-Authorship (
actor_id+prompted_by):- When a team member asks Sati or an MCP client to create or modify records (in business tables, agents, or
knowledge_docs), the row inplatform_audit_logsrecordsactor_type = 'agent',actor_id = <Agent UUID>, andprompted_by = <Human User UUID>. - Furthermore,
knowledge_docstracks both the human creator and the AI co-pilot, displaying the co-authorship badge in the/knowledgeUI.
- When a team member asks Sati or an MCP client to create or modify records (in business tables, agents, or
- Batch Correlation (
batch_id):- When an operation modifies multiple rows in a single call (for example, a batch
database__insertof 30 products or adatabase__updateaffecting multiple orders), the engine generates a sharedbatch_idacross allplatform_audit_logsevents produced by that operation.
- When an operation modifies multiple rows in a single call (for example, a batch
- Mandatory Human Attribution in MCP (
user_prompt→reason):- All mutation and delegation tools on the Remote MCP server require the
user_promptparameter. - The MCP server automatically prefixes the Personal Access Token name (
[MCP: <KeyName>] <user_prompt>) into thereasoncolumn of allplatform_audit_logsrows under thatbatch_id, and logs a trace entry in Sati's conversation history so the workspace owner has full visibility into actions performed from external MCP clients.
- All mutation and delegation tools on the Remote MCP server require the
3. How to Revert or Restore Changes (RESTORE)
When a user wants to undo an accidental change (an unintended edit, creation, or deletion of a record):
- One-Click Restore from the Web UI (Native
RESTORE):- In the audit timeline (available inside the detail view of any business record or Satia Doc as well as in the global Audit panel), every event has a "Restore" (
Restaurar) button. - Clicking it automatically reverses the operation (
UPDATEreverts tochanges.old,DELETEre-inserts the record preserving its originalidand all relationships, andCREATEdeletes the newly created record) and writes a new entry inplatform_audit_logswithaction = 'RESTORE'.
- In the audit timeline (available inside the detail view of any business record or Satia Doc as well as in the global Audit panel), every event has a "Restore" (
- Assisted Restore via Sati or MCP (Using
changes->'old'):- If the user asks in chat "Revert the price or fields of record X back to what they were before the last change", you can:
- Run
SELECT id, action, changes, created_at FROM platform_audit_logs WHERE record_id = 'RECORD-UUID' ORDER BY created_at DESC LIMIT 5. - Inspect the
changes->'old'object to identify the exact previous values. - If the record exists and was an
UPDATE, calldatabase__updateon the business table with the previous values extracted fromchanges->'old'. If it was a complexDELETEor the user wants a fullRESTOREpreserving the original UUID, also let them know they can click "Restore" on that event in the web audit history.
- Run
- If the user asks in chat "Revert the price or fields of record X back to what they were before the last change", you can:
4. Forensic Audit SQL Recipes (database__query)
Use these queries with database__query to answer questions like "Who changed the price of this product?", "What did the automation do today?", or "What changes were made via MCP?":
-- 1. Complete change history of a specific record (with actor, human co-author, and diff)
SELECT id, actor_type, actor_id, prompted_by, batch_id, action, reason, changes, created_at
FROM platform_audit_logs
WHERE record_id = 'RECORD-UUID'
ORDER BY created_at DESC
LIMIT 20
-- 2. Audit the latest modifications on a specific business table (e.g., 'pedidos')
SELECT id, actor_type, actor_id, prompted_by, action, record_id, reason, changes, created_at
FROM platform_audit_logs
WHERE entity_slug = 'pedidos'
ORDER BY created_at DESC
LIMIT 30
-- 3. Inspect all records affected within a single batch operation (batch_id)
SELECT id, entity_slug, action, record_id, reason, changes, created_at
FROM platform_audit_logs
WHERE batch_id = 'BATCH-UUID'
ORDER BY created_at ASC
LIMIT 100
-- 4. Audit changes executed by Python automation scripts
SELECT id, actor_id AS script_id, entity_slug, action, record_id, changes, created_at
FROM platform_audit_logs
WHERE actor_type = 'automation'
ORDER BY created_at DESC
LIMIT 30
-- 5. Audit all recent actions executed via Remote MCP
SELECT id, actor_id, prompted_by, batch_id, entity_slug, action, record_id, reason, created_at
FROM platform_audit_logs
WHERE reason ILIKE '[MCP:%'
ORDER BY created_at DESC
LIMIT 30
5. Audit Retention Windows
By default, all workspaces include 30 days of free audit retention in platform_audit_logs. Workspaces with extended compliance or forensic auditing requirements can configure retention windows of 60, 90, 180, or 365 days at Settings > Billing (/settings/billing) (see the billing manual for retention add-on pricing).