Open-source evidence layer

# Who did what, how risky it was, and proof it happened.

Veritio records application events, agent sessions, code changes, and deployments as hash-linked audit events — with origin and a deterministic risk score on every step — that anyone can independently verify and export. Evidence support for reviews and investigations, _not_ automatic compliance.

[View on GitHub ↗](https://github.com/getveritio/veritio)[See examples](/examples/)

![Veritio Cloud console in dark mode: the Operations dashboard with an evidence stream of hash-linked tool calls, code changes, and deploys, each with a risk score, above a critical episode's risk timeline.](/_astro/console-dashboard.DaCC8Xr2_1jpcue.webp)

Veritio Cloud · Operations console — captured from a reference deployment running `@veritio/core` risk scoring under policy `veritio.reference.v1`. Demonstration data.

## Software ships itself now.

An agent writes the migration. A pipeline approves it. A service deploys it to production at three in the morning. The work is real — and so are the questions that follow it: _who did this, under whose review, and how dangerous was it?_

Application logs weren't built to answer. They rotate, they get rewritten, and they belong to whoever holds the database. Veritio turns each action into a record instead: an origin — user, service, or AI agent — a deterministic risk score, and a hash that locks it into sequence. Evidence, not logs.

![](/media/evidence-stream-poster.jpg)

Evidence stream · demonstration data

## Anatomy of a record.

This is the fourth record from the recording above — the production table drop — exactly as an SDK stores it. Hashes truncated for print.

record #4 · deploy.deployedjson

```
{
  01"sequence": 4,
  "previousHash": "5db8…",
  02"hash": "c1a7…",
  "hashAlgorithm": "sha256",
  "canonicalization": "veritio-json-v1",
  "appendedAt": "2026-06-23T00:03:00.412Z",
  03"event": {
    "id": "evt_9f27a1c4",
    "occurredAt": "2026-06-23T00:03:00.000Z",
    "action": "deploy.deployed",
    "actor": {
      "type": "service",
      "id": "svc_deploy"
    },
    "target": {
      "type": "deployment",
      "id": "dep_0623"
    },
    "scope": {
      "tenantId": "org_acme",
      "environment": "production"
    },
    "metadata": {
      "activityEpisodeId": "ep_7c21f0a3",
      04"riskSignals": {
        "operationType": "destructive",
        "reversibility": "irreversible",
        "envCriticality": "production",
        "dataVolume": 12000,
        "fanOut": 12,
        "referenceCount": 12
      }
    }
  }
}
```

1.  01
    
    ### sequence · previousHash
    
    Each record locks to the one before it, per tenant. Delete or reorder history and the chain stops verifying at exactly that point.
    
2.  02
    
    ### hash · canonicalization
    
    SHA-256 over canonical bytes (veritio-json-v1). Change one character anywhere in the record and this stops matching.
    
3.  03
    
    ### event
    
    The protocol body: who (actor.type — user, service, or ai\_agent), what (action, target), and where (tenant scope). Same field names in TypeScript, Python, and Go.
    
4.  04
    
    ### metadata.riskSignals
    
    The inputs behind the score in the recording above. The policy is open — recompute the score yourself and you get the same number.
    

Hover a note — or the record — to cross-highlight

## Edit one byte. The chain notices.

An audit trail is only as good as its answer to one question: _how do I know nobody touched it?_

Veritio's answer is arithmetic, not access control. The verifier re-derives every hash from the canonical bytes and walks the chain, so mutation, deletion, and reordering all surface — with the exact position where history diverged.

And because the verifier ships in the open packages, an auditor doesn't have to trust your database, your admins, or us.

verify.tsts

```ts
import { verifyAuditRecords } from "@veritio/core";

verifyAuditRecords(records);
// → { ok: true }

// Quietly promote someone in an old record:
records[2].event.metadata.role = "admin";

verifyAuditRecords(records);
// → { ok: false, index: 2, reason: "hash_mismatch" }

// Try deleting the record instead:
const gapped = records.filter((_, i) => i !== 2);

verifyAuditRecords(gapped);
// → { ok: false, index: 2, reason: "sequence_mismatch" }
```

## Start in your own stack.

Install the SDK, create an audit event, append it to a store. The in-memory store runs anywhere, so you can record and verify evidence before you wire up durable storage.

audit-event.tsts

```ts
import { MemoryAuditStore, createAuditEvent, hashAuditEvent, verifyAuditRecords } from '@veritio/core'

const store = new MemoryAuditStore()
const scope = { tenantId: 'org_acme', environment: 'production' }

const event = createAuditEvent({
  id: 'evt_member_invited_01',
  occurredAt: '2026-08-09T10:00:00.000Z',
  actor: { type: 'user', id: 'usr_123' },
  action: 'organization.member.invited',
  target: { type: 'organization', id: 'org_acme' },
  scope,
  purpose: 'access_management',
  lawfulBasis: 'contract',
  retention: 'security_1y',
  metadata: { role: 'viewer' },
})

const record = await store.append(event, { idempotencyKey: 'invite:inv_123' })
const records = await store.list(scope)
const verification = verifyAuditRecords(records)

console.log({ sequence: record.sequence, verification, hashPrefix: hashAuditEvent(event).slice(0, 12) })
```

### In the box

SDKs

@veritio/core 0.4.7 · source-backed Python and Go SDKs

Adapters

Better Auth, Next.js, TanStack Start, SvelteKit · UI intent helpers for React, Vue, Svelte

Storage

PostgreSQL/Neon, MySQL, MariaDB, MongoDB · Redis tip cache

Schemas

Audit events, evidence graph edges, export bundle format

Verifier

Chain verification in every SDK — re-runnable by auditors

Workbench

veritio dev --mcp: local evidence graph, scenario runner, MCP tools

[View on GitHub ↗](https://github.com/getveritio/veritio)[See examples](/examples/)

## Or let us run it.

Veritio Cloud is the managed way to run the same open protocol: we operate project-scoped ingest, evidence storage, and export requests. Exported records remain independently checkable with the open verifier. The open-source path always works on its own; Cloud is for teams that would rather buy the operations than staff them.

[Create an account ↗](https://console.getveritio.com/register)[See pricing →](/pricing/)[Talk to us](mailto:hello@getveritio.com?subject=Veritio%20Cloud)

-   ·Managed projects and ingest
-   ·A shared evidence graph across services
-   ·Exports and verification on demand
-   ·Team access and operational support

![Veritio Cloud episode canvas: a critical activity episode's events — security risk, tool calls, a code change, and a deployment — laid out as connected cards, with the episode's critical-risk rollup in the corner.](/_astro/episode-canvas.B23-yYN6_9mykb.webp)

The same records on Veritio Cloud's episode canvas — scores and chain, tracked visually instead of as a list. Demonstration data.
