Skip to main content

Audit Log

Every access check, mutation, and key rotation is recorded in an append-only log with per-record HMAC signatures. Verify integrity independently — no trust in the database required.

Event-driven architecture​

Audit logging is fully asynchronous. The request path fires an event into SQS and moves on — logging never adds latency to access checks.

Hot path (DynamoDB): real-time queryable for 7–180 days depending on your subscription tier. Records carry a ttl field — DynamoDB auto-deletes them on expiry.

Cold path (S3): as records expire from DynamoDB, the stream triggers the archive Lambda. Records are grouped by (org, day), gzip'd, and written to S3 with GLACIER_IR storage class and Object Lock (COMPLIANCE or GOVERNANCE per org). Cold retention ranges from 0–360 days.

Failure handling: every stage has a DLQ. Messages that fail 3 processing cycles go to a parking queue — never silently discarded.

Retention by tier​

TierHot (DynamoDB)Cold (S3 Archive)
Free7 daysNone
Starter30 daysNone
Growth30 days60 days
Business90 days90 days
Scale180 days180 days
Enterprise180 days*360 days

*Enterprise tier can override hot retention per-org via subscription settings.

HMAC signing​

Every record is independently signed with HMAC-SHA256 using a per-stage secret. The signing payload is:

eventType|ISO_8601_timestamp|actor|result|action|scopeId|resourceType|resourceId

The signature is stored on the DynamoDB record. An auditor can recompute it to prove no record was modified. Each record stands alone — there's no hash chain linking records together, so records can be verified individually or in bulk without traversing the full history.

What gets logged​

Every mutation, access check, and system event is recorded with: who, what, when, result, and an HMAC signature.

RBAC operations​

EventTrigger
permission.created, .updated, .deletedPermission CRUD
role.created, .updated, .deletedRole CRUD
scope.created, .updated, .deletedScope management
access-policy.created, .updated, .deletedAccess policy assignment
resource-type.created, .updated, .deletedResource type registration

Authentication & organization​

EventTrigger
auth.success, auth.failedLogin attempts
organization.createdNew org registration
team-member.added, .removedTeam membership changes
backup-codes.generated, backup-code.consumed, backup-codes.disabledMFA backup codes

API keys & SSO​

EventTrigger
api-key.created, .deleted, .rotatedKey lifecycle
sso.configured, .updated, .deletedSSO configuration
scim.token-rotatedSCIM token rotation
scim.user-provisioned, .user-deprovisionedSCIM user sync
scim-group.created, .updated, .deletedSCIM group sync

Access decisions​

EventTrigger
access.granted, .deniedEvery access check (via SQS consumer)

Relationships (ReBAC)​

EventTrigger
tuple.writtenRelationship tuple created
tuple.deletedRelationship tuple removed

MCP / Agent IAM​

EventTrigger
mcp-server.created, .updated, .deletedMCP server CRUD
mcp.tool-callTool execution via gateway
mcp.consent-granted, .consent-revokedUser consent decisions
mcp.approval-decidedHITL approval/denial
mcp.assignment-set, .assignment-removedUser server assignments
mcp.threat-detected, .drift-detectedSecurity detection events
session-token.minted, .revokedDownscoped token lifecycle

Policy & configuration​

EventTrigger
tier-policy.updatedAgent tool tier ceiling changes
ip-allowlist.updatedIP allowlist modifications
webhook-endpoint.created, .updated, .deletedWebhook registration
sod-constraint.created, .deletedSeparation of duty constraints
approval-request.created, .approved, .deniedHITL approval lifecycle

Billing & monitoring​

EventTrigger
subscription.changedPlan upgrades/downgrades
overage.consent-grantedOverage consent acceptance
anomaly.detectedAutomatic detection by the anomaly system
anomaly.acknowledgedManual acknowledgment in dashboard

Verifying integrity​

An auditor verifies records independently — no trust in WardenAuth required:

cURL

curl -X POST https://api.wardenauthz.com/v1/scope/workspace-eng/audit/verify \
-H "x-api-key: YOUR_MANAGEMENT_KEY"
{
"valid": true,
"total": 12847,
"matched": 12847,
"mismatchCount": 0
}

Each record's HMAC is recomputed and compared to the stored signature. A mismatch means the record was modified after writing.

Querying​

List events filtered by actor, resource, date range, or scope:

curl -H "x-api-key: YOUR_MANAGEMENT_KEY" \
"https://api.wardenauthz.com/v1/audit?scopeId=workspace-eng&actor=subject-alice&limit=50"

Access decisions (access.granted / access.denied) are listed by scope and date range. The actor and resource filters return the other events (configuration changes, key and role management, approvals); to review decisions, query the scope for a time window.

Full API reference

Exporting​

Temporarily unavailable

Bulk export is disabled while it moves to dedicated infrastructure; the endpoint answers 503 Service Unavailable. Page through GET /v1/audit in the meantime. The dashboard's "Export CSV" button still exports the page you are viewing.

Download up to 100,000 records as CSV or JSON:

curl -H "x-api-key: YOUR_MANAGEMENT_KEY" \
"https://api.wardenauthz.com/v1/scope/workspace-eng/audit/export?format=csv" \
-o audit-export.csv

Edge cases​

  • The audit log is append-only. No update or delete operations exist. Accidental entries cannot be removed — they're permanent evidence.
  • SQS publish failures drop the event. The request path does not retry audit logging — it swallows errors so the request succeeds. Audit events lost to transient SQS failures are accepted as a trade-off for zero latency.
  • Verification works on individual records. There's no chain traversal — you can verify a single record or a date range without recomputing the entire history.
  • Cold archive writes are idempotent. The archive Lambda uses conditional S3 puts (IfNoneMatch) with content-hash keys — stream redelivery never creates duplicate objects.