Concepts
Understand the cryptographic foundations of SealTrail.
What is an audit trail?
An audit trail is a chronological record of actions taken within a system. Traditional audit logs are stored in databases or files — but there's no way to prove they haven't been modified after the fact.
SealTrail solves this by chaining events together with cryptographic hashes. Each event's hash depends on the previous event, creating a tamper-evident chain — similar to how blockchains work, but without the overhead.
Hash chains
Every event in SealTrail is linked to the previous one through a SHA-256 hash. The hash is computed from:
- The event payload (actor, action, resource, context)
- The previous event's hash
- The event timestamp
// Simplified hash computation
hash = SHA256(
JSON.stringify(payload) + previousHash + timestamp
)
// Example chain:
// Event 1: hash = SHA256(payload1 + GENESIS_HASH + t1)
// Event 2: hash = SHA256(payload2 + event1.hash + t2)
// Event 3: hash = SHA256(payload3 + event2.hash + t3)If anyone modifies an event's data, its hash changes — and every subsequent hash in the chain becomes invalid. This makes tampering detectable.
Genesis hash
The first event in a chain has no predecessor. It uses a special genesis hash as
its previousHash — a well-known constant that marks the beginning of a chain.
SHA256("GENESIS"). It's a fixed value shared across all
SealTrail chains, making the chain start verifiable.
Chain partitioning
By default, all events go into the default chain. For better scalability and
organization, you can partition events into independent chains by resource type:
// Separate chains for different resource types
await logEvent({
actor: "user_123",
action: "invoice.created",
resource: "inv_456",
chain: "invoices", // Goes to the "invoices" chain
});
await logEvent({
actor: "admin_1",
action: "user.suspended",
resource: "user_789",
chain: "users", // Goes to the "users" chain
});
// Each chain maintains its own independent hash sequence.
// No cross-chain dependencies = better write throughput.Benefits of chain partitioning:
- Scalability — Parallel writes to different chains don't conflict
- Organization — Group related events logically
- Verification — Verify one chain without scanning the entire dataset
- Performance — Reduces
409 CONFLICTerrors under high concurrency
Verification
Verification re-computes an event's hash from its stored payload, previous hash, and timestamp. If the computed hash matches the stored hash, the event is intact. If they differ, the data has been tampered with.
// Verification process:
// 1. Fetch the event and its predecessor
// 2. Re-compute: expectedHash = SHA256(payload + prevHash + timestamp)
// 3. Compare expectedHash with storedHash
// 4. Check that event.previousHash matches predecessor.hash
// Result:
{
valid: true, // Hash matches
errors: [], // No integrity issues
eventHash: "sha256:a1b2c3...", // Stored hash
computedHash: "sha256:a1b2c3...", // Re-computed hash
chainIntact: true, // Previous hash link is valid
verifiedAt: "2026-03-10T14:32:00Z"
}