Horkos
Sign inStart free

Built so the record holds up.

Horkos exists to answer one question under scrutiny: what did this person agree to, and when? Everything below follows from that.

Your private key never leaves you

Your backend signs short-lived RS256 tokens; Horkos registers only the public half. We could not mint a token as one of your users if we wanted to.

Two separate identity systems

The tokens your users' sessions ride on and the credentials your team signs in with never share a verification path. Conflating them would be a security defect, and the code is structured so it cannot happen.

Published versions are immutable

Publishing canonicalises and hashes the content. There is no edit path — changing terms means publishing a new version, and the one your users accepted stays byte-identical forever.

Acceptances are written before acknowledgement

The database record is authoritative and synchronous. Evidence generation happens afterwards; a failure there can never invalidate an acceptance that was already recorded.

Evidence is stored privately

Artifacts live in a private bucket and are only ever reached through short-lived signed links issued to an authorised member of your workspace, with each issuance logged.

Subjects stay opaque

Horkos stores an identifier you choose. No names, emails, phone numbers or addresses enter the system — the evidence identifies WHICH acceptance, and you hold WHO.

Tenant isolation by construction

Every stored record is addressed by a key derived from the verified tenant, so cross-tenant access is not a check that could be forgotten — it is unrepresentable.

Retention you control

Privacy exports expire on a fixed window, and a subject data-access request produces a scoped, hash-verified archive of everything recorded for that subject.

Sub-processors and infrastructure

Horkos runs entirely on Amazon Web Services in a single region, with no third-party analytics, tag managers, or session-recording scripts on this site or in the SDK. The consent modal loads from our CDN and talks only to our API.