Security
Financial data is a liability we take seriously.
ShadowLedger reads accounting data to find wasted software spend. That is all it does with it. Here is exactly how the data is accessed, stored, and removed, in plain terms.
Read-only, always
ShadowLedger only ever reads. When you connect QuickBooks, we issue query calls to pull transactions and vendors. We never create, edit, or delete anything in your books, and we never touch payroll runs, payments, or bank credentials.
No access required to try
The CSV path runs entirely from a file you export yourself. No login, no OAuth, no connection to anything. You see the found money first, then connect QuickBooks only if you want continuous syncing, and we only ever read.
Tokens encrypted at rest
If you connect QuickBooks, the OAuth tokens are encrypted with AES-256-GCM using a fresh nonce per record. The encryption key lives in the runtime environment, never in the database, so a database copy alone reveals nothing.
Isolated per account
Every scan, connection, vendor rule, and finding is scoped to your account at the query layer. There is no shared view and no cross-account lookup. One account can never read another account's data.
Revoke and delete on your terms
Disconnect QuickBooks and we revoke the grant with Intuit right away, so the token stops working immediately. Delete stored scans whenever you want. Close your account and every grant is revoked the same way before the data is erased, so nothing is left pointing at your books.
Hardened transport and app
All traffic is HTTPS. Reports render inside sandboxed frames, responses carry a strict security-header set, and every billing and account webhook is signature-verified before it is trusted.
How your data flows
There are two ways data reaches the engine, and you choose which. The CSV path takes a transactions export you download from QuickBooks or a bank, runs the detection engine, and renders a report. Nothing is connected and no credentials are involved. The QuickBooks path uses OAuth: you approve access on Intuit’s own consent screen, and we exchange that for tokens we use to pull transactions on your behalf. Intuit has no read-only accounting scope, so the guarantee is in what we do: we only ever issue read and query calls, never writes. You can start with CSV and never connect anything.
What we store
- Transactions we process become a stored scan: the detected subscriptions, findings, and the source rows so a scan can be recomputed when you correct a match. You can delete any scan at any time.
- Connection tokens, only if you connect QuickBooks, encrypted at rest with AES-256-GCM. We never see or store your bank or QuickBooks password; the OAuth flow means we never have it.
- Account basics handled by our authentication provider (Clerk). We do not store your password. Payments run through Stripe; we store only your plan status and Stripe identifiers, never your full card number.
Who processes your data
We use a small set of third parties to run the Service, and share data with them only as needed for their function. This list is generated from the code rather than kept by hand, and a test fails the build if a new outbound integration is added without appearing here.
- Vercel: Application hosting, and storage for firm logos on client reports.
- Prisma Postgres: The primary database that stores your scans and account data.
- Clerk: Authentication and account management.
- Stripe: Payments and subscription billing.
- Anthropic: The AI analysis behind vendor matching, the Ask your ledger chat, and contract term extraction.
- Resend: Transactional and notification email.
- Inngest: Background jobs, including scheduled re-scans and renewal alerts.
- Expo: Push notifications to the mobile app, if you use it. Renewal alerts name the vendors that are renewing, so those names appear in the notification text.
Where the AI runs
Three features use a large language model: matching a transaction description to a known vendor, the Ask your ledger chat, and pulling terms out of a contract you upload. All three run on Anthropic’s API and nothing else. There is no second model provider and no cheaper fallback, because every one of those calls carries a line out of a customer’s books and adding a provider means adding a company that sees them.
An uploaded contract is sent to Anthropic to be read and is never written to disk here. Under Anthropic’s commercial terms, API inputs are not used to train their models. The model never decides anything on its own: findings are suggestions you accept or reject, and the numbers in a report come from your transactions, not from the model.
Accounting systems you connect
These are platforms you already use and choose to connect. Data flows from them to us because you asked for it, which is a different relationship from the providers above.
- Intuit / QuickBooks Online: When you choose to connect it, to read your accounting transactions. We only ever issue read and query calls, and never write to your books.
- Xero: The same read-only transaction access as QuickBooks Online, for firms on Xero.
- Google Workspace (not open yet): Reads the admin reports that show which paid applications a workspace is actually using.
Retention and deletion
You are in control of the financial data. Delete a scan and the findings, the parsed transactions, and the vendor records behind it are removed from the database, not flagged as hidden. Disconnect QuickBooks and we revoke the grant with Intuit right away and delete the stored tokens.
Close your account and the erasure runs in the background within minutes, not some open-ended window. First every accounting grant you hold is revoked at the provider, across every client workspace, so no live token is left behind. Then scans, transactions, connections, clients, custom rules, share links, calendar links, vendor corrections, your uploaded report logo, and your preferences are all deleted, and any active subscription is cancelled. Two things are kept but severed from you rather than deleted: product analytics events and any feedback you sent us, both stripped of the account id and, for feedback, the reply address you gave, so what remains cannot be traced to you or your clients. Full details are in the Privacy Policy.
Need it gone sooner, or need confirmation in writing? Email support@getshadowledger.com and I will handle it myself.
Internal review
The application has been through a full internal security review covering tenant isolation, authentication, the public share and calendar links, the billing and account webhooks, and the report renderer. That review is ongoing, not a one-time checkbox. We do not currently hold a third-party certification such as SOC 2, and we will say so plainly here rather than imply one we do not have.
Who is behind this
ShadowLedger is built and run by John Dorn, a solo founder based in California. That is worth saying plainly, because handing a client ledger to an anonymous website is a reasonable thing to refuse. There is no support team standing between you and the person who wrote the code: security questions, incident reports, and deletion requests reach me directly at support@getshadowledger.com, and I answer them myself.
If you need a data processing agreement before connecting a client ledger, the whole thing is published at /dpa, including the sub-processor annex and a list of the limitations worth knowing about before you sign. Email that address for a countersigned copy. If you need something an operation this size cannot provide, a completed SOC 2 report being the usual one, I will tell you that directly instead of working around the question.
Reporting an issue
Found something, or just have a question about how any of this works? Email support@getshadowledger.com and it reaches the person who builds ShadowLedger. Please give us a reasonable window to fix a genuine vulnerability before disclosing it publicly.
Try it without connecting anything.
Export one CSV, upload it, see the audit. No account access required.
Run your free audit