Kesef

Security

Four things, in order of how much they matter

This page is specific on purpose. "Bank-level encryption" tells you nothing; what follows is the actual design, including where it is weakest.

1. The database decides who can read what

Every row of financial data carries an owner, and PostgreSQL itself enforces the rule that you can only see your own. This is not a filter the application remembers to add to each query — it is a policy inside the database, checked on every read and every write.

The difference matters because of how leaks actually happen. In a normal application, one query out of two hundred forgets its WHERE clause and one person sees another person's transactions. Here, the account the API connects with cannot read a single row until it declares whose data it is asking for.

The failure mode is no data, not all data. A code path that forgets to establish an identity gets zero rows back, or a permission error. It does not get everybody's rows. That property was verified against a real database before any application code was written, and a test suite re-verifies it on every change — including through raw SQL, so it is proving the database is enforcing it rather than proving our own filter runs.

2. No access token is ever in your browser

The usual pattern for a web app stores a session token in the browser where JavaScript can read it. Any cross-site-scripting flaw — in the app's own code, or in any one of its dependencies — then reads that token and walks away with full access to the account.

Kesef does not do that. Signing in gives your browser:

  • an opaque session identifier — it is not a token and carries no claims;
  • marked HttpOnly, so no script can read it, ours included;
  • marked Secure and same-site, so it never leaves an encrypted connection or crosses to another site.

The real session lives on the server. That is also what makes "sign out everywhere" instant — a stateless token has to be waited out; a server-side session is deleted.

3. Your AI can read everything and change nothing

You can connect your own AI assistant to your data. The key it uses is read-only, and there is no setting that changes that.

The reason is specific. Merchant names and transaction descriptions come from your bank, which means someone who can send you a payment can choose what text lands in your ledger — including text shaped like an instruction to an AI. Filtering that text is a losing game. Instead:

An AI connection holds a credential that the write endpoints refuse. A prompt injection hidden in a merchant name has nothing to reach for. It is not blocked; it is impossible.

Every AI request is also recorded in an audit log, because a model rather than a person initiated it.

4. Bank credentials are never ours to lose

A bank connection is made through a provider that holds your credentials. Kesef never sees your bank password. What it stores is an access token, encrypted at rest with a key held outside the database — so a leaked database backup does not hand over live bank access.

What the frontend cannot do

The public site you are reading and the application both ship as static files. Neither holds a secret, and neither can reach the database. A compromised frontend dependency can attack the page in your browser — which is bad — but it cannot read a session token, cannot reach the database, and cannot see another account's data.

What each part of the system can touch
Part Holds secrets Can reach the database
This marketing siteNoNo
The web app in your browserNoNo
The APIYesYes, as a restricted role
Your AI over MCPA read-only keyReads only, your rows only

Where it is weakest

Stating this plainly is part of the point. The strongest link in this design is the database boundary; the weakest is the same as every other web application's — a compromised dependency running in your browser could still tamper with what you see on screen while you are signed in. Content-security policy and hash-locked dependencies bound that, and they do not eliminate it.

We would rather say so than imply a guarantee that does not exist.

How to reach us

If you have found something, please tell us before you tell anyone else. We will confirm receipt within two working days and keep you updated until it is closed.