Klari Technologies Limited
Security
Last reviewed 2026-08
Klari is built around five hardening rules. Every customer of the product benefits from all of them; nothing here is an enterprise upsell.
1. Where your data lives
Tenant data — your organisation, RoPAs, DPIAs, evidence files, dossiers, audit log — is stored exclusively in Frankfurt, Germany (eu-central-1). The Postgres database, the object storage bucket, and the auth subsystem are all Supabase-hosted in that region.
Application compute runs on Vercel functions pinned to fra1. No US- or non-EU CDN holds tenant data. Cross-border flows to Germany are conducted under standard data protection clauses with our infrastructure providers, as contemplated by NDPA s.43, and rely on the recognition under NDPA s.41 that the European Economic Area provides an adequate level of protection. We can produce the current clause sets for NDPC submission on request.
One disclosure for completeness. The request-routing layer that separates our marketing site from the product runs at the edge, close to you, rather than in Frankfurt. It reads and refreshes your session token so it can decide where to send you. No tenant record — no RoPA, DPIA, evidence file, dossier or audit row — is read, written or cached outside Frankfurt.
2. Row-level security, on every table
Every tenant-scoped table in Klari has an organization_id column and an RLS policy gating SELECT, INSERT, UPDATE, and DELETE on membership of that org. The membership check goes through a SECURITY DEFINER helper so it cannot be tampered with from user-scoped queries.
A two-org cross-tenant harness runs on every CI commit and asserts that a user in org A cannot read, write, or count rows belonging to org B. It carries over 130 assertions and is the source of truth for the tenant-isolation contract.
Two limits worth stating plainly. The harness asserts against the database directly rather than through our data-access layer, and it currently covers ten tables — records, assessments and their child rows, invitations, audit events, organisations, memberships, profiles and dossiers. Evidence, invoices and published documents are protected by the same policy pattern but are not yet in the harness. Separately, a small number of server-side paths use a service-role connection that bypasses row-level security by design — evidence deletion, the internal billing tools and the scheduled jobs — and those paths enforce tenancy in application code, so the harness cannot cover them.
3. Append-only audit log
Every state-changing action in Klari writes a row to audit_events through a single chokepoint. UPDATE and DELETE are RLS-denied — the table is append-only by construction. Event types come from a closed enum maintained by migrations; arbitrary string literals fail at write time.
The audit timeline is a first-class product surface: DPOs read it as part of the normal compliance workflow. Each row carries the actor, the resource, the before / after snapshot, the IP and user-agent, and an idempotency key for de-duplication.
4. Private storage with signed URLs
Every uploaded file — evidence, DPO appointment letters, generated dossier PDFs — lands in a private Supabase Storage bucket. Browsers never see object URLs; they fetch via signed download URLs with a 15-minute TTL that re-sign on every click.
Path scheme is {organizationId}/{path} for live objects, {organizationId}/_deleted/{ts}/... for soft-deleted ones. Object UPDATE and DELETE are RLS-denied. Soft-delete renames the object via a server-side admin client, which asserts that the object path is owned by the calling organisation before it acts; membership itself is established upstream by the row-level-security-gated read that produced the organisation.
5. The mutation chokepoint
Every action that changes tenant compliance data in Klari calls a single composition: auth check → rate limit → mutation body → audit append. A handful of actions compose those same primitives by hand rather than through the shared helper. A few paths deliberately write no audit row because they change nothing inside a tenant’s compliance record — editing your own profile name, cancelling a part-finished upload, requesting a magic link, and submitting the public request-access form. Everything that touches a record, an assessment, a dossier, evidence, membership or organisation settings is audited.
One honest limit. The audit row is written immediately after the mutation commits, not inside the same database transaction. If the audit write itself fails, the mutation has already landed — the failure is captured and alerted on rather than silently swallowed, but we do not claim the mutation is rolled back. Closing that gap means moving the audit append into the transaction, which is on our engineering roadmap.
Rate limiting goes through Upstash Redis on a sliding window, keyed by user for authenticated calls and by IP for anonymous ones — one key or the other, not both. It is an availability-first control rather than a security boundary: if Redis is unreachable the limiter fails open so an outage cannot lock customers out of their own compliance records. The service-role Supabase key is server-only and never shipped to the browser.
6. Document tamper-evidence
Every PDF Klari generates — RoPA, DPIA, NDPC submission, DPO appointment letter, CAR dossier — carries a SHA-256 over a canonical JSON snapshot of the source data, printed on the cover page in grouped hex and again in the footer of every page. Re-render the document from the same data and you get the same hash; change a field and you do not.
For the RoPA, the DPIA and the CAR dossier, a second SHA-256 is taken over the rendered file bytes and recorded in an audit event at the moment of export, so a document can be tied back to the log. The NDPC submission PDF and the DPO appointment letter do not yet emit that event and carry the dataset hash only.
These are tamper-evidence hashes, not digital signatures. Klari applies no PKI signature to any PDF: a hash proves the document matches the data it was rendered from, it does not prove who produced it.
7. Sub-processors
Klari uses a small, EU-resident set of sub-processors:
- Supabase — Postgres, Auth, Storage (Frankfurt, eu-central-1)
- Vercel — application hosting (Frankfurt, fra1)
- Resend — transactional email (Ireland, eu-west-1)
- Upstash — rate-limit cache (Ireland, eu-west-1)
- Cloudflare — DNS + inbound email routing (global, no tenant data)
- Sentry — error monitoring (Frankfurt ingest)
We notify customers of any addition that materially changes data location or category of access at least 14 days in advance. A version-tracked copy of this list, carrying its own SHA-256 hash, will be published in our Trust Centre once it has completed legal review; until then the list above is the current one, and we will send the current version on request to security@klari.ng.
8. Incident response
We aim to acknowledge security reports within one business day at security@klari.ng. For data-breach reporting aligned to the NDPA 72-hour clock, write to privacy@klari.ngand we will route the notification to the customer's DPO of record.
9. Compliance roadmap
Klari is honest about what is and isn't in place today. The items below are signposted here so an enterprise procurement team can plan around them; nothing is hidden behind a paywall or a "request access" form.
- SOC 2 Type II — target audit window FY2027. We will engage an auditor once a Tier-1 customer requires it and we have a 12-month operations history. The five hardening rules above are designed to map cleanly onto the SOC 2 common criteria.
- ISO 27001 — sequenced after SOC 2. Same evidence base, different standard.
- SAML / OIDC SSO — built when the first customer requires it. Supabase Auth supports SAML on its Pro tier, so this is a low-risk add.
- 2FA / TOTP — same trigger; Supabase Auth supports it.
- Customer-managed encryption keys — will be implemented if a customer requires BYOK as part of contracting.
- Object Lock / WORM evidence storage — interface is in place; AWS S3 with Object Lock is the swap target when a bank-tier customer requires it.
- Penetration test — none has been commissioned to date. We intend to book a first engagement before signing a Tier-1 customer, and to repeat it annually thereafter.
If your procurement requires any of these before signing, write to security@klari.ng with your timing and we will discuss a delivery commitment as part of the contract.
10. Service level commitments
Klari does not yet publish a binding SLA. Uptime is monitored continuously — a scheduled internal check plus an independent external monitor, both against the live health endpoint every five minutes — but the availability target and service-credit schedule are still with counsel and are not in force. We will not quote numbers we cannot yet stand behind contractually.
If your procurement needs a committed availability figure and credit schedule before signing, write to security@klari.ng with your requirements and timing, and we will agree them as part of the contract. The published version will carry a version number and SHA-256 hash in the Trust Centre.
11. Master Services Agreement
Our MSA is drafted and in legal review; it is not yet posted for self-service download. Request the current counterpart from hello@klari.ng and we will send it. Negotiated counterparts are encouraged for any procurement that requires bespoke terms — send redlines to the same address.