Security

Why it can be trusted with the real book.

Five commitments, each enforced by the architecture rather than by policy. What follows is how, in enough detail for your counsel and your CTO.

Read-only.

The connections can see. One action can move money, and it is fenced.

Account, ledger and portfolio data arrive through Plaid, your custodian, your reporting platform, Sage Intacct and Addepar with read permissions only. None of those paths can initiate a transfer, and no credential stored for them could.

The single exception is paying a bill that is already approved in Bill.com. It is never done from a report or a chat. It is staged as the exact request that would be sent, hashed, decided by a principal or the COO who is not the person who asked, re-read against the live bill at the moment of execution, sent once, and recorded. The next section has the whole path.

Credentials for every connection are exchanged and stored server-side, one secret per entity per system. They never reach the browser and never appear in a log; the platform logs the host, the path, the status and the latency of a vendor call and nothing else. A connection whose credentials name a different Intacct company or Bill.com organization than the one configured is refused.

Row-level.

Your family is a claim in the token, enforced by the database.

Sign-in issues a token that carries your family identifier. Every table that holds family data has a row-level security policy on that identifier. A query without the claim returns nothing — not an error, nothing.

No family identifier is ever accepted from the browser. The few operator tasks that must look across families (billing, the controls, the daily anchor) are named in one reviewed list, run under a separate audited role, and nothing outside that list can open a cross-family query; the controls check it every run.

Human-approved.

The system stages. A named person approves.

Anything that would leave the platform — a reminder, an email, a task, a record change — is staged in an approval queue, shown in full, and executed only after an explicit yes from a named person. The approval is logged with who, what, when and in which role.

For a Bill.com payment or bill approval, five things stand between the request and the vendor. It is staged against the synced bill, which must exist, be approved in Bill.com, be unpaid, and be owed at least the amount; the same bill, amount and date staged twice yields one item, never two. Only a principal or the COO may decide it, and the requester of a payment cannot approve it. Before anything is sent, the bill is read again from Bill.com and the action is refused if the bill was paid, partly paid below the amount, archived or un-approved in the meantime. The request sent is the request approved: the hashes must match. It is sent once and never retried on an ambiguous failure; the outcome is recorded as executed, rejected, uncertain (held for a person to confirm in Bill.com) or refused, with the reason.

The concierge that answers questions in the portal has no account data. It explains the steps and the frameworks; it cannot read or act on your book.

Provable.

Every number carries its provenance, and any change to the record shows.

The assumptions a number rests on live on an append-only ledger: source, effective date, who set it, who approved it. A new value supersedes on a date; nothing is edited or deleted, and the database refuses an overlapping history even from a raw insert.

Every deterministic answer is sealed with a hash over the book's content, the policy in force, the engine version and the question, and decisions are recorded against that hash. Answers from a language model are marked as not sealed. No model does arithmetic.

Every query against family data writes an audit row, allowed or blocked. Every request the platform serves writes one audit line with the family, the person, the route and the outcome, kept for a year.

Every pull from Sage Intacct, Bill.com or Addepar carries a fingerprint of its rows, and the nightly tie-out between them names the exact snapshots it compared. Sums are done in whole cents; a figure the source did not send is absent, never zero; an account or holding no rule can place is listed with its amount rather than dropped; two currencies are never added together.

Tied out.

The ledger, the payables and the portfolio checked against each other every night.

For a family on Sage Intacct, Bill.com and Addepar, one legal entity is one Intacct entity, one Bill.com organization and one Addepar portfolio. Every night, per entity: open payables against the AP account (must tie, $1.00 or 0.5%); Addepar's portfolio value against the investment accounts (a break only when the books are carried at market, otherwise the unrecorded mark, shown as information); Addepar cash against the cash accounts (information). Before any of that, the trial balance must sum to zero, the balance sheet must balance, and the Addepar snapshot must sum to its own total to the cent.

A break is recorded with both figures, the difference, the tolerance and the likely cause. A missing side is recorded as insufficient data, never as a tie. One entity's failed connection is recorded on that entity's run and stops no other family's.

Practices

The unglamorous part.

Your data stays yours
Your own people can read the book back at any time, as it stood on any date, through a read-only interface: nothing in it can change a record. Access is by a token the principal or COO creates, which expires, can be revoked at once, and is stored only as a hash. Every read is on your audit log with the fingerprint of what was served, and a full export is entered in the export ledger. There is no exit fee and nothing to request.
Transport
TLS everywhere, HSTS preloaded, a content security policy on every page, strict referrer policy, no framing.
Network
Databases and caches sit in subnets with no route to the internet; compute reaches AWS services through private endpoints. The application is reachable only through its edge.
Storage
Encrypted at rest. Uploaded statements and the approval queue use a customer-managed key with yearly rotation; documents are versioned and never deleted by an infrastructure change.
Secrets
API keys and credentials are never in code or configuration files. The platform's live in a secrets manager; the website's are encrypted environment variables on its host, read only at run time. The website reaches the identity provider through short-lived federated credentials, not a stored key.
Identity
Managed identity provider with hosted sign-in, PKCE, 16-character passwords, per-user roles scoped by family, and same-day removal that revokes open sessions.
Rate limits
Every public write endpoint is rate-limited, with honeypot fields on forms; the platform API is rate-limited per signed-in person and per address at the edge.
Backups
Point-in-time recovery for 35 days on the platform database and the queues, and 7 days on the website database; a restore drill of the platform database every quarter, with the measured recovery time written down.
Dependencies
Pinned and reviewed; the build fails on a known high-severity vulnerability or a committed secret.
Tenancy
Each entity's Intacct, Bill.com and Addepar credentials are one secret per connection. Every table that holds ledger lines, bills, payments, holdings or tie-out results carries the family identifier with row-level security forced on reads and writes; one family's sync failing is recorded on that family's run and stops nothing else.
Scanning
Dynamic application security testing is configured against the deployed stack; account posture is scored continuously against the AWS foundational standard.
Added September 2026
Edge
A web application firewall in front of the platform (IP reputation, common exploits, known bad inputs, per-address rate limits); the load balancer accepts traffic from the edge only, verified by a secret header.
Audit trail
Every API call in the cloud account recorded, all regions, tamper-evident, kept seven years, including every read of an uploaded document. Alarms on root use, sign-in without MFA, policy and firewall changes.
Detection
Managed threat detection on the account, storage and running containers; findings of medium severity and above page the operator within fifteen minutes.
MFA
A second factor required for every login, every role; each sign-in's risk signals are logged for review.

We do not claim certifications we do not hold. The control list, with the command that proves each one is on, is written for your CTO; ask for it, under NDA if you prefer.

Who else touches the data

10 subprocessors. No more without telling you.

Amazon Web Services (us-east-1)
Platform, identity, storage, model inference
Vercel
Website and portal hosting, edge, analytics
Neon
Portal database (onboarding state, the policy ledger)
Anthropic
The Sibyl model path and the concierge; the question and the computed rows it needs, never used for training
Stripe
Billing; card details never touch our systems
HubSpot
Contact details for people who ask to hear from us
Plaid
Read-only account connections, only if you choose them
Sage Intacct
Your general ledger, read through its Web Services API with a user you create, only if you connect it
Bill.com
Your payables, read through its API; the one write is a payment two of your people approved, only if you connect it
Addepar
Your portfolio, read through its portfolio query with an API key you issue, only if you connect it

Reviewed quarterly. A change is announced to every family thirty days before it takes effect.

Questions for your CTO or counsel?

Send them. Security questions get an engineer, not a salesperson.

Ask an EngineerFAQ