---
title: Audit Logs
path: api-guides/audit-logs
status: published
---

# Audit Logs

Query, summarize, and export the audit log. Every action in ScaiVault — reads, writes, rotations, policy changes, certificate issuance, dynamic leases — has an audit entry.

**Base path:** `/v1/audit/`

## Query

```bash
curl -H "Authorization: Bearer $TOKEN" \
     "https://scaivault.scailabs.ai/v1/audit/logs?from=2026-04-22T00:00:00Z&to=2026-04-23T00:00:00Z&action=read&limit=100"
```

```python
resp = httpx.get(
    "https://scaivault.scailabs.ai/v1/audit/logs",
    headers={"Authorization": f"Bearer {os.environ['SCAIVAULT_TOKEN']}"},
    params={
        "from": "2026-04-22T00:00:00Z",
        "to": "2026-04-23T00:00:00Z",
        "action": "read",
        "limit": 100,
    },
)
for log in resp.json()["logs"]:
    print(log["timestamp"], log["identity_id"], log["secret_path"])
```

```typescript
const params = new URLSearchParams({
  from: "2026-04-22T00:00:00Z",
  to: "2026-04-23T00:00:00Z",
  action: "read",
  limit: "100",
});
const resp = await fetch(
  `https://scaivault.scailabs.ai/v1/audit/logs?${params}`,
  { headers: { "Authorization": `Bearer ${process.env.SCAIVAULT_TOKEN}` } },
);
const { logs } = await resp.json();
```

Response:

```json
{
  "logs": [
    {
      "id": "log_aaa111",
      "timestamp": "2026-04-23T18:00:00.123456Z",
      "action": "read",
      "secret_path": "environments/production/salesforce/api-credentials",
      "identity_type": "service_account",
      "identity_id": "sa:reporting-service",
      "source_ip": "10.0.1.50",
      "user_agent": "scaivault-python/1.0.0",
      "success": true,
      "duration_ms": 12,
      "request_id": "req_xyz"
    }
  ],
  "cursor": "eyJpZCI6MTc4fQ",
  "has_more": true
}
```

### Filters

| Parameter | Description |
|-----------|-------------|
| `from` / `to` | ISO 8601 timestamps |
| `action` | `read`, `write`, `delete`, `list`, `rotate`, `policy_create`, `policy_update`, `policy_delete`, `policy_bind`, `policy_unbind`, `pki_issue`, `pki_revoke`, `dynamic_generate`, `dynamic_revoke` |
| `identity_id` | Exact match |
| `identity_type` | `user`, `service_account`, `group` |
| `path_prefix` | Filter to secrets under a path |
| `success` | `true` or `false` |
| `source_ip` | Exact match |
| `request_id` | Exact match (e.g. finding one trace) |
| `limit` | Default 100, max 1000 |
| `cursor` | Pagination |

## Audit trail for a secret

Every access to one secret over time:

```bash
curl -H "Authorization: Bearer $TOKEN" \
     https://scaivault.scailabs.ai/v1/audit/secrets/environments/production/salesforce/api-credentials
```

Response:

```json
{
  "secret_path": "environments/production/salesforce/api-credentials",
  "logs": [...],
  "summary": {
    "total_reads_30d": 1547,
    "total_writes_30d": 2,
    "unique_accessors_30d": 12,
    "last_read": "2026-04-23T18:00:00Z",
    "last_write": "2026-04-20T14:22:00Z"
  }
}
```

Useful for compliance questions ("who has read this secret in the last quarter?").

## Audit trail for an identity

Every action one identity took:

```bash
curl -H "Authorization: Bearer $TOKEN" \
     "https://scaivault.scailabs.ai/v1/audit/identities/user:alice@acme.example?from=2026-04-01T00:00:00Z"
```

Response:

```json
{
  "identity_id": "user:alice@acme.example",
  "logs": [...],
  "summary": {
    "total_actions_30d": 234,
    "secrets_accessed_30d": 15,
    "last_activity": "2026-04-23T18:00:00Z"
  }
}
```

Useful for offboarding: when an employee leaves, pull their trail, rotate anything they touched.

## Summary statistics

```bash
curl -H "Authorization: Bearer $TOKEN" \
     "https://scaivault.scailabs.ai/v1/audit/summary?from=2026-04-01T00:00:00Z&to=2026-05-01T00:00:00Z"
```

Response:

```json
{
  "total_events": 125432,
  "successful_events": 124890,
  "failed_events": 542,
  "actions_breakdown": {
    "read": 98321,
    "write": 1432,
    "delete": 54,
    "rotate": 28,
    "policy_update": 12
  },
  "top_identities": [
    {"identity_id": "sa:reporting-service", "count": 35000},
    {"identity_id": "sa:billing-service", "count": 28000}
  ],
  "top_resources": [
    {"path": "integrations/salesforce/oauth", "count": 15000}
  ]
}
```

Good for dashboards and anomaly baselines.

## Export

For long-term archival or offline analysis, export to an object store:

```bash
curl -X POST https://scaivault.scailabs.ai/v1/audit/export \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "2026-01-01T00:00:00Z",
    "to": "2026-01-31T23:59:59Z",
    "format": "jsonl",
    "destination": {
      "type": "s3",
      "bucket": "audit-exports",
      "prefix": "scaivault/2026-01/",
      "credentials_path": "infra/aws/audit-exports/writer"
    }
  }'
```

Formats: `jsonl` (one event per line), `csv` (flat, column-heavy).

Destinations: `s3`, `gcs`, `azure_blob`. Credentials come from a ScaiVault secret — the export doesn't take inline AWS keys.

Response:

```json
{
  "export_id": "exp_abc",
  "status": "pending",
  "estimated_records": 125432,
  "created_at": "2026-04-23T18:00:00Z"
}
```

Poll status:

```bash
curl -H "Authorization: Bearer $TOKEN" \
     https://scaivault.scailabs.ai/v1/audit/exports/exp_abc
```

When `status: "completed"`, the manifest lists the written files.

## Retention

By default, ScaiVault retains audit logs for **7 years**. Older entries are moved to cold storage (if configured) or deleted. Configure retention per tenant in the admin UI under **Audit → Retention**.

Exports are your responsibility to retain — ScaiVault uploads them and doesn't track them afterward.

## What the audit log records

Every entry includes:

- **Who.** Identity ID, type, session tracking.
- **What.** Action name, resource path.
- **When.** Timestamp with microsecond precision.
- **Where.** Source IP, user agent.
- **How.** Request ID, HTTP method, status, duration.
- **Outcome.** Success / failure, error code if failed.
- **Context.** Extra data per action (e.g. `rotation_reason`, `policy_violation_condition`).

Reads of secret values include the path but *not* the value. The audit log is never a place where secrets leak.

## What the audit log does *not* record

- Reads of audit logs themselves (to avoid recursive noise — set up a separate SIEM destination if you need this).
- Health check requests.
- Identity cache-sync events (visible under `/v1/identity/sync/history`).

## Common questions

**"Who accessed this secret in the last week?"**
`GET /v1/audit/secrets/{path}?from=<7d ago>&action=read` — returns identities and times.

**"Did this policy change break anyone?"**
Filter to `action=read` with `success=false` around the policy change time. Failed reads after a policy tightening often indicate broken service accounts.

**"What did this ex-employee touch?"**
`GET /v1/audit/identities/user:person@acme.example?from=<hire date>` — and rotate anything on the list.

**"What happened during the incident at 14:30?"**
`GET /v1/audit/logs?from=<14:25>&to=<14:35>` — slice the 10-minute window for inspection.

## What's next

- [Events and Webhooks](../core-concepts/events-and-webhooks) — real-time stream, not just after-the-fact query.
- [Audit Logs Reference](../reference/audit) — endpoints.
