Skip to content

Security that is structural.

Isolation you cannot misconfigure beats a policy nobody reads. This page lists what protects your customers' data — checked line by line against the source code, the address registry and our operator.

12
BCrypt work factor
15
Minutes until an access token dies
7
Enforced rate-limit policies
27
Threats analysed in the STRIDE model

Where your data lives.

Separation first, encryption second, and an exit that is a file rather than a negotiation.

  • Tenant isolation

    An account created through signup gets its own database, and each installed module keeps its tables in their own schema inside it. In the platform's own identity tables, tenant scope is applied by the data layer as well, rather than left to each query.

  • Where it runs

    The platform's servers are in the Netherlands, hosted by TransIP. Email delivery and SMS use providers outside the EU; the privacy policy names each one and what it receives.

  • Encryption at rest

    The databases run with SQL Server Transparent Data Encryption, so the database files are encrypted on disk.

  • Stored credentials

    Database connection strings and payment-provider credentials are encrypted with ASP.NET Core Data Protection before they are stored, and are never written to logs.

  • Getting your data out

    Where an account has its own database, we can export a complete copy of it for you on request, as a standard SQL Server .bacpac file.

Identity and sessions.

Short-lived by default, revocable in one move, and every number below is fixed in code.

15min
access-token lifetime
256bit
random refresh tokens
5min
one-time-code expiry
3attempts
one-time-code cap
5attempts
lockout threshold
12
BCrypt work factor
  • Passwords

    Hashed with BCrypt at work factor 12, fixed in code. Lockout after 5 failed attempts by default — tenant-configurable, and it can be switched off.

  • Sessions

    Access tokens expire in 15 minutes. Refresh tokens are 256-bit random values, stored only as a hash, single-use, and rotated on every refresh.

  • One-time codes

    Optional 6-digit codes by email or SMS, hashed at rest, expiring in 5 minutes with a 3-attempt cap.

  • Trusted devices

    Host-prefixed, secure, same-site-strict cookies holding a value stored server-side as a hash. Presenting a superseded cookie revokes the device and blocks the sign-in.

  • Revoking access

    Every trusted device can be revoked at once — and revocation fires on its own after a password change, a lockout, two-factor being switched off, or an email or phone change.

Boundaries, limits and the record.

Checks at the edge, caps on the road in, and an append-only trail behind every change.

  • Authorization

    Permission-gated endpoints declare the permission they require, checked at the HTTP boundary against the signed token's claims without a database round-trip. Endpoints that serve only the signed-in user's own data are gated by authentication alone.

  • Rate limits and headers

    Seven enforced rate-limit policies, and eight security headers including HSTS and a deny-by-default content-security policy on API responses.

  • Audit record

    Changes to the platform's own tables — sign-in, roles, permissions, settings — are recorded append-only: who, what, which table and row, when, and the values after the change. Password hashes, one-time-code hashes, two-factor secrets and security stamps are excluded. A deletion records the row's key, not its former contents.

  • Threat model

    A written STRIDE model: 27 analysed threats across four trust zones and the host-tenant boundary, with four accepted residual risks stated.

Every line above was last checked on 19 July 2026 — against the source code, and for hosting and disk encryption against the address registry and our operator.

Send us your security questionnaire.

We'll answer it line by line, with the people who wrote the code.

Get in touch