Organizations
An Organization (also called a Tenant) is the top-level account boundary in AuditRails. Everything — your projects, events, API keys, billing, and team members — lives inside one organization. Each organization has its own independent hash chain, so events from different customers or tenants never intermingle.Plans
All plans include the same 180-day base retention — see Retention below for how enabling a compliance framework can extend it.
Roles
Projects
A Project is a logical grouping of events within your organization. Each project is scoped to one or more API keys, which means events from different applications, environments, or services are cleanly separated. A common pattern is to create one project per environment:Events
An Event is the atomic unit of data in AuditRails. When you callaudit.log(...), you are writing one event to the chain.
Fields
string
required
What happened, in
resource.verb format (e.g. user.login, document.deleted, invoice.paid). Maximum 255 characters. This is the only required field.string
The identity that performed the action — typically a user ID, service account name, or API client identifier (e.g.
user_123, svc-billing).string
The object that was acted upon, in
type/id format (e.g. session/sess_abc, document/doc_789, invoice/inv_001).object
An arbitrary JSON object for any additional context — IP addresses, request IDs, before/after values, geolocation, etc. The total request body must not exceed 256 KB.
SDK-Injected Fields
The SDK (or API ingest layer) automatically attaches these fields before hashing. You do not set them manually:Because
timestamp is assigned server-side at ingest, it cannot be backdated. This is an intentional integrity guarantee — the chain reflects the true order events were received by AuditRails.Hash Chains
Hash chaining is the core mechanism that makes AuditRails tamper-proof. Every event you log is cryptographically linked to every event that came before it, forming an unbroken chain where any modification — however small — is immediately detectable.The Formula
previous_hash— the SHA-256 hash of the immediately preceding event in your tenant’s chain.canonical_payload— the deterministically serialized event fields (action, actor_id, resource, metadata).timestamp_ms— the server-assigned ingest timestamp for this event, expressed in milliseconds since epoch.
Genesis Event
The very first event in any tenant’s chain uses a genesis hash as itsprevious_hash:
Tamper Detection
Because each hash depends on all previous hashes, modifying any single event changes its hash, which changes the next event’s expected input, which invalidates every hash that follows. AuditRails continuously runs background verification jobs that re-compute and compare hashes. Any discrepancy triggers an immediate alert.Storage Tiers
AuditRails writes every event to two independent storage backends simultaneously:
WORM (Write Once, Read Many) means that once an event is committed to cold storage, no user action, no admin command, and no AWS API call can remove or overwrite it before the retention period expires. This is enforced at the S3 infrastructure level, not just by software policy.
Retention
Every plan includes the same base retention, applied identically to both storage tiers, and begins from the event’s ingest timestamp:
Enabling a compliance framework with a longer minimum retention requirement extends this automatically — the longest applicable period always wins. For example, enabling SOX raises effective retention to 7 years; HIPAA sets a 6-year minimum; NIS2 and DORA both require 5 years.
Upgrading your plan does not retroactively extend the retention of existing events. Events already written are retained for the period that was active when they were ingested. New events pick up the new retention period immediately.
API Keys
API keys authenticate your requests and scope them to a specific project. AuditRails uses two key formats:
Keys are SHA-256 hashed before being stored in AuditRails’ database. The raw key value is never persisted — if you lose it, you must revoke it and generate a new one. Each key is scoped to a single project and carries no cross-project permissions.