Security

How Nya protects your data, and who can read it, including the limits.

In short

  • Your balances, transactions, history, budgets, goals and the tokens that connect your banks are encrypted before they are stored.
  • Some details around them are stored as plain text: dates, ids, the names of your banks, merchant names you renamed, and the names you and the people you share with gave each other.
  • Nya never sends, receives or holds money, and keeps no payment app’s login, card or account number. Under Shared expenses it keeps the list of what people owe you and what you owe them, encrypted, names and usernames included; the money moves in Venmo, Cash App or however you pay each other.
  • Nya is not encrypted end to end. Whoever runs Nya holds the keys, so they can read your data. The encryption protects against someone who gets the database or a backup without those keys.
  • Bank connections through Plaid work for US institutions only; your own SimpleFIN account, or your own Lunch Flow account where this copy of Nya offers it, may reach others.
  • No outside security audit has been done yet.

What is encrypted, and how

These values are encrypted with AES-256-GCM before they are written to the database: the tokens that connect your banks through Plaid, the access your own SimpleFIN account gives Nya, the API key of your own Lunch Flow account, balances, net-worth history, transactions, budgets, goals, the categories you set and the names you give merchants, manual accounts, how each bank connection is doing, the records of when shared accounts were shown, the record of changes made with API tokens, and the short-lived copies of what the dashboard last showed. Some details around them are not; they are listed below.

This copy of Nya uses envelope encryption. Those values are encrypted with data keys that the app generates. Each data key is stored only in locked form, encrypted with a master key that is kept in the server’s environment settings, never in the database. Changing the master key locks the data keys again under the new one and leaves the data itself untouched, so a key change cannot damage it.

Each account made on this version of Nya normally has a data key of its own from the start, used for its data alone. An account made before it, or one made at a moment its key couldn’t be (while the master key is being changed, say), is under a set of data keys shared by everyone on this copy of Nya until whoever runs it moves the account to a key of its own. A value under one account’s key can’t be read as another’s, even copied into its place; values still under a shared key can, until they are moved.

Values written before the master key was set up stay under Nya’s original single key (also AES-256-GCM, also kept only in the environment) until they are moved to a data key. If a shared data key ever cannot be used, a value is written under that original key and the server’s log says so. An account with a key of its own never falls back: if its key can’t be used, its data can’t be read or written on that server until it can.

What this protects against: someone who gets a copy of the database or a backup, but not the keys. What it does not protect against: someone with access to the server’s environment, which holds both the master key and the database password. That includes whoever runs Nya.

Receipts and documents you attach to transactions are encrypted on Nya’s server before they are stored, each with a key of its own, and kept in a private Vercel Blob store. The store never holds those keys: each is kept only in the database and its backups, locked with your account’s own data key. So the file store, or a copy of it, holds nothing readable on its own. A photo is made smaller and re-encoded in your browser before it is sent, which drops what the camera saved with it, such as where it was taken, and the server refuses a photo that still carries a location; a PDF is kept as you chose it, with what it carries, such as its author. They are shown only through the app itself, to you signed in: no link to a file works without signing in, and none is ever public. Whoever runs this copy of Nya can read them, as they can read the rest of your data. Adding new ones is off on this copy of Nya.

What is stored as plain text

The values are encrypted; some of the structure around them is not. In the database and in backups, these are plain text:

  • dates and times: which days have a recorded balance, and when things were saved;
  • ids: of your accounts, transactions and bank connections (random strings from Plaid, or made by Nya for manual accounts and a SimpleFIN or Lunch Flow connection), of your sign-in account, of your API tokens (random, and not enough to use one), and of the people you split costs with and your IOUs (random, made by Nya: their names, usernames and amounts are encrypted);
  • the names of the banks you linked, and whether Plaid included transactions when each connection was linked;
  • the merchant names you renamed (the new names you gave them are encrypted);
  • for sharing: the names you and the people you connect with gave each other, which accounts each of you shares at which level and until when, which of your net worth, spending, holdings, budgets and goals each of you shares, at which level (with the random ids of the goals chosen), and for each connection a random id, which its records of when shared accounts were shown are kept under, and when those records began (what they record is encrypted), never the balances, amounts or transactions themselves.
  • for the record of changes made with API tokens, where tokens may make changes: the day each change was made and which token made it (what it changed is encrypted).
  • for receipts and documents: a random id for each, and which of your transactions have one, by their ids; in the file store, each encrypted file’s size and when it was uploaded.

The database also holds the IP address of a device that typed a wrong password, for up to 15 minutes; of a device that sent API tokens, or links to turn off a weekly summary, that didn’t work, for up to 10 minutes; and on the demo, that of a device that used a demo account, for up to 10 minutes. These never go into backups. And for each API token, how many requests it made in the current minute, deleted when the token is revoked, or 2 minutes after the last request made with any of your tokens; where tokens may make changes, for a token that can update balances or make changes, its writes in the current minute and its changes in the current 24 hours, all your tokens’ changes in the current 24 hours, and the manual accounts whose balance a token set in the current 24 hours, by their ids, deleted when the token is revoked or the window ends; and for the weekly summary, how many you asked to be sent now, kept for a day, and how many times a link to turn it off was used, kept for an hour. And how many times you read what is shared with you, or what someone sees of yours, kept for 10 minutes.

Encrypting these as well is planned.

Your data, in Settings under Your data and privacy, lists what Nya keeps about you kind by kind: which of it is plain text, and which key the rest is encrypted with, your account’s own or one this copy of Nya shares.

The database also keeps the European Central Bank’s exchange rates in plain text: public, the same for everyone, kept once for every account, and left out of Nya’s nightly backups. Every currency the ECB publishes is kept, so which ones are there says nothing about anyone. Your home currency and your own exchange rates are encrypted.

Who can read what

Who can read what
WhoWhat they can read
The operator, who runs this copy of NyaEverything, in practice. The master key and the database password are kept in the same hosting environment, so the encryption does not protect against whoever controls it. A managed key service that records every use of the key is planned.
Upstash, the databaseThe encrypted values, and the plain text listed above.
Vercel, the hostEvery request and response while the app handles it, and the app’s logs, and the nightly backups, which it stores. It also stores your receipts and documents, encrypted; each file’s key is locked in the database, apart from the files.
PlaidYour bank login, typed into Plaid’s window or your bank’s own page (Nya never sees it). Then your accounts, balances and transactions, and holdings and loan details where you have them, under Plaid’s own privacy policy.
SimpleFIN, if you connect itYour bank connections, which you make and pay for in your own SimpleFIN account (or another paid service that speaks its protocol, such as Redbark), under its own terms, and when Nya reads your accounts there. Nya contacts only the host in the Setup Token you paste, to claim it, and the host of the access that claim returns, to read your accounts; never a private or internal address.
Lunch Flow, if you connect itYour bank connections, which you make and pay for in your own Lunch Flow account, under its own terms, and when Nya reads your accounts there and which ones. Nya sends the API key you paste only to Lunch Flow’s own address (lunchflow.app, and its www name), never to another host a redirect points to, and never to a private or internal address.
Clerk, the sign-in serviceYour email address and your sign-in activity, and your name and picture if you sign in with Google or another account. Its bot check runs on Cloudflare (Turnstile), which sees your IP address and browser when it runs. Only when this copy of Nya uses Clerk accounts rather than a shared password.
Programs you give an API token toWhat the API and the MCP server serve (the Developers page lists it): your accounts and balances, net worth and its history, the last year of transactions, budgets, recurring bills and holdings, and your shared expenses, the one answer that names the people you split costs with, until you revoke the token. Never your sign-in or your bank logins, and no token changes your shared expenses. A token made to read changes nothing. Where whoever runs this copy of Nya lets tokens make changes, one made to update balances sees only your accounts and their balances and changes only a manual account’s balance, and one made to make changes can add, change and delete the transactions entered on your manual accounts, add and change your manual accounts, categories and tags, and undo its own changes (an undo deletes what the change made, and an account it made goes with its transactions and its past balances), but never delete any other account, category or tag, and never change a bank’s transaction itself (though moving or renaming a category changes how every transaction in it is filed and counted). An AI assistant you connect to the MCP server reads the same, and its provider keeps what it reads under its own terms. Never your receipts or documents.
People you share withOnly what you choose, account by account: that it exists, its balance, or its balance and last 30 days of transactions; and, if you choose them, your net worth, as an amount, with only the accounts in it whose balances you share, and your spending by category, holdings, budgets or goals you pick, each as percentages or amounts, worked out from your data each time it is shown to them, never the transactions behind them; until the end date you set, if you set one. And your record of each time it was shown to them, the same one you see. Never the people you split costs with, what anyone owes, or a payment. They can never change anything. Never your receipts or documents.
Your deviceYour accounts, their balances and your net-worth history, as the app last showed them, kept in the browser so it opens at once and works offline. Anyone using the unlocked device can read them. They are cleared when you sign out. Never your receipts or documents.

Backups

Every night the server copies the database to a private Vercel Blob store, and reads each copy back to check it before any older one is deleted. A copy is deleted once it is more than 30 days old, but the newest 7 are always kept, so if backups ever stop, the last ones are not deleted.

A backup holds the same kinds of data as the database, apart from API tokens: the encrypted values and the plain text listed above, and, in a file of their own kept beside it, the data keys in their locked form. Its encrypted parts cannot be read without the keys kept in the server’s environment. API tokens are never backed up, so restoring a backup ends every token, and none revoked before it can work again. It never holds the access a SimpleFIN account gives Nya, which works on its own: restoring a backup ends that access, and you connect again with a new Setup Token. Nor does it hold a Lunch Flow API key, for the same reason: after a restore you connect again with one.

The backups of the data keys are kept apart so that deleting an account can take its key out of every one of them without rewriting the data: the last 7 nights’ are kept, each checked before an older one is deleted. A key leaves them when the account it belongs to is deleted, or, for one that has gone from the database without that, once no backup still kept can need it.

Deleting your account

If you sign in with your own account, Delete my account is in your account window: open your account menu (your picture or initial, at the top right), choose Manage account, then Data & privacy. It disconnects each of your banks at Plaid, deletes everything stored for you, ends all sharing both ways, and deletes your sign-in. If it stops part way, your data is already out of reach, and running it again finishes the job. It ends with a receipt, to copy or save: what was deleted, when the last backup holding your data is gone, and what stays and why.

Each account made on this version of Nya normally has a data key of its own from the start, and an account made before it (or one made while a key couldn’t be) has one once whoever runs this copy has moved it; until then, its data is under a key shared by everyone on this copy.

Deleting an account destroys its own key, so nothing encrypted under it can be decrypted from any copy Nya keeps, normally within minutes of the deletion and at the latest after the next nightly backup that succeeds. The encrypted copies stay in backups, unreadable, until they are deleted, and the plain text in them stays readable until then. Copies under a shared key stay readable with it until they are deleted. The receipt says which applies to the account.

Your receipts and documents are deleted from the file store, part of them by a later nightly run if the store can’t be reached, and the key that would open any copy left of them is destroyed with your account’s key.

What it does not reach:

  • Backups: copies taken before the deletion keep your data until they are deleted, within 32 days while the nightly backup keeps running. If it stops, nothing is deleted until it runs again. The receipt gives the date.
  • A backup of the keys that whoever runs this copy of Nya downloaded by hand, for as long as they keep it.
  • A backup taken while an older version of Nya ran, which holds every key.
  • A record that the account existed: its random id and the day its key was destroyed, kept for good, so that a restored backup never brings the account back.
  • Invite links you made that nobody has used: each holds your sign-in id and the name you gave, and expires on its own within 72 hours.
  • Plaid’s own copy: Plaid keeps what it collected under its own policy. You can see and delete your connections at Plaid in the Plaid Portal.
  • The first account on a copy of Nya, the operator’s own, cannot be deleted from the app.
  • With the shared password there is no delete button: the operator deletes the data.

The Privacy page says how long everything else is kept.

Signing in

With Clerk accounts, Clerk runs the sign-in, and only people the operator has added can get in. Your account window lists the devices you are signed in on, and can sign any of them out.

With the shared password, a correct password sets a signed cookie that the page’s scripts cannot read, sent only over HTTPS and good for 30 days. Sign out everywhere ends every session on every device, this one included, within seconds; changing the password does too. Each IP address gets 10 wrong passwords per 15 minutes, then has to wait. If the database cannot be reached, that limit is skipped rather than locking everyone out.

API tokens

A token you make under API tokens lets a program read your data, and, where whoever runs this copy of Nya lets tokens make changes and you choose when you make it, change some of it, through Nya’s API and its MCP server (see the Developers page). Nya shows it once and never stores it: it keeps a SHA-256 hash of the token’s secret, inside your own data and encrypted with it, and checks a token by comparing hashes in constant time. A token that doesn’t work gets the same answer whatever the reason (unknown, revoked, a wrong secret, or another person’s data), and one whose secret doesn’t match costs the same work whoever’s data it names, so a token can’t be used to find out whose data exists. Only a token whose secret checks out is told more: that its data is being restored, say, and to try again later. Requests with tokens that don’t work are counted by the address they come from, which is turned away for a while after too many.

Making one needs a fresh sign-in, as downloading your data does. A token only reads, unless, where whoever runs this copy of Nya lets tokens make changes, you chose when you made it that it may update manual accounts’ balances or make changes. That choice is kept with it and can never be widened, and a token never gains kinds of changes added to Nya after it was made. A token makes at most 100 requests a minute; one that can update balances or make changes at most 30 writes a minute and 500 changes a day, with 2,000 changes a day for all your tokens. Every change to something that already exists, but a balance, names the version it was made from, so a program working from an old read can’t write over what you just did. Every change is recorded for 30 days under API tokens, with what it changed, where most can be undone or forgotten. A token works until you revoke it, even after Sign out everywhere or a change of the shared password; with sign-in accounts it stops when the account that made it is taken off the list of people allowed in. Deleting your account deletes every token with the rest of your data, and restoring a backup ends every token, since backups leave them out.

Downloading your data

A download of your data needs a fresh sign-in, as making an API token does, and each account can download 5 times an hour. This copy of Nya sends no email, so a download isn’t emailed to you. The file is made as it is sent to your browser and never written anywhere on the way.

Receipts and documents download the same way, as ZIP files of about 50 MB each, each behind a fresh sign-in and a set of them counted as one download: each file in them is decrypted on Nya’s server as it is sent, and the ZIP file is never written anywhere on the way.

You can protect it with a passphrase. It is then encrypted as it is sent, in the age format (age-encryption.org): a key made from your passphrase with scrypt, at the setting age itself uses, which makes each guess at it slow, locks a random key, and the file is encrypted with ChaCha20-Poly1305 in parts that each carry a check, so a file that was changed, cut short or put back together in another order doesn’t open. The passphrase is sent to Nya with the request, used for that, and never stored or logged. Nobody can recover a lost one.

Bringing a download back

Where whoever runs this copy of Nya has turned it on, Bring back a download reads the file in your browser, a few megabytes at a time, and checks every part of it there; a protected one is opened there with its passphrase, which is never sent. Nya gets its records in batches, each with a SHA-256 checksum listed in the restore’s record before the first one is written, takes them only in that order and only if each matches, checks every record again before writing it into your account, encrypted as the rest of your data is, and keeps nothing of the file but what it holds: not the file, not a batch, not in a log.

It needs a fresh sign-in, as a download does, and goes only into an account with nothing in it yet. Nothing in the file can bring back a credential: no access to a bank, no SimpleFIN or Lunch Flow access, no API token, no sharing. While a restore hasn’t finished, the API and the MCP server answer nothing from it and change nothing in it, and what you share answers nothing from it. Undo, while a restore is unfinished and for 7 days after it finishes, empties the account again, as emptying it does: both need a fresh sign-in and are refused while a bank is connected, so a connection is never left running at Plaid, SimpleFIN or Lunch Flow.

A bank brought back from Plaid counts before you link it only on your answer, never inferred, and each answer is checked against what is stored when you give it. From the moment a connection is saved, every connection made since holds those transactions, counted nowhere, until you say whether it is that bank (one carrying it on answers only for itself), so a bank connected again doesn’t count them twice before you answer; what can’t be read holds them too, and says so. Carrying an account from SimpleFIN or Lunch Flow on with one tracked in its place is asked of you while one waits, never assumed, says what it matched, and can be undone.

Security headers

Every response from the app carries these headers:

  • Strict-Transport-Security: browsers only connect to Nya over HTTPS, for two years after a visit.
  • X-Frame-Options: DENY: no other site can show Nya inside a frame.
  • X-Content-Type-Options: nosniff: a file is only ever treated as the type it says it is.
  • Referrer-Policy: strict-origin-when-cross-origin: other sites learn at most that you came from Nya, never which page (an invite link, say).
  • Permissions-Policy: the camera, microphone, location, payments, USB and other device features Nya never uses are switched off.
  • Cross-Origin-Opener-Policy: same-origin-allow-popups: a site that opens Nya gets no hold on its window, while your bank’s sign-in window, opened from Plaid, still works.

Every page also carries a Content-Security-Policy, which this copy of Nya enforces: it may only run scripts that carry a one-time code issued with it, and the scripts those load, and may only load from and connect to Nya itself, Plaid and, with Clerk accounts, Clerk and the bot check it uses, and no other site may show it in a frame.

Where bank connections work

Bank connections go through Plaid and work for US institutions only: Nya asks Plaid for US institutions when you connect. Anything else, such as a bank in another country, an institution Plaid cannot reach, or a house or a car, can be tracked as a manual account: you enter the balance in the account’s own currency, which you choose, and update it when you like.

Your own SimpleFIN account may reach banks Plaid can’t (Redbark, a separate paid service that speaks the same protocol, covers Australia and New Zealand): you pay for it, connect your banks there, and paste a Setup Token into Nya. Nya exchanges the token, once, for read-only access, keeps that access encrypted, never writes it to a log, and asks for your accounts about once a day. It brings no pending transactions, no holdings and no categories.

Where this copy of Nya offers it, your own Lunch Flow account may reach banks in other countries too: you pay Lunch Flow, connect your banks there, and paste the API key of an API destination into Nya. Nya checks the key with Lunch Flow once, keeps it encrypted, never writes it to a log or shows it again, and asks for your accounts about once a day. It brings no pending transactions, no holdings and no categories, and gives no date with a balance, so Nya shows the day it received each one.