Built for finance teams who can't afford surprises
This page describes the security controls Fin-Central implements today, stated at the scope they actually operate at. Where a control is narrower than the industry shorthand implies, we say so on this page rather than in a follow-up call.
Data handling
Today Fin-Central takes accounting data by CSV/XLSX import of an export from Xero, QuickBooks, Sage or another ledger. Direct OAuth connections to Xero, QuickBooks and Sage are built into the software but are not yet switched on for this service, so no account can connect one yet; what follows describes how they work once enabled. We do not replace your ERP — your ledger of record stays in place. Xero and Sage connect with read-only scopes. QuickBooks is the exception and we will not blur it: Intuit publishes no read-only accounting scope, so the only scope that grants ledger access (com.intuit.quickbooks.accounting) also grants write access. Fin-Central issues only read calls against QuickBooks, but the authorisation you grant is write-capable, and you should assess it on that basis rather than on our intent.
Encryption — exactly what is covered
We state this precisely because the usual one-line version is misleading. Application-level AES-256-GCM encryption is applied to connector OAuth access and refresh tokens (AccountingConnection) and to your 2FA secret (User.mfaSecret) — see src/lib/connectors/credentials.ts. Passwords are bcrypt-hashed and 2FA recovery codes are SHA-256 hashed, both one-way and never recoverable. Your ledger data — invoices, bills, bank transactions, trial balance, forecasts and the audit log — is NOT encrypted by the application; it is stored as ordinary database columns, because every page filters, joins and aggregates over them in SQL. It is held in access-controlled database storage on our UK hosting provider's infrastructure; we do not claim disk-level encryption for it. Traffic is TLS in transit.
Key management and rotation
Token encryption uses a versioned key ring: the first configured key encrypts, all configured keys are tried on decrypt, so a key can be rotated with no downtime and no re-encryption migration. The token key is configured separately from the session-cookie secret, so rotating one need not lock you out of the other — but note that if no dedicated token key is set, the ring falls back to deriving one from the session secret, and the application logs an error saying so on every start. Managed-KMS envelope encryption (AWS KMS or Google Cloud KMS) is available and must be switched on deliberately: set KMS_PROVIDER and KMS_KEY_ID, then generate a wrapped data key with scripts/kms-wrap-dek.ts. It is off by default, and when it is off the token key is a local one held in the deployment's environment. If a managed KMS is configured and then cannot be reached, the application fails the operation and logs it rather than quietly reverting to the local key.
Access control
Five tenant roles — OWNER, FINANCE_ADMIN, PREPARER, REVIEWER, READ_ONLY — enforced server-side on every mutating route. Sign-off is separated from preparation: a PREPARER cannot approve their own cash-flow overrides. Every CSV export resolves against an exhaustive capability table with no permissive default, so an export added later is denied until someone grants it explicitly. Tenant isolation is enforced from the server session on every query — the acting company is never read from the request.
Two-factor authentication
Self-service TOTP enrolment (RFC 6238) from any authenticator app, enforced as a second step at login. Single-use recovery codes can be generated for device loss; only their hashes are stored, and using one is recorded in the audit log.
Audit trail
Logins, logouts, role changes, overrides and their approvals, close actions, uploads, billing events, exports, and refused exports are written to a per-tenant audit log with actor, action, entity and timestamp. The log records other users' actions, so reading or exporting it requires a tenant admin — a READ_ONLY or PREPARER user cannot pull it. The log is kept for 13 months — a full audit cycle plus a month of overlap so any period can be compared against the same period last year — after which older entries are deleted. Entries that evidence a data-rights action are exempt from that and are never deleted: account erasures, tenant deletions, data exports, and refused exports or permission denials. The sign-up entry recording acceptance of the Terms is kept for the same reason: it is the record of the contract. Rejected import rows are logged as counts and reasons only; the rejected row content itself is returned to the uploader in the response and is not written to the log.
Retention, and what deletion actually means
Every retention period is stated exactly, on /legal/privacy, and every one of them is the period the deletion job applies — the published periods are asserted against the retention constants by the test suite, so the policy cannot go on describing a period the software has stopped applying. The short version: for the ledger we process on your behalf we are the processor and you keep your own statutory six-year records in your accounting system, so we hold a shorter working copy rather than a second archive. Audit evidence files and the text extracted from them are deleted 90 days after an engagement closes; bank transactions at 24 months; the vendor lookup cache at 12. Supplier bills (36 months) and the general ledger and trial balance (27 months) are deliberately kept longer because the three-year spend comparison, prior-year comparatives and audit-pack opening balances depend on them. Deletion removes the database rows AND the underlying files, and is followed by a storage reclaim so the deleted content is no longer readable in the database file — a plain DELETE leaves the payload on disk in both SQLite and PostgreSQL. Two limits we would rather state than gloss: database backups taken before a deletion still contain it until they age out on their own schedule, and the deletion job is run on a schedule by the operator of this deployment rather than by a timer inside the application.
Your data rights, self-serve
Any user can download the personal data held about them (profile, memberships, their own activity) as JSON, and can erase their own account, from Settings → Security. No support ticket, no waiting on us. If you are the only OWNER there is no account left without you, so the same control closes the whole account after a second confirmation — every record and file deleted, subscription cancelled.
Fail-closed production boot
In production the application refuses to start with a missing or too-short session secret, or without a database URL — a forgeable session is treated as worse than an outage. It warns loudly on SQLite in production, partially-configured billing, and connectors running without a dedicated encryption key.
AI & Finance Copilot
Copilot routes questions to ledger-grounded tools with citations, and a language model writes the sentences around them. Every figure and every match comes from our own deterministic tools run against your ledger; the model sees what those tools returned plus the question you typed, and nothing else. This service is configured with OpenCode Zen as its model provider. Account numbers, sort codes, passwords and connector tokens are never part of a request. Each AI feature can be switched off per workspace, and with it off the same screens are produced by the rules engine with nothing sent anywhere. AI output is decision support, not professional advice.
Subprocessors
- •OVHcloud — hosting of the application, database and backups, United Kingdom
- •Cloudflare — DNS, and forwarding of mail sent to our contact addresses
- •Stripe (Stripe Payments UK Ltd) — subscription payments; your contract for the software is with us, and Stripe calculates and accounts for any UK VAT on the sale
- •Email is sent from our own mail server on the same hosting; no third-party email service is used
- •Xero / Intuit / Sage — only once direct connections are enabled and you authorise one
- •OpenCode Zen, and the model it routes to — the language-model layer of the Copilot, board-pack commentary, audit-pack analysis and Reconcile Mode, only where a feature is enabled
- •The full, current list is at /legal/subprocessors
Certifications: none
We hold no security or privacy certification, attestation or independent audit report of any kind, and we are not going to imply otherwise by naming one as a roadmap item. What we offer instead is the list above: specific, named, and checkable in the source. If your review process requires a certified supplier, we do not meet that bar today.
Known limitations, published
We publish the gaps as well as the controls — encryption scope, per-instance rate limiting, application-enforced (not database-enforced) tenant isolation, and more. Ask us for docs/KNOWN-LIMITATIONS.md and docs/SECURITY-OVERVIEW.md; they are written for your IT reviewer, not for marketing.
Who provides this service
Fin-Central is provided by Nikah AI Limited under the Terms of Service, Data Processing Addendum and Privacy Policy. Security reviewers are welcome to assess the controls above — the contact addresses on the legal pages reach us for questionnaires and technical questions.