Security
A compliance tool has to survive its own audit.
Here is precisely what Reldavi stores, what it refuses to store, and how the boundaries are enforced. If any of this does not satisfy your reviewer, tell us what is missing.
Masking happens before anything is buffered
This is the most important boundary in the product. A property marked [AuditMask] is projected inside your process, on your servers, before the event reaches the in-memory buffer. The original value is never queued, never serialized, never transmitted and never stored. We cannot disclose what we were never given.
Redact
The value is replaced entirely. Nothing about the input survives.
Preserve last / first
Keeps the digits a human needs to recognise a record — ************4242 — and nothing more.
Keyed hash
HMAC-SHA256 with a secret that stays on your servers. Identical inputs hash identically, so the field stays searchable without being reversible.
Keeps the domain and one character: e***@contoso.com.
Length
Records only that the value changed, and how long it was.
Tenant isolation is structural, not procedural
The tenant comes from your credential
It is resolved from the API key at the edge and never read from the payload. A producer that named someone else's tenant could write into their history, so producers are not allowed to name one.
Every query carries it
The tenant predicate is added by the query builder, not by each handler. A test asserts that no generated statement can leave without it.
Storage is partitioned by tenant
Which is also why erasing one customer's data is a metadata operation that completes in milliseconds rather than a table rewrite.
And a second boundary inside it
An account can be narrowed further, to particular projects or resource types, so that "the support team can read order history and cannot read payroll" is a sentence you can actually say. That scope is put on the session at sign-in and applied on every route, including exports.
Retention is a contract, not a setting we forgot
Each customer has their own window. A bank buying seven years and a startup buying thirty days live in the same deployment without either affecting the other. Expired data is dropped per tenant on a schedule, and if a tenant is owed an archive that cannot be written, the data is kept rather than deleted — losing evidence somebody paid to keep is the worse failure.
Nothing edits history
There is no API that modifies a recorded event. The only write path is ingestion, and the only delete path is retention.
Every day is sealed, and the seals are chained
Each day closes with a Merkle root over every event in it, and each seal carries the hash of the day before. Altering one record a year ago means recomputing every seal since — including the ones you have already been shown. You can verify any day yourself from the dashboard, and a single event can prove it belongs to its sealed day with a proof of a few dozen bytes.
Retries do not duplicate
Event ids are generated by the client as UUIDv7 and used as the idempotency key, so a batch resent after a timeout collapses instead of doubling.
Exports are exact
Report exports deduplicate strictly, because an export is the artefact an auditor relies on.
One button produces the whole file
A date range in, an archive out: the records as CSV and JSON, the Merkle root sealed for every day in the range, the destruction certificates for anything since removed, a manifest carrying the SHA-256 of every file, and a page explaining how to check all of it. Assembling that by hand is where a week goes.
Rollbacks leave nothing
Events are emitted only after your transaction commits.
What this gives your compliance programme
KVKK
Personal data can be masked or pseudonymised at source, so it never enters the audit store. Erasure requests are satisfied by dropping a tenant partition. Data can stay in Türkiye, or on your own servers. Every destruction issues a numbered certificate carrying the Merkle roots of the days it destroyed — because proving destruction is a documentary duty, and the guidance treats a missing document as evidence it never happened.
GDPR
Article 30 records of processing, Article 17 erasure, and data-minimisation by design — the SDK records the properties you mark and nothing else. A data processing agreement is available.
GoBD
German tax law requires Revisionssicherheit: records complete, traceable to whoever made them, unalterable once written, retained ten years, and producible as a machine-readable export on request. The sealed daily roots are what turns "unalterable" from an assertion into something an auditor can recompute, and the export is CSV or NDJSON with the checkpoint hashes beside it. Retention is set per resource type, so ten years for the records the tax office asks about does not mean ten years for session logs.
SOC 2
Change history with actor attribution, immutable records, defined retention and exportable evidence covers a large part of the Change Management and Logging criteria.
ISO 27001
Supports A.8.15 logging and A.8.16 monitoring with per-record attribution and tamper-evident history.
EU AI Act
Article 12 has required high-risk AI systems to record events automatically since 2 August 2026, and Article 26 requires deployers to keep those logs for at least six months. Agent events carry their own block — which model, which version, which tool call, on whose authority, and whether a person approved it — and the whole prompt and result rather than a clipped sample. The day's Merkle root covers all of it, so a record whose model was edited afterwards no longer verifies.
How the platform itself is built
API key secrets are never stored
Only a SHA-256 digest of a 256-bit random secret. Passwords use PBKDF2 with the ASP.NET Core hasher.
Transport is TLS only
Payloads are gzipped, authenticated with a bearer token and rate limited per tenant.
The dashboard ships a strict CSP
No bundler, no CDN, no external fonts — so self covers the whole application and there is no inline script to whitelist.
Exports are injection-safe
CSV fields that a spreadsheet would execute are neutralised. A display name is attacker-controlled, and an audit report should not run code on the auditor's machine.
Dependencies fail the build
A published advisory on any package stops the build. Warnings are errors.
Need a security review pack?
Architecture documentation, our data processing agreement and a sub-processor list are available on request.