Security
Protecting the financial layer.
This is software for real financial data. Every claim on this page reflects what is actually enforced in the schema and access-control layer — not a marketing checklist.
How a request is scoped
Authentication
Sessions are managed through Supabase Auth and refreshed on every request at the routing layer — a session is never trusted from client-held state alone. Unauthenticated requests to any application route redirect to sign-in before a page renders.
Authorization
What a member can do is governed by a role, checked on both the server and at the database layer. A member can never grant themselves a higher role — that path is blocked at the row-level security policy, not only in application code.
| Role | Read | Write | Delete |
|---|---|---|---|
| Owner, Admin, Accountant | ✓ | ✓ | ✓ |
| Manager, Employee | ✓ | ✓ | — |
| Viewer | ✓ | — | — |
Data isolation
Every table that holds financial data carries a row-level security policy scoped to organization membership. A query issued by one organization's session cannot return another organization's rows, regardless of what the application code asks for.
Private documents
Uploaded documents live in a private, per-organization storage path with its own access policy. The bucket is never public: only a member of the owning organization can ask for a document, and the link they receive is short-lived and expires within minutes.
Auditability
Financial record changes write to an append-only audit log. The table itself rejects UPDATE and DELETE at the database level — a change can be superseded by a new entry, never edited or erased after the fact.
AI action control
The assistant can read, analyze, and calculate freely — every calculation runs through a deterministic engine, never invented by the model. Any action that would write or delete a record is held in a pending state until a privileged member explicitly confirms it.
Bank connections
Bank sign-in happens in Plaid's window: Countorra never receives your bank username or password. The access key Plaid issues for a connection is encrypted with AES-256-GCM before it is stored, under a key held only in the server environment and never in the database, in a table no member role can read. It is never sent to the browser. Returning from a bank's own sign-in page uses one fixed address for everyone; which workspace you return to comes from an encrypted, server-issued session tied to your sign-in, never from the address itself.
Provider credentials and webhooks
Credentials for Plaid, Stripe and our other providers exist only on the server — none is ever included in what your browser downloads. Messages Plaid and Stripe send to Countorra are verified against their signatures before anything in them is acted on, and a message delivered twice is processed once.
Background work
Bank imports run in a background worker on the server. It can be started only with a deployment secret, it is rate limited like any other caller, and every job it runs is bound to one workspace — it cannot read or write another's data. It stops itself well inside its time limit, and work interrupted part-way is picked up again without being duplicated.
Monitoring
Errors and security-relevant events — refused sign-ins, rate limits, rejected webhooks, background-worker health — are recorded through one filter that removes passwords, tokens, email addresses, amounts and the content of AI questions before anything is written.
Deleting your account
Account deletion is self-serve and requires your password again. First, Countorra cancels the Stripe subscription of every workspace being deleted and confirms with Stripe that nothing can be charged again; if that cannot be confirmed, nothing is deleted. Then it asks Plaid to end its access and destroys every stored bank access key; if a key cannot be destroyed, nothing is deleted. Documents are removed from storage, then the workspaces you alone use, then your sign-in. A workspace cannot be deleted directly from the browser, and the database refuses to delete one whose subscription can still be charged.
What we do not claim
Countorra has not been audited or certified by a third party — no SOC 2 report, ISO 27001 certification, PCI DSS certification or independent penetration test. Card payments are handled entirely by Stripe, so card numbers never reach Countorra. No system is perfectly secure.