Files
ChatApp/supabase/migrations/20260515000001_user_keys.sql
byGalax d10b0fb5c3 feat(db): add user_keys table with RLS and public-key view
Note: not applied locally — push via pnpm prod:migrate when ready.
2026-05-15 22:00:52 +02:00

54 lines
2.3 KiB
SQL

-- Per-user X25519 identity replacing the per-device key model.
-- The private key is sealed with a PIN-derived Argon2id KEK; the server
-- never sees plaintext. Lockout counters protect the 6-digit PIN against
-- online brute force by gating ciphertext delivery (see try_unlock_user_key).
create table if not exists public.user_keys (
user_id uuid primary key references auth.users(id) on delete cascade,
public_key bytea not null,
sealed_private_key bytea not null,
salt bytea not null,
kdf_params jsonb not null,
recovery_sealed_private_key bytea null,
recovery_salt bytea null,
failed_attempts int not null default 0,
locked_until timestamptz null,
failed_recovery_attempts int not null default 0,
recovery_locked_until timestamptz null,
key_version int not null default 1,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
alter table public.user_keys enable row level security;
drop policy if exists user_keys_self_rw on public.user_keys;
create policy user_keys_self_rw
on public.user_keys
for all
to authenticated
using (user_id = auth.uid())
with check (user_id = auth.uid());
-- Public-key view: any authenticated user may read peer public keys to wrap
-- conv-keys for them. Only the columns granted below are exposed.
create or replace view public.user_public_keys
with (security_invoker = true) as
select user_id, public_key, key_version
from public.user_keys;
grant select on public.user_public_keys to authenticated;
-- Column-level grant lets the view see those columns without RLS rejecting
-- non-owners. The self_rw policy still grants full row access to the owner.
grant select (user_id, public_key, key_version) on public.user_keys to authenticated;
drop policy if exists user_keys_select_public_columns on public.user_keys;
create policy user_keys_select_public_columns
on public.user_keys
for select
to authenticated
using (true);
alter publication supabase_realtime add table public.user_keys;