60 seconds

A multi-user API,
and you write no code

Every row belongs to whoever created it. Nobody can read anyone else's. There is no schema to write, no migration to run, no middleware to remember — and nothing to deploy but one file.

The whole thing

# 1. one binary, no runtime, no container curl -L https://github.com/javimosch/bkn/releases/latest/download/bkn -o bkn chmod +x bkn # keeps this demo in ./demo.db instead of your real store at ~/.bkn export BKN_DATA=./demo.db export BKN_ADMIN_TOKEN=dev-token # 2. the only line that matters: who owns a row, and who may touch it ./bkn store create notes/entries \ --owner-field user_id \ --access read=owner --access create=owner \ --access update=owner --access delete=owner # 3. two people echo -n 'ada-password' | ./bkn auth user create ada@example.io --password-stdin echo -n 'bob-password' | ./bkn auth user create bob@example.io --password-stdin ./bkn serve &

That is the setup. Now log in as each of them and watch what happens.

login() { curl -s localhost:7799/v1/auth/login -H 'Content-Type: application/json' \ -d "{\"email\":\"$1\",\"password\":\"$2\"}" | jq -r .tokens.access_token; } ADA=$(login ada@example.io ada-password) BOB=$(login bob@example.io bob-password) # ada writes a note. look closely: there is no user_id in this request curl -s localhost:7799/v1/store/notes/entries -H "Authorization: Bearer $ADA" \ -H 'Content-Type: application/json' -d '{"text":"ada note"}' | jq -c .record
{"id":"01M395D4R200HTP291HG48XNDT","text":"ada note", "user_id":"01M395D1FX3RMEG0MHTB7K8QM7"}

The server stamped it. Ada never sent a user_id and could not have got it wrong.

# each of them reads the same URL N=localhost:7799/v1/store/notes/entries curl -s $N -H "Authorization: Bearer $ADA" | jq -c '[.records[].text]' curl -s $N -H "Authorization: Bearer $BOB" | jq -c '[.records[].text]' curl -s -o /dev/null -w '%{http_code}\n' $N # nobody
ada: ["ada note"] bob: ["bob note"] nobody: 401

Now try to cheat

Ada knows Bob's user id. She writes a row and claims it is his.

curl -s localhost:7799/v1/store/notes/entries -H "Authorization: Bearer $ADA" \ -H 'Content-Type: application/json' \ -d '{"text":"forged","user_id":"01M395D1K538BXDMB5NW98ZPAE"}' \ | jq -c '.record | {text, user_id}' # that is bob's id
{"text":"forged","user_id":"01M395D1FX3RMEG0MHTB7K8QM7"} ← ada's id, not bob's bob still sees: ["bob note"]
It did not return an error. It returned the truth. The owner is not a field the caller gets to set — it is stamped from the token, so a request that lies about it is simply corrected. There is no code path where forgetting a check lets it through, because there is no check: the owner is part of the query, not a condition tested beside it.

What you did not write

The interesting one is the third. Owner scoping being part of the read rather than a guard in front of it is the difference between "we remembered everywhere" and "it cannot be forgotten".

Where this goes next

Swap owner for org and the same two lines give you tenant isolation instead of per-user. Swap it for public and you have a read-only API for a front end. When you need real behaviour rather than storage — validating a form, verifying a webhook signature, exporting a CSV — that is a JavaScript file you install with bkn script create, not a service you stand up.

Needs curl and jq. Linux x86_64, statically linked. Delete demo.db and the binary and nothing remains. · bkn · GitHub