Audit Log

TameFlare maintains an append-only audit log that records every action request, policy decision, approval, execution, and system event. This page covers the audit architecture, schema, retention, export, and compliance evidence.


Architecture

Append-only design

The audit log is append-only. There is no API to delete, modify, or overwrite audit events. Every event is written once and never changed.

PropertyStatus
Append-only writesYes - INSERT only, no UPDATE or DELETE
Delete APINone - no endpoint exists to delete audit events
Modification APINone - events are immutable after creation
Cryptographic chainingNot implemented - events are not hash-chained. A database admin with direct SQLite access could theoretically modify or delete rows.
TimestampsServer-side UTC - set by the control plane, not the agent
OrderingMonotonic - events are inserted in order with auto-incrementing IDs
Note
TameFlare's audit log provides application-level immutability (no API to modify events) but not cryptographic immutability (no hash chain or Merkle tree). For regulatory compliance requiring tamper-evident logs, export events to an external SIEM with its own integrity guarantees.

What gets logged

Every significant action in TameFlare creates an audit event:

TriggerEvent typeLogged by
Agent requests an actionaction.requestedControl plane
Policy evaluates an actionaction.allowed, action.deniedControl plane
Action requires approvalaction.pending_approvalControl plane
Human approves/deniesapproval.respondedControl plane
Action is executed via gatewayaction.executedControl plane
Kill switch toggledkill_switch.activated, kill_switch.deactivatedControl plane
Agent registered/suspended/revokedagent.registered, agent.suspended, agent.revokedControl plane
Policy created/updated/deletedpolicy.created, policy.updated, policy.deletedControl plane
Gateway created/updatedgateway.created, gateway.updatedControl plane
User login/logoutuser.login, user.logoutControl plane
Config export/importconfig.exported, config.importedControl plane

Event schema

Every audit event contains these fields:

FieldTypeExampleDescription
idstringevt_abc123Unique event ID
event_typestringaction.deniedEvent type (see list above)
org_idstringorg_xyzOrganization ID
agent_idstringagent_deploy_botAgent that triggered the event (if applicable)
user_idstringuser_abcUser that triggered the event (if applicable)
action_request_idstringact_def456Related action request (if applicable)
detailsJSON{"decision": "deny", ...}Event-specific payload
created_atdatetime2026-02-08T20:00:00ZUTC timestamp

Event-specific details

action.requested

{
  "action_type": "github.pr.merge",
  "resource": {"provider": "github", "target": "acme/api", "environment": "production"},
  "parameters": {"pull_number": 42},
  "risk_score": 45,
  "risk_hints": {"production_target": true, "irreversible": false}
}

action.denied

{
  "decision": "deny",
  "reason": "Cannot delete protected branches",
  "matched_policy": "pol_github_branch_safety",
  "matched_rule": "block-protected-branch-deletion",
  "risk_score": 85
}

action.allowed

{
  "decision": "allow",
  "reason": "Development actions are auto-approved",
  "matched_policy": "pol_github_branch_safety",
  "matched_rule": "allow-dev-actions",
  "decision_token_kid": "configured_key",
  "risk_score": 10
}

approval.responded

{
  "approved": true,
  "responded_by": "alice@company.com",
  "response_time_seconds": 45,
  "note": "Reviewed PR, looks good"
}

kill_switch.activated

{
  "scope": "all",
  "activated_by": "alice@company.com",
  "reason": "Suspicious agent behavior detected"
}

Complete event type list

Event typeCategoryDescription
action.requestedActionsAgent submitted an action request
action.allowedActionsPolicy evaluation returned allow
action.deniedActionsPolicy evaluation returned deny
action.pending_approvalActionsAction requires human approval
action.executedActionsAction was executed via gateway
action.execution_failedActionsGateway execution failed
approval.respondedApprovalsHuman approved or denied a pending action
approval.expiredApprovalsApproval timed out (5 min)
kill_switch.activatedKill switchKill switch turned on
kill_switch.deactivatedKill switchKill switch turned off
agent.registeredAgentsNew agent created
agent.suspendedAgentsAgent suspended
agent.activatedAgentsAgent reactivated
agent.revokedAgentsAgent permanently revoked
policy.createdPoliciesNew policy created
policy.updatedPoliciesPolicy definition or metadata updated
policy.deletedPoliciesPolicy deleted
policy.enabledPoliciesPolicy enabled
policy.disabledPoliciesPolicy disabled
gateway.createdGatewaysNew gateway configured
gateway.updatedGatewaysGateway settings updated
user.loginAuthUser logged into dashboard
user.logoutAuthUser logged out
user.registeredAuthNew user account created
config.exportedConfigConfiguration exported
config.importedConfigConfiguration imported

Retention

Per-tier retention

TierDefault retentionConfigurable?
Starter (free)30 daysYes, via AUDIT_RETENTION_DAYS
Pro ($29/mo)90 daysYes
Team ($79/mo)1 yearYes
EnterpriseCustomYes

Cleanup job

Audit events older than the retention period are purged by the maintenance cleanup job:

# Manual cleanup
curl -X POST \
  -H "Authorization: Bearer $MAINTENANCE_SECRET" \
  https://tameflare.com/api/maintenance/cleanup

The cleanup job purges:

  • Audit events older than AUDIT_RETENTION_DAYS
  • Expired session tokens
  • Used nonces older than 24 hours

Automated cleanup (cron)

# Daily at 3 AM
0 3 * * * curl -sf -X POST -H "Authorization: Bearer $MAINTENANCE_SECRET" https://tameflare.com/api/maintenance/cleanup

What happens after retention

  • Events are permanently deleted from the SQLite database
  • No archive is created automatically - export before retention expires if you need long-term storage
  • The cleanup is irreversible
Warning
If you need audit events beyond the retention period, export them before they expire. TameFlare does not archive events automatically.

Export

CSV export (dashboard)

  1. Navigate to Audit Log in the dashboard
  2. Apply filters (event type, date range, agent)
  3. Click Export CSV

The CSV includes all fields: event ID, type, agent, user, timestamp, and the full details JSON.

CSV export (API)

curl -H "Cookie: session=YOUR_SESSION" \
  "https://tameflare.com/api/dashboard/audit-export?event_type=action.denied&from=2026-01-01&to=2026-02-01" \
  > denied-actions-jan.csv

Query parameters:

  • event_type - filter by event type
  • from / to - date range (ISO 8601)
  • agent_id - filter by agent

Webhook forwarding

Configure webhook_url on action requests to receive real-time event notifications:

{
  "action_spec": { "type": "github.pr.merge", ... },
  "webhook_url": "https://your-siem.example.com/ingest/TameFlare"
}

TameFlare sends a POST to the webhook URL when the action is decided (allowed, denied, or approved). The payload includes the full action spec, decision, and audit metadata.

SIEM integration

SIEMIntegration method
SplunkWebhook forwarding to Splunk HEC endpoint
DatadogWebhook forwarding to Datadog Log API, or CSV export + Datadog Agent
Elastic/ELKWebhook forwarding to Logstash HTTP input, or CSV import
Sumo LogicWebhook forwarding to HTTP Source
CustomWebhook to any HTTP endpoint, or periodic CSV export via cron

There is no native syslog output. For syslog integration, use a webhook-to-syslog bridge or export CSV and ingest via your SIEM's file collector.


Compliance evidence

Proving the approval chain

For auditors who need to verify that an action was properly authorized, TameFlare provides a complete chain of evidence:

1. action.requested  - Agent submitted the request (timestamp, action spec, risk score)
2. action.denied OR action.pending_approval - Policy evaluation result (matched policy, rule, reason)
3. approval.responded - Human approved/denied (who, when, note)
4. action.executed   - Gateway executed the action (timestamp, upstream status)

Generating an audit trail for a specific action

# Get all events for a specific action request
curl -H "Cookie: session=YOUR_SESSION" \
  "https://tameflare.com/api/dashboard/audit-export?action_request_id=act_abc123" \
  > action-trail.csv

Or view in the dashboard: Actions → (click action) → Audit Timeline

The action detail page shows the complete timeline:

StepEventTimestampActor
1Action requested2026-02-08 14:00:00 UTCDevOps Bot
2Policy evaluated → requires_approval2026-02-08 14:00:00 UTCpol_github_branch_safety
3Approval requested2026-02-08 14:00:01 UTCSlack notification sent
4Approved by alice@company.com2026-02-08 14:02:15 UTCalice@company.com
5Executed via gateway2026-02-08 14:02:16 UTCGateway (github connector)
6Upstream response: 200 OK2026-02-08 14:02:17 UTCapi.github.com

What TameFlare can prove

ClaimEvidence
"This action was authorized by policy"action.allowed event with matched_policy and matched_rule
"A human approved this action"approval.responded event with responded_by email and timestamp
"This action was blocked"action.denied event with reason and matched_policy
"The kill switch was active during this period"kill_switch.activated and kill_switch.deactivated events with timestamps
"This agent was suspended"agent.suspended event with timestamp and user

What TameFlare cannot prove

ClaimLimitation
"The audit log has not been tampered with"No cryptographic chaining. Direct DB access could modify events.
"This is the complete set of events"Events can be deleted via direct DB access or retention cleanup.
"The timestamps are accurate"Timestamps are server-side. Clock skew is possible.

For regulatory environments requiring tamper-evident logs, export events in real-time to an external SIEM with cryptographic integrity (e.g., AWS CloudTrail, Splunk with hash verification).


Next steps