Files
supabase/apps
Alaister YoungandAlaister Young fbf7ce44ef [FE-3544] fix(studio): role impersonation for truncated cell loads (#48215)
Loading a truncated cell's full value from the inline grid editors or
the row side-panel editors called `getCellValue` without
`roleImpersonationState`, so the fetch ran with full DB privileges
instead of the role selected in **View as role** — leaking values RLS
would deny. Same class of bug #46442 fixed for row copy/export; the
mutation already accepted the state, these call sites just weren't
passing it.

**Changed:**

- Pass `roleImpersonationState` into `getCellValue` in all 4
truncated-cell loaders (inline grid Text/Json editors + row side-panel
Text/Json editors), mirroring the existing `Header.tsx` pattern

**Added:**

- MSW component test on the row side-panel `TextEditor` asserting the
cell-value SQL is wrapped with `set local role` when impersonation is
active, and not wrapped when it isn't

## To test

Note: if the impersonated role can't select the row at all (e.g. force
RLS with no policy), the main grid correctly shows 0 rows under **View
as role**, so the "Load full value" button is never reachable — you
can't exercise this path that way. Use a row the role *can* see and
verify the request is role-wrapped:

- Create a table with a text value long enough to be truncated in the
grid (>16KB), with RLS enabled and an anon-visible row:
  ```sql
  create table public.secrets (id int primary key, secret text);
  alter table public.secrets enable row level security;
  alter table public.secrets force row level security;
create policy "anon can read" on public.secrets for select to anon using
(true);
  insert into public.secrets values (1, repeat('a', 20000));
  ```
- In the Table Editor, set **View as role → anon** — the row should be
visible with the `secret` cell truncated
- With the network tab open, load the full value via each path:
double-click the cell (inline editor) and the row side panel's expand
editor → "Load full text data" (a `jsonb` column exercises the two JSON
editor paths the same way)
- The `pg-meta` query request body should start with `set_config('role',
'anon', true)` + anon JWT claims before the `select secret …`. Before
this fix it was a bare unwrapped `select secret from public.secrets
where id = 1;`
- Drop the policy and confirm the grid shows 0 records under anon
(denial still applies at the grid level); switch back to the default
role and confirm the full value still loads normally with no wrapper

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-23 16:46:51 +08:00
..