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.
Request logs
Airtable keeps no record of individual API calls. The proxy logs every one — who called, what they read or wrote, and when.
Media caching
Airtable attachment links expire. VibeKit's don't — your photos stay up.
Quick Proxies
A public link per record that serves one field: a redirect, an image, a file or a QR code. No app code.
Try it on your own base
Paste a token, point at a view, hand the prompt to your agent.