You’ll build the core of almost every app: people create accounts, sign in, and work with their own data, and nobody can read or change anyone else’s, even by editing your app’s code in their browser. You’ll use: Auth, a table, an access rule, and the TypeScript client (Python is shown for the server-side parts). Time: about 20 minutes.

How it works

Your app holds the publishable key, which is safe to ship. When someone signs in, the client also sends their access token. For every request, Pawabase evaluates the table’s rule with that person’s id, and for lists it turns the rule into a database filter, so only their rows are ever read.

1. Create the table

In Studio, open Data → Tables → Create table: Then open the table’s Settings and set Owner field to owner_id. Pawabase will fill it with the signed-in person’s id on every create, so your app never sends it.

2. Set the access rule

Open the table’s Access tab and set each operation: “Record owner” means the caller is signed in and owner_id equals their id. Because the edit rule reads owner_id, nobody can change that field through your app either, so a note can’t be handed to someone else. See Write records.
Prefer the rule picker’s Record owner to a custom comparison: it becomes a database filter, so lists are exact and fast. See How rules are evaluated.

3. Turn on sign-up

Open Users & auth → Sign-in & registration and make sure email and password sign-in and sign-up are on. For a first test, you can leave email verification off; switch it on before launch (Email verification). Also make sure mail delivery is set up if verification is on, or nobody can confirm their address. Add your app’s address (for example http://localhost:5173) under Users & auth → Domains, so confirmation links can return to it (Redirect URLs).

4. Create the client

src/pawabase.ts
The browser build of the client refuses to start with a secret key, so you can’t ship one by mistake.

5. Sign up and sign in

src/auth.ts
signInWithPassword returns { status: "signed_in" }, or { status: "mfa_required", verify } when the person has two-step verification. See Email and password.

6. Follow the session

The client stores the session, refreshes the token before it expires, and tells you when things change:
src/session.ts
Show your app’s screens from this callback rather than checking once at startup: it also fires when the session ends in another tab or is revoked.

7. Read and write notes

src/notes.ts
Notice what’s not in this code: no eq("owner_id", me). The rule does it on the server. Adding the filter in the client is harmless, but it isn’t what protects the data.

8. Check it with two people

The test that matters is that one person can’t see another’s notes. Run this with a development publishable key:
test/isolation.test.ts
Run tests like this against development in CI whenever rules change. More techniques are in Testing rules.

9. From a server

On your own server, act for a signed-in person by passing their access token, so the same rules apply:
Use a secret key only for work that should ignore the rules, like an admin export, and never on behalf of an individual request. See Node.js.

Troubleshooting

Where next

Teams and organizations

Share data inside a company.

Private files

Let people upload their own files.

Passkeys

Passwordless sign-in.

Access rules

Everything rules can do.