Security & trust

What we protect, how, and what is not done yet.

Your financial data is the most sensitive information in your business. Everything on this page is either verified in our codebase or measured in production, and the things we have not done are listed as plainly as the things we have. Last reviewed 30 September 2026.

Isolation at the database

Row-Level Security is enabled and forced on 122 of 154 tables. The other 32 hold no customer rows. The database refuses a cross-tenant read even if the application asked for one.

No passwords to steal

Magic-link sign-in only. Links expire in 15 minutes and are capped at 5 per address per hour. Sessions last 24 hours. Sensitive actions ask you to re-verify.

Credentials encrypted separately

Connector tokens are encrypted with an application key that never sits in the database. TLS 1.2+ with HSTS in transit; encryption at rest by the database provider.

Audit you cannot edit

Security and data events go to an append-only audit table enforced by database triggers. Export, anonymisation and deletion requests are built in.

Data isolation

Your data is yours alone.

Isolation is enforced by PostgreSQL Row-Level Security, not only by application code. Every tenant-scoped table carries a policy, the policy is forced so it applies even to the table owner, and the tenant context is set per transaction and cleared automatically at commit or rollback, so a pooled connection cannot leak one workspace into the next.

Measured, not asserted

On 30 September 2026, at schema revision 137: 154 tables, 122 with Row-Level Security enabled and forced. The 32 without it are platform tables that hold no customer rows (sign-in tokens, backup runs, the migration ledger, global model registries) and the monthly partitions of audit and telemetry tables, whose parent carries the policy.

Tested from the outside

45 test files exercise cross-tenant denial, including writes with the wrong tenant, empty tenant context, and pooled-connection reuse. The full suite is 12,500 tests and runs on every change.

Connector credentials

Each workspace’s OAuth tokens and API keys are encrypted before they are written, with a key held only in the application environment. Decryption happens in memory at sync time. One workspace’s credentials cannot be read or used by another.

Database roles

The application connects as a role that cannot bypass Row-Level Security. Only the migration role can, and it cannot log in.

Access controls

Strict authentication, zero passwords.

There are no passwords to phish, reuse or leak. Access is by single-use magic link to a work email address, and the actions that matter most ask you to prove it is still you.

Sign-in

Magic link via work email. Links are single-use and expire after 15 minutes. At most 5 links per address per hour, enforced against a shared store so the limit holds across every server.

Sessions

Signed session tokens that expire after 24 hours, with issue and expiry claims required on every request. Sessions are recorded server-side and are revoked on logout.

Step-up for sensitive actions

22 security-sensitive actions, such as deleting workspace data, changing roles or exporting evidence, require a fresh verification within a 10-minute window, and 10 of them also require a written reason that is recorded in the audit log. A test in our build fails if an action is declared sensitive but not wired.

Rate limits and CSRF

120 requests per minute per IP on the API; 10 per minute on sensitive endpoints. Cross-site request forgery protection on every mutation. Admin endpoints check the caller’s role explicitly.

Single sign-on is not built. SAML and OIDC are on the roadmap and not yet started. If SSO is a requirement for you, tell us and we will sequence it.
Encryption and transport

Encrypted in transit and at rest.

TLS 1.2 or higher on every connection, with HTTP Strict Transport Security so a browser will not fall back to plain HTTP. Data at rest is encrypted by our database provider. Secrets that we manage ourselves get a second, separate layer.

In transit

TLS 1.2+ and HSTS. Tokens and keys are never placed in URLs or written to logs.

At rest

Encryption at rest is provided by the managed PostgreSQL service that hosts the database. Nightly backups are encrypted before they leave the platform and stored in object storage.

Connector credentials

Encrypted with Fernet (AES-128-CBC with HMAC-SHA256 authentication) under a key that lives only in the application environment, with key rotation supported. The database never holds a plaintext token.

Browser hardening

Every response carries Content-Security-Policy, Strict-Transport-Security, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy and Permissions-Policy.

Data handling

What we store, and what we send where.

We store what is needed to compute your KPIs and to let you trace every figure back to its source rows. We do not sell data, and your financial data is not used to train any model.

What we store

Canonical transaction-level records from your connected sources (invoices, payments, customers, subscriptions, expenses), the monthly KPI aggregates computed from them, connector credentials (encrypted), user email addresses, workspace settings, and the audit log. Traceability to source rows is why the transaction-level records are kept.

Retention and deletion

Financial data is retained for the life of your workspace. You can delete all workspace data from inside the app; the action requires step-up verification and a reason, and the audit log of the deletion itself is kept. Account deletion runs after a 7-day grace period during which it can be cancelled. Platform telemetry follows fixed retention classes of 30 days, 90 to 180 days, one year, and a 7-year append-only class for compliance records.

AI narrative

The Executive Brief narrative is generated by Anthropic’s Claude. The request contains your company name, the period, and KPI-level summaries. It does not contain transaction rows or your customers’ names. Anthropic states that by default it does not use inputs or outputs from its commercial API to train its models.

Uploads

File uploads are restricted to CSV and Excel, checked by content rather than file extension, and exports neutralise spreadsheet formula injection. Outbound connector requests are guarded against server-side request forgery.

Subprocessors

Who handles your data.

A short list, each for one specific function.

SubprocessorPurposeDataLocation
RenderApplication and background-worker hostingAll application trafficUS (Oregon)
NeonManaged PostgreSQL databaseAll stored application dataUS (AWS us-east-1)
Amazon Web ServicesEncrypted nightly database backups (S3)Encrypted backup archivesUS
AnthropicExecutive Brief narrative generationCompany name and KPI-level summariesUS
ResendTransactional email (magic links, digests, alerts)Email address, message contentUS
StripeBilling and subscriptionsEmail address; payment details are held by StripeUS
SentryApplication error reportingError traces, passed through a scrubber that removes secrets and personal dataUS
Control baseline

57 controls, each with a test.

Our security programme is written down as a control baseline: 57 controls in nine categories, each mapped to NIST CSF 2.0, OWASP ASVS 5.0.0 and the OWASP API Security Top 10 (2023), with a named test method and the evidence it produces. Most controls are verified by automated tests that run on every change.

Nine categories

Identity and access (8), tenant isolation (7), data protection (7), threat detection and response (6), audit and accountability (7), input validation and uploads (6), AI and agent security (5), privacy and consent (5), infrastructure and operations (6).

Checked in the build

Every change runs secret scanning (gitleaks), Python static security analysis (Bandit, with a budget that can only go down), dependency vulnerability audits for Python and JavaScript, and Dependabot updates across three ecosystems, alongside the 12,500-test suite.

Security questionnaire

A completed self-assessment structured on the Cloud Security Alliance CAIQ-Lite domains is available to prospects and their security teams on request, with the control IDs and evidence behind each answer. It says no where the answer is no.

Ask for the evidence

Policy definitions, test results and audit samples can be shared under NDA for a security review. Write to [email protected].

Status

Where we are, and what is not done.

We are early. This list is the honest version, and we would rather you read it here than discover it in a questionnaire.

In place

Tenant isolation, audit, privacy requests

Forced Row-Level Security, append-only audit, and data subject export, anonymisation and deletion are live and tested.

In place

Automated security checks on every change

Secret scanning, static analysis, dependency audits and the full test suite gate every merge.

Not yet

Third-party penetration test

Not yet performed. We will commission one scoped to multi-tenant authorisation, two tenants and two roles, when a customer engagement requires it. Ask us and we will share the scope.

Not yet

Independent audit (SOC 2)

Not started. We will begin a SOC 2 programme when customers require it. Until then, the control baseline and the questionnaire above are what we can offer, and both are checkable.

Not yet

Single sign-on

SAML and OIDC are not built. On the roadmap.

Partial

Restore drill

Backups run nightly and are encrypted. A full restore-and-verify drill with a measured recovery time has not yet been completed on production data; the tooling for it shipped on 29 September 2026.

Vulnerability disclosure

Found something? Tell us.

We take security reports seriously and aim to respond within 48 hours. Please do not publicly disclose a vulnerability before we have had a chance to address it. We do not run a bug bounty programme, and we will acknowledge responsible disclosure.

Write to [email protected].