Security and privacy
Open Net Worth is self-hosted and single-operator: everything it knows about your finances lives in one database, on one machine you control, gated by one password.
Where your data lives
Almost everything — ledger, accounts, budget, positions, connector settings, chat history — lives in a single SQLite database file. A few larger files (receipt images, uploaded statements) sit alongside it as plain files. Both the database and its credentials are readable only by the account running the app.
No cloud account, no telemetry, no analytics — nothing about your usage is collected or reported, and no update-check or license-check phones home. The app works exactly as well fully disconnected as online, minus whatever you’ve deliberately connected (live prices, an AI provider, a bank sync).
Login
One password, set on first run — no separate user accounts. Never stored in plain text: hashed with PBKDF2 (SHA-256, 600,000 rounds, a fresh random salt every time the password is set or changed). Login issues a signed session token, not a database-backed session — the signature makes it valid, checkable without a lookup on every request.
- Lockout: 5 wrong attempts from the same address locks further attempts out for 15 minutes.
- Sessions last 30 days by default before re-login is required.
- Changing your password invalidates every other logged-in session immediately — the device you changed it from stays logged in; every other device needs the new password. No way to log out one device on its own.
- Your API token is separate from your password, unaffected by a password change. Leaked client config, or rotating on principle? Rotate the token on its own from Settings → Security — invalidates only the old token, for every client using it, without touching browser sessions.
- A freshly installed instance with no password yet answers loopback requests without asking you to log in, so you can reach it to set one — but refuses anything not from the machine itself. Once a password is set, loopback stays trusted by default too (so a local script or tool doesn’t need to log in); turn this off if you don’t want it.
What can leave the machine, and when
Nothing leaves automatically beyond what you’ve explicitly configured:
| Category | What’s sent |
|---|---|
| Your AI provider | Your conversation with Lucius, via your own API key — see models and cost. Nothing routes through a server this project operates. |
| Live prices | A bare ticker or coin id, for anything you hold or watch — see Price sources. |
| Anything you’ve connected | Email (read-only), Telegram, a web search provider, a bank/brokerage sync, or external MCP — each page states plainly what it sends and when. None on by default. |
Handling of anything untrusted
Content from outside the app — an email body, a web page, a price feed, an MCP server’s output — is data to reason about, never instructions to follow, marked as such before it reaches the AI model. Such content could carry text crafted to look like an instruction (a prompt injection); the app fences untrusted content off from anything that actually controls what Lucius does, regardless of what it says.
Related pages
operations/exposing-beyond-localhost— the real risks of reaching beyond this machineoperations/backup-and-restore— how backups strip credentials before downloadlucius/permissions— the separate control over what Lucius may do