Security

Audit Log

Comprehensive audit logging for all security-sensitive operations in AxiomDB — network changes, credential rotations, team modifications, and more.

Audit Log

AxiomDB records every security-sensitive operation in an immutable audit log. The audit log provides full traceability for compliance, incident response, and operational review. Audit events outlive the resources they describe — even after a branch or project is deleted, the audit record persists.


Event Catalog

Project Events

EventDescriptionActor
project.createdA new project was createdOwner
project.deletedProject was permanently deletedOwner
project.settings.updatedProject settings were modifiedOwner/Admin

Branch Events

EventDescriptionActor
branch.createdA new branch was createdAdmin/Developer
branch.deletedA branch was deletedAdmin
branch.credentials.viewedConnection credentials were revealedDeveloper+
branch.credentials.rotatedCredentials were rotatedAdmin
branch.restoredBranch was restored from backupAdmin

Network Events

EventDescriptionActor
network.rule.createdA new CIDR rule was addedAdmin
network.rule.deletedA CIDR rule was removedAdmin
network.policy.changedSecurity mode was changedOwner

Backup Events

EventDescriptionActor
backup.snapshot.createdA backup snapshot was createdSystem
backup.restore.startedA restore operation was initiatedAdmin

Team Events

EventDescriptionActor
team.invitation.createdA member invitation was sentAdmin
team.member.removedA member was removed from the projectAdmin/Owner
team.member.role_changedA member's role was changedAdmin/Owner

Event Schema

Every audit event follows a consistent schema:

{
  "id": "evt_7xK2mP9nQ3w8",
  "event": "branch.credentials.rotated",
  "timestamp": "2026-01-15T10:30:00Z",
  "actor": {
    "id": "usr_8xK2mP",
    "email": "alice@example.com",
    "role": "admin",
    "ip_address": "203.0.113.42",
    "user_agent": "axiom-cli/1.4.0"
  },
  "resource": {
    "type": "branch",
    "project_id": "prj_abc123",
    "project_name": "my-project",
    "branch_id": "br_main",
    "branch_name": "main"
  },
  "details": {
    "target": "both",
    "rotation_id": "rot_9xK2mP3n",
    "previous_rotation": "2025-10-15T10:30:00Z",
    "trigger": "manual"
  },
  "metadata": {
    "request_id": "req_4nR8wP2x",
    "session_id": "ses_3mZ7kF9x",
    "api_token_id": "ptk_xxxxxxxxxxxx"
  }
}

Field reference

FieldTypeDescription
idstringUnique event identifier. Globally unique and immutable.
eventstringEvent type from the catalog above.
timestampISO 8601UTC timestamp of when the event occurred.
actorobjectThe user or system that performed the action.
actor.idstringUser ID or system for automated events.
actor.emailstringEmail address (if human actor).
actor.rolestringRole at the time of the action.
actor.ip_addressstringSource IP address.
actor.user_agentstringClient identifier (CLI, API, dashboard).
resourceobjectThe resource affected by the action.
resource.typestringResource type: project, branch, network_rule, team_member.
resource.project_idstringProject identifier.
resource.branch_idstringBranch identifier (if applicable).
detailsobjectEvent-specific details. Varies by event type.
metadataobjectRequest metadata for correlation.

Querying the Audit Log

Via Dashboard

  1. Navigate to Project Settings → Audit Log.
  2. Use filters to narrow by event type, actor, date range, or resource.
  3. Click any event to see full details.

Via CLI

# List recent events
axiom audit list --project my-project

# Filter by event type
axiom audit list --project my-project --event branch.credentials.rotated

# Filter by actor
axiom audit list --project my-project --actor usr_8xK2mP

# Filter by date range
axiom audit list --project my-project --since "2026-01-01" --until "2026-01-31"

# Filter by resource
axiom audit list --project my-project --branch br_main

# Combine filters
axiom audit list \
  --project my-project \
  --event network.policy.changed \
  --since "2025-06-01" \
  --format json

Via API

curl -G "https://api.axiom.cloud/v1/projects/prj_abc123/audit" \
  -H "Authorization: Bearer ptk_xxxxxxxxxxxx" \
  --data-urlencode "event=branch.credentials.rotated" \
  --data-urlencode "since=2026-01-01T00:00:00Z" \
  --data-urlencode "limit=50" \
  --data-urlencode "cursor=evt_previous_last_id"

Response:

{
  "events": [
    {
      "id": "evt_7xK2mP9nQ3w8",
      "event": "branch.credentials.rotated",
      "timestamp": "2026-01-15T10:30:00Z",
      "actor": {
        "id": "usr_8xK2mP",
        "email": "alice@example.com",
        "role": "admin"
      },
      "resource": {
        "type": "branch",
        "project_id": "prj_abc123",
        "branch_id": "br_main",
        "branch_name": "main"
      },
      "details": {
        "target": "both",
        "rotation_id": "rot_9xK2mP3n"
      }
    }
  ],
  "pagination": {
    "cursor": "evt_7xK2mP9nQ3w8",
    "has_more": true,
    "total": 1247
  }
}

Audit Event Details

project.created

Triggered when a new project is created.

{
  "event": "project.created",
  "details": {
    "project_name": "my-project",
    "region": "us-east-1",
    "postgres_version": "16.1",
    "initial_mode": "restricted"
  }
}

project.deleted

Triggered when a project is permanently deleted. This is irreversible.

{
  "event": "project.deleted",
  "details": {
    "project_name": "my-project",
    "confirmation_typed": true,
    "branches_deleted": 3,
    "backups_deleted": 12,
    "team_members_removed": 5
  }
}

branch.credentials.viewed

Triggered when a user reveals connection credentials.

{
  "event": "branch.credentials.viewed",
  "details": {
    "target": "runtime",
    "credential_type": "url",
    "masked_url": "postgresql://axiom_pooler:****@pooler.axiom.cloud:6432/mydb"
  }
}

branch.credentials.rotated

Triggered when credentials are rotated.

{
  "event": "branch.credentials.rotated",
  "details": {
    "target": "both",
    "rotation_id": "rot_9xK2mP3n",
    "previous_rotation": "2025-10-15T10:30:00Z",
    "trigger": "manual",
    "password_length": 32,
    "password_entropy_bits": 192
  }
}

network.policy.changed

Triggered when the security mode is changed.

{
  "event": "network.policy.changed",
  "details": {
    "previous_mode": "restricted",
    "new_mode": "public_runtime",
    "confirmation_typed": false,
    "requires_confirmation": false
  }
}

network.rule.created

Triggered when a CIDR rule is added.

{
  "event": "network.rule.created",
  "details": {
    "rule_id": "rule_2kF9x3mZ",
    "label": "Office VPN",
    "cidr": "203.0.113.0/24",
    "ports": "both",
    "scope": "project",
    "expires_at": "2026-06-01T00:00:00Z"
  }
}

network.rule.deleted

Triggered when a CIDR rule is removed.

{
  "event": "network.rule.deleted",
  "details": {
    "rule_id": "rule_7pQ4nR8w",
    "label": "CI Runner",
    "cidr": "198.51.100.0/24",
    "reason": "manual",
    "expired": false
  }
}

backup.snapshot.created

Triggered when a backup snapshot is created.

{
  "event": "backup.snapshot.created",
  "details": {
    "snapshot_id": "snap_3mZ7kF9x",
    "branch_id": "br_main",
    "size_bytes": 1073741824,
    "type": "automatic",
    "retention_days": 30
  }
}

backup.restore.started

Triggered when a restore operation is initiated.

{
  "event": "backup.restore.started",
  "details": {
    "restore_id": "rst_4nR8wP2x",
    "source_snapshot": "snap_3mZ7kF9x",
    "target_branch": "br_main",
    "point_in_time": "2026-01-14T23:59:00Z",
    "estimated_duration_seconds": 120
  }
}

team.invitation.created

Triggered when a member invitation is sent.

{
  "event": "team.invitation.created",
  "details": {
    "invitation_id": "inv_7xK2mP9n",
    "email": "bob@example.com",
    "role": "developer",
    "expires_at": "2026-01-22T10:30:00Z"
  }
}

team.member.role_changed

Triggered when a member's role is changed.

{
  "event": "team.member.role_changed",
  "details": {
    "member_id": "usr_bob456",
    "member_email": "bob@example.com",
    "previous_role": "developer",
    "new_role": "admin"
  }
}

Retention Policy

PolicyDuration
Default retention2 years
Extended retention7 years (on request)
Minimum retention1 year
Branch deletionEvents persist
Project deletionEvents persist

Events outlive resources

Audit events are stored independently of the resources they describe. Deleting a branch does not delete its audit history. This ensures compliance even after resource cleanup.


Exporting Audit Data

CSV export

axiom audit export \
  --project my-project \
  --format csv \
  --since "2026-01-01" \
  --until "2026-01-31" \
  --output audit-january.csv

JSON export

axiom audit export \
  --project my-project \
  --format json \
  --since "2026-01-01" \
  --until "2026-01-31" \
  --output audit-january.json

Streaming to external systems

# Stream to stdout for piping to external systems
axiom audit stream \
  --project my-project \
  --event branch.credentials.rotated,network.policy.changed \
  --format jsonl | \
  jq -c '.event' | \
  # Send to your SIEM

Integration with SIEM

AxiomDB audit events can be integrated with security information and event management (SIEM) systems:

Webhook delivery

{
  "webhook": {
    "url": "https://siem.example.com/api/events",
    "events": ["*"],
    "format": "json",
    "headers": {
      "Authorization": "Bearer siem_token_xxxxx",
      "X-Source": "axiomdb"
    },
    "retry": {
      "max_attempts": 3,
      "backoff_seconds": [10, 60, 300]
    }
  }
}

Setting up a webhook

axiom audit webhook create \
  --project my-project \
  --url "https://siem.example.com/api/events" \
  --events "*" \
  --header "Authorization: Bearer siem_token_xxxxx"

Alerting

Configure alerts for high-severity audit events:

{
  "alerts": [
    {
      "name": "Public mode enabled",
      "event": "network.policy.changed",
      "condition": "details.new_mode == 'public_all'",
      "channels": ["email", "slack"],
      "recipients": ["security@example.com"]
    },
    {
      "name": "Credential rotation",
      "event": "branch.credentials.rotated",
      "channels": ["slack"],
      "recipients": ["#ops-alerts"]
    },
    {
      "name": "Project deleted",
      "event": "project.deleted",
      "channels": ["email", "slack", "pagerduty"],
      "recipients": ["security@example.com", "#ops-alerts"]
    }
  ]
}

Creating an alert via CLI

axiom audit alert create \
  --project my-project \
  --name "Public mode enabled" \
  --event "network.policy.changed" \
  --condition "details.new_mode == 'public_all'" \
  --channel email \
  --recipient "security@example.com"

Compliance

The audit log is designed to support compliance with common frameworks:

FrameworkRelevant Controls
SOC 2 Type IICC6.1 (Logical access), CC7.2 (Monitoring), CC8.1 (Change management)
HIPAA§164.312(b) (Audit controls), §164.308(a)(1)(ii)(D) (Information system activity review)
GDPRArticle 30 (Records of processing activities), Article 5(2) (Accountability)
PCI DSSRequirement 10 (Track and monitor all access)
ISO 27001A.12.4.1 (Event logging), A.12.4.3 (Protection of log information)

Best Practices

  1. Review regularly. Schedule weekly or monthly reviews of the audit log.
  2. Set up alerts. Get notified immediately for high-severity events.
  3. Export for compliance. Archive audit exports alongside your compliance documentation.
  4. Correlate with other systems. Integrate with your SIEM for cross-system visibility.
  5. Monitor for anomalies. Look for unusual patterns: credential rotations from new IPs, public mode changes, bulk deletions.
  6. Restrict access. Only grant audit:read to team members who need it.

Troubleshooting

Missing events

Cause: The event was filtered out by your query parameters.

Fix: Remove filters and search by timestamp or actor:

axiom audit list --project my-project --since "2026-01-15T10:00:00Z" --until "2026-01-15T11:00:00Z"

Webhook delivery failures

axiom audit webhook status --project my-project
WEBHOOK                STATUS    LAST DELIVERY        FAILURES
https://siem...        active    2026-01-15T10:30Z    0

Fix: Check the webhook endpoint is reachable and returning 2xx status codes.

Export timeout

Cause: Large date ranges may time out.

Fix: Export in smaller chunks:

axiom audit export --project my-project --since "2026-01-01" --until "2026-01-15" --output part1.json
axiom audit export --project my-project --since "2026-01-16" --until "2026-01-31" --output part2.json

On this page