Immutable audit trail library for Go

Chronicle your events

Hash-chained audit events, GDPR crypto-erasure, SOC2/HIPAA compliance reports — production-ready out of the box.

$go get github.com/xraph/chronicle
Record()
SHA-256
Persist
user.login
info
perm.change
warning
data.delete
critical
SHA-256 Chain
GDPR Erasure
SOC2 / HIPAA
Multi-Tenant
Features

Everything you need for audit trails

Chronicle handles the hard parts — hash chains, GDPR erasure, compliance reports, multi-tenancy — so you can focus on your business logic.

Hash Chain Integrity

Every event is linked by SHA-256 to its predecessor. Tamper any event and the chain breaks — Chronicle detects it instantly.

verify.go
report, err := c.VerifyChain(ctx, &verify.Input{
AppID: "myapp",
TenantID: "tenant-1",
})
"text-fd-muted-foreground/60 italic">// valid=true verified=842 gaps=[] tampered=[]

GDPR Crypto-Erasure

Per-subject AES-256-GCM encryption. Destroy the key — data becomes unrecoverable. Hash chain stays structurally valid.

erasure.go
result, _ := svc.Erase(ctx, &erasure.Input{
SubjectID: "user-42",
Reason: "GDPR Article 17",
RequestedBy: "dpo@company.com",
}, "myapp", "tenant-1")
"text-fd-muted-foreground/60 italic">// key_destroyed=true events_affected=12

Compliance Reports

Generate SOC2, HIPAA, EU AI Act, and custom reports with a single call. Export to JSON, CSV, Markdown, or HTML.

compliance.go
report, _ := engine.SOC2(ctx, &compliance.SOC2Input{
Period: compliance.DateRange{
From: q1Start, To: q1End,
},
AppID: "myapp",
GeneratedBy: "admin@company.com",
})

Multi-Tenant Isolation

Scope middleware stamps every event with AppID and TenantID. Query isolation is enforced automatically — no cross-tenant data leaks.

scope.go
ctx = scope.WithAppID(ctx, "myapp")
ctx = scope.WithTenantID(ctx, "tenant-1")
ctx = scope.WithUserID(ctx, "user-42")
 
"text-fd-muted-foreground/60 italic">// All events and queries are
"text-fd-muted-foreground/60 italic">// automatically scoped to tenant-1

Plugin System

BeforeRecord and AfterRecord hooks let you enrich or drop events. AlertHandler fires in real time on matching severity or category.

plugin.go
func (p *MetricsPlugin) OnAfterRecord(
ctx context.Context,
ev *audit.Event,
) error {
metrics.Inc("audit.event", ev.Severity)
return nil
}

Pluggable Stores

Start with in-memory for development, swap to PostgreSQL or Bun ORM for production. Implement your own store in ~36 methods.

main.go
c, _ := chronicle.New(
chronicle.WithStore(
store.NewAdapter(postgres.New(pool)),
),
chronicle.WithCryptoErasure(true),
chronicle.WithLogger(slog.Default()),
)
Recording Pipeline

From call to immutable record.

Chronicle orchestrates the entire audit recording lifecycle — scope stamping, hash chain linking, plugin hooks, and multi-store persistence.

Automatic Scope Enforcement

Every event is stamped with AppID, TenantID, UserID, and IP from context. Query isolation is enforced at the store layer — no tenant can see another's data.

Deterministic Hash Chain

SHA-256 is computed over sorted metadata: prevHash|timestamp|action|resource|category|outcome|severity. Erasure destroys encrypted payloads but leaves the chain intact.

Plugin Hooks

BeforeRecord can enrich or silently drop events. AfterRecord fires post-persist for metrics and tracing. AlertHandler triggers on severity or category rules.

c.Info()
user.login
Scopetenant+user
SHA-256hash chain
user.login
✓ Recorded
perm.escalate
⚠ Warning
data.wipe
✕ Critical
Info
Warning
Critical
Plugin
Developer Experience

Simple API. Tamper-proof records.

Record your first audit event in under 20 lines. Verify the entire hash chain with a single call.

Recording
main.go
1package main
2 
3import (
4 "log/slog"
5 "github.com/xraph/chronicle"
6 "github.com/xraph/chronicle/scope"
7 "github.com/xraph/chronicle/store"
8 "github.com/xraph/chronicle/store/postgres"
9)
10 
11func main() {
12 pgStore := postgres.New(pool)
13 c, _ := chronicle.New(
14 chronicle.WithStore(store.NewAdapter(pgStore)),
15 chronicle.WithCryptoErasure(true),
16 chronicle.WithLogger(slog.Default()),
17 )
18 
19 ctx = scope.WithAppID(ctx, "myapp")
20 ctx = scope.WithTenantID(ctx, "tenant-1")
21 ctx = scope.WithUserID(ctx, "user-42")
22 
23 "text-fd-muted-foreground/60 italic">// Record a tamper-proof audit event
24 err = c.Warning(ctx, "perm.escalate", "role", "admin").
25 Category("access").
26 SubjectID("user-42").
27 Meta("from", "viewer").
28 Meta("to", "admin").
29 Record()
30}
Verification
verify.go
1package main
2 
3import (
4 "fmt"
5 "github.com/xraph/chronicle/verify"
6)
7 
8func auditVerify(c *chronicle.Chronicle, ctx context.Context) {
9 "text-fd-muted-foreground/60 italic">// Verify the full hash chain for a tenant
10 report, err := c.VerifyChain(ctx, &verify.Input{
11 AppID: "myapp",
12 TenantID: "tenant-1",
13 })
14 if err != nil {
15 log.Fatal(err)
16 }
17 
18 fmt.Printf(
19 "valid=%v verified=%d gaps=%v tampered=%v\n",
20 report.Valid,
21 report.Verified,
22 report.Gaps,
23 report.Tampered,
24 )
25 "text-fd-muted-foreground/60 italic">// valid=true verified=8420 gaps=[] tampered=[]
26}

Start auditing your system

Add production-grade, tamper-proof audit trails to your Go service in minutes. Chronicle handles hash chains, GDPR erasure, and compliance reports out of the box.

$go get github.com/xraph/chronicle