Security overview

Last updated 2026-10-21.

Where your data lives

Application and database are hosted in the European Union. Data is encrypted in transit with TLS and at rest by the managed database provider. No customer data is transferred outside the EEA in the ordinary course of running the service.

How tenants are separated

Every customer's data is isolated by Postgres row-level security, not by application filters. Each request binds the tenant's identity to the database session, and the policies do the rest — a query that forgets to filter returns nothing rather than returning somebody else's rows.

The application connects as a non-superuser role with FORCE ROW LEVEL SECURITY applied, so the policies hold against the application's own queries, including a query with a bug in it. An automated test fails the build if any tenant-scoped table lacks a policy.

On our shared hosting that role is also the one that owns the tables, because the database plan provides a single login. That means the policies protect against mistakes in the application, not against somebody who has already found a way to run arbitrary SQL as it. A dedicated database runs migrations and the application as separate roles, and there the application cannot switch a policy or the audit trigger off at all.

Customers who require physical separation can be run on a dedicated database. Ask us.

Access and authentication

Sign-in is by single-use magic link sent to a verified email address. No passwords are stored, so there are none to leak or reuse. Within a company, members hold one of three roles — owner, editor, viewer — and the actions that change what the company asserts about itself (accepting residual risk, editing the scoring methodology, exporting or deleting data) are restricted to owners.

An owner can withdraw a member's access at any time from the team page. It takes effect on that person's next request — not at their next sign-in — and it is enforced by the same database policy that separates one company from another, so a revoked member's session reads an empty database rather than a hidden one. Their record in the audit log, and their name against the risks and controls they owned, are deliberately kept: withdrawing access is not a way to erase what somebody did. Anything they owned is flagged on the register until a colleague takes it over.

What we record

Every change to a risk, control, score, sign-off or the scoring methodology is written to an append-only audit log with an actor and a before/after. The log is protected by a database trigger that rejects every update the application issues, so no code path can rewrite history. As above, on shared hosting the database login could remove the trigger itself; on a dedicated database it cannot.

We do not log credentials, tokens, or the contents of your register in application logs.

Backups and retention

The database is backed up daily by the managed provider, with encryption at rest. Each backup is also copied to a second provider in the EU, encrypted before it leaves the application with a key that is held offline and never on any server, so that provider stores only data it cannot read. Both are retained for at most 30 days and then expire.

This matters for deletion, and we would rather state it plainly than imply something neater: when you delete an account, the data is removed from the live service immediately at the end of the 30-day grace period. Copies inside backups taken before that point, in either place, age out as those backups expire, within the 30-day window above. We do not selectively edit backups, and any provider claiming otherwise is describing something different from what a database backup is.

Taking your data with you

Any owner can export everything the account holds — including score history and the full audit log — in JSON or CSV, at any time, without asking us. Exports are themselves recorded in the audit log.

What we are not claiming

Riskhold is not ISO 27001 or SOC 2 certified, and does not offer SSO or enforced MFA today. We would rather say so here than have you find out during procurement. Sign-in already avoids passwords entirely, which addresses part of what MFA is usually asked for.

Reporting something

If you believe you have found a security problem, email [email protected]. We will acknowledge within two working days.