Security Overview
Balance Widget reads bank balances, so it's fair to ask how it's built. This page describes the controls that exist today and, in section 8, the ones that don't — because a security document that lists only strengths isn't worth reading.
- The trust boundary
- Credentials we never hold
- Secrets and tokens
- Tenant isolation
- Data minimisation
- Infrastructure
- Access management
- What isn't in place yet
- If something goes wrong
- Reporting a vulnerability
1The trust boundary
The app on your device is treated as untrusted. It authenticates as you and holds nothing privileged. Everything that touches Plaid happens in server-side functions, which are the only place our API credentials exist.
This matters because the alternative is common and bad: an app that talks to Plaid directly has to carry the Plaid secret in its binary, where anyone can extract it in minutes. Balance Widget has no such secret to extract. The most a compromised copy of the app can do is read the balances of the account it's signed in to.
2Credentials we never hold
Your bank username and password never reach us. Your bank sign-in happens inside Plaid's flow, between you and your institution. We receive a token that permits reading account and balance data.
That token cannot move money, open accounts, or change anything at your bank. It is read-only, and you can revoke it at any time by unlinking the account in the app.
3Secrets and tokens
- The Plaid client secret is held only as a server-side environment secret. It is not in the app bundle, not in the repository, and not in any client-visible configuration.
- Plaid access tokens are stored encrypted at rest and decrypted only inside a server function running with elevated privileges. They are never returned to a client, on any code path.
- The table holding secrets is privilege-denied to the application roles rather than merely filtered by policy — there is an automated test asserting that a query from an application role fails outright instead of returning zero rows. The distinction matters: a filtered table leaks the moment a policy is misconfigured.
- Client-side configuration values that are safe to publish — the API URL, the anonymous key, the analytics key — are committed deliberately and annotated as such, so nobody later mistakes a real secret for one of them.
4Tenant isolation
Every table containing user data has row-level security enabled, with policies scoping access to the authenticated user's own rows. Enforcement lives in Postgres, not in application code, so a bug in a server function cannot return another user's balances.
A non-destructive isolation test runs against the schema and asserts that one user's session cannot read, update, or delete another user's rows. It is part of the codebase, not a one-off check performed once and forgotten.
5Data minimisation
We request the narrowest set of Plaid permissions the product actually needs, and we hold as little of what comes back as we can. We do not store your full account number — only the last few digits, which is what a widget needs to label itself.
This is a security control rather than a product limitation dressed up as one. Data we never collect cannot leak, and data we discard after use cannot leak later. Where the app's data needs change, the privacy policy is updated before the change ships.
6Infrastructure
Balance Widget runs entirely on managed cloud services, all in the United States. We do not operate servers, and there is no office network or on-premise equipment in scope.
| Provider | Role | Data in scope |
|---|---|---|
| Plaid | Financial data aggregation | Account and balance data |
| Supabase | Postgres, authentication, server functions | Email, balances, encrypted tokens |
| PostHog | Product analytics | Pseudonymised usage events |
| Sentry | Error monitoring | Crash and error diagnostics |
| Apple | Distribution and billing | Subscription state; no card data reaches us |
| Cloudflare | Website hosting | Public marketing and policy pages only |
Data is encrypted in transit with TLS everywhere, and at rest by each provider's platform encryption. Our own additional encryption of Plaid access tokens sits on top of that, so a database disclosure alone does not yield usable bank tokens.
7Access management
Access to production data is restricted to authorised Lava Factory LLC personnel and granted only where it is needed to operate the service. No provider's staff has standing access to your data outside their own documented support and incident processes.
On our side: multi-factor authentication on every provider account, credentials held in a password manager rather than reused, and full-disk encryption on the machines used for development.
8What isn't in place yet
Stated openly, because you're entitled to weigh it:
- No dedicated vulnerability scanning tooling. We rely on the managed platforms' own patching and on dependency updates, not on a scanner we run ourselves.
- No third-party penetration test. The application has not been assessed by an external security firm.
- Retention deletion is manual. Deletion requests are carried out by hand within the committed 30-day window. The scheduled job that will enforce retention automatically is planned and not yet built — see the retention policy.
- No device management. Development machines are not enrolled in an MDM platform.
- No formal certification. We are not SOC 2 or ISO 27001 audited, and we make no zero-trust architecture claims.
These are gaps in tooling and process maturity, not in the architectural controls described above — and we would rather you learn about them here than discover them later.
9If something goes wrong
Application errors are captured in Sentry and reviewed. If we become aware of a breach of personal data, we will investigate, take steps to contain it, and notify affected users and the relevant authorities without undue delay — and, where the GDPR applies, within 72 hours of becoming aware. If the breach involves data obtained through Plaid, we will notify Plaid in line with our developer agreement.
10Reporting a vulnerability
If you find a security problem, please tell us before telling anyone else. Email security@lavafactory.com with enough detail to reproduce it. We'll acknowledge it, keep you updated while we fix it, and credit you if you'd like. We won't pursue legal action against anyone who reports a problem in good faith and doesn't access or modify other people's data while finding it.