Core feature

Every request only ever returns the records that belong to the signed-in user — enforced on the proxy, not in the browser.

In a real app, "logged in" is not the same as "allowed to see this". A signed-in user should get their records and only theirs. Do that filtering in the browser and it isn't security — it's a suggestion, because anyone can change the request the page sends.

VibeKit enforces it on the proxy. You attach rules to an endpoint that bind to the signed-in user's own record — their id, their email, a field on their row — so every read and write is filtered down to the records that belong to them before Airtable is ever touched. Nothing the client sends can widen that scope, and it fails closed: no valid user, no data.

Record-level, like Supabase's row-level security

If you've used Postgres or Supabase, this is the same idea as row-level security (RLS) — only your rows live in Airtable. Instead of writing SQL policies, you write rules in the admin that reference the signed-in user (their record and auth context), and the proxy applies them to every request against that endpoint.

Built on your Airtable users

The user is a record in your Airtable users view (see Airtable authentication), so an access rule is just a field on that row. Change the row and you change what that person can see — in real time. Paired with the server-side key, your base is never exposed and the rules can't be bypassed, so one base can safely serve many users who each see only their own slice of it.

Questions this page answers
row level security for airtablerestrict airtable records to the logged-in usersupabase rls equivalent for airtableper-user record access on the airtable apisecure multi-tenant airtable app