dmitrymaranik
Hi, and thanks for ElatoAI. I ran a static RLS analyzer ([pgrls](https://github.com/pgrls/pgrls)) over `supabase/migrations` and wanted to flag the policies on `public.users` — applying the migrations to a clean Postgres confirms the `anon` (unauthenticated) role has broad read **and write** access: | policy | cmd | role | predicate | |---|---|---|---| | `Enable read access for all users` | SELECT | public | `USING (true)` | | `Update user table` | UPDATE | **anon** | `USING (true) WITH CHECK (true)` | Concretely, with just the project's `anon` API key (no login): - **read** — every row of `public.users` is selectable. - **write** — every row of `public.users` is updatable: an anonymous caller can rewrite **any** user's row, not only their own. I suspect part of this is intentional for the device path — `esp users can update devices` is also `anon`-scoped, so the ESP32 likely talks to Supabase with the anon key. That's a reasonable pattern, but as written these policies are **unscoped** (`USING (true)`), so they apply to *all* rows for *any* anonymous caller rather than just the row that belongs to the calling device/user. Worth scoping each to the owning row — e.g. `USING (id = <the identifier the device/session carries>)` — and moving anything that doesn't truly need to be public off the `anon`/`public` role. (Also, lower priority: no `FORCE ROW LEVEL SECURITY` on these tables, and the same `USING (true)` public-read shape on `devices` / `languages` / `personalities`.) I held off on a PR because the right predicate depends on your device-auth model — happy to send one once you confirm which column ties a `users` row to its device/session and whether the public read is deliberate.