Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
-- Ensure direct PostgREST access to forced-device overrides uses the
-- channel-scoped RBAC permissions instead of broad app read/write rights.

DROP POLICY IF EXISTS "Allow delete for auth, api keys (write+)"
ON public.channel_devices;

DROP POLICY IF EXISTS "Allow insert for auth (write+)"
ON public.channel_devices;

DROP POLICY IF EXISTS "Allow read for auth, api keys (read+)"
ON public.channel_devices;

DROP POLICY IF EXISTS "Allow read for auth (read+)"
ON public.channel_devices;

DROP POLICY IF EXISTS "Allow update for auth, api keys (write+)"
ON public.channel_devices;

CREATE POLICY "Allow delete for auth, api keys (write+)"
ON public.channel_devices
FOR DELETE
TO anon, authenticated
USING (
public.rbac_check_permission_request(
public.rbac_perm_channel_manage_forced_devices(),
owner_org,
app_id,
channel_id
)
);

CREATE POLICY "Allow insert for auth (write+)"
ON public.channel_devices
FOR INSERT
TO authenticated
WITH CHECK (
public.rbac_check_permission_request(
public.rbac_perm_channel_manage_forced_devices(),
owner_org,
app_id,
channel_id
)
);

CREATE POLICY "Allow read for auth (read+)"
ON public.channel_devices
FOR SELECT
TO anon, authenticated
USING (
public.rbac_check_permission_request(
public.rbac_perm_channel_read_forced_devices(),
owner_org,
app_id,
channel_id
)
);

CREATE POLICY "Allow update for auth, api keys (write+)"
ON public.channel_devices
FOR UPDATE
TO anon, authenticated
USING (
public.rbac_check_permission_request(
public.rbac_perm_channel_manage_forced_devices(),
owner_org,
app_id,
channel_id
)
)
WITH CHECK (
public.rbac_check_permission_request(
public.rbac_perm_channel_manage_forced_devices(),
owner_org,
app_id,
channel_id
)
);

COMMENT ON POLICY "Allow delete for auth, api keys (write+)"
ON public.channel_devices IS
'Direct channel_devices deletes require channel.manage_forced_devices for the target channel.';

COMMENT ON POLICY "Allow insert for auth (write+)"
ON public.channel_devices IS
'Direct channel_devices inserts require channel.manage_forced_devices for the target channel.';

COMMENT ON POLICY "Allow read for auth (read+)"
ON public.channel_devices IS
'Direct channel_devices reads require channel.read_forced_devices for the target channel.';

COMMENT ON POLICY "Allow update for auth, api keys (write+)"
ON public.channel_devices IS
'Direct channel_devices updates require channel.manage_forced_devices for both old and new target channels.';
26 changes: 20 additions & 6 deletions supabase/schemas/prod.sql
Original file line number Diff line number Diff line change
Expand Up @@ -19079,7 +19079,7 @@ CREATE POLICY "Allow delete for auth (admin+) (all apikey)" ON "public"."channel



CREATE POLICY "Allow delete for auth, api keys (write+)" ON "public"."channel_devices" FOR DELETE TO "anon", "authenticated" USING ("public"."check_min_rights"('write'::"public"."user_min_right", "public"."get_identity_org_appid"('{write,all}'::"public"."key_mode"[], "owner_org", "app_id"), "owner_org", "app_id", NULL::bigint));
CREATE POLICY "Allow delete for auth, api keys (write+)" ON "public"."channel_devices" FOR DELETE TO "anon", "authenticated" USING ("public"."rbac_check_permission_request"("public"."rbac_perm_channel_manage_forced_devices"(), "owner_org", "app_id", "channel_id"));



Expand All @@ -19099,7 +19099,7 @@ CREATE POLICY "Allow insert for apikey (write,all) (admin+)" ON "public"."apps"



CREATE POLICY "Allow insert for auth (write+)" ON "public"."channel_devices" FOR INSERT TO "authenticated" WITH CHECK ("public"."check_min_rights"('write'::"public"."user_min_right", "public"."get_identity"(), "owner_org", "app_id", NULL::bigint));
CREATE POLICY "Allow insert for auth (write+)" ON "public"."channel_devices" FOR INSERT TO "authenticated" WITH CHECK ("public"."rbac_check_permission_request"("public"."rbac_perm_channel_manage_forced_devices"(), "owner_org", "app_id", "channel_id"));



Expand Down Expand Up @@ -19231,7 +19231,7 @@ CREATE POLICY "Allow read for auth (read+)" ON "public"."app_versions_meta" FOR



CREATE POLICY "Allow read for auth (read+)" ON "public"."channel_devices" FOR SELECT TO "anon", "authenticated" USING ("public"."check_min_rights"('read'::"public"."user_min_right", "public"."get_identity_org_appid"('{read,upload,write,all}'::"public"."key_mode"[], "owner_org", "app_id"), "owner_org", "app_id", NULL::bigint));
CREATE POLICY "Allow read for auth (read+)" ON "public"."channel_devices" FOR SELECT TO "anon", "authenticated" USING ("public"."rbac_check_permission_request"("public"."rbac_perm_channel_read_forced_devices"(), "owner_org", "app_id", "channel_id"));



Expand Down Expand Up @@ -19313,7 +19313,7 @@ CREATE POLICY "Allow update for auth (write+)" ON "public"."app_versions" FOR UP



CREATE POLICY "Allow update for auth, api keys (write+)" ON "public"."channel_devices" FOR UPDATE TO "anon", "authenticated" USING ("public"."check_min_rights"('write'::"public"."user_min_right", "public"."get_identity_org_appid"('{write,all}'::"public"."key_mode"[], "owner_org", "app_id"), "owner_org", "app_id", NULL::bigint)) WITH CHECK ("public"."check_min_rights"('write'::"public"."user_min_right", "public"."get_identity_org_appid"('{write,all}'::"public"."key_mode"[], "owner_org", "app_id"), "owner_org", "app_id", NULL::bigint));
CREATE POLICY "Allow update for auth, api keys (write+)" ON "public"."channel_devices" FOR UPDATE TO "anon", "authenticated" USING ("public"."rbac_check_permission_request"("public"."rbac_perm_channel_manage_forced_devices"(), "owner_org", "app_id", "channel_id")) WITH CHECK ("public"."rbac_check_permission_request"("public"."rbac_perm_channel_manage_forced_devices"(), "owner_org", "app_id", "channel_id"));



Expand Down Expand Up @@ -19555,6 +19555,22 @@ ALTER TABLE "public"."channel_devices" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."channel_permission_overrides" ENABLE ROW LEVEL SECURITY;


COMMENT ON POLICY "Allow delete for auth, api keys (write+)" ON "public"."channel_devices" IS 'Direct channel_devices deletes require channel.manage_forced_devices for the target channel.';



COMMENT ON POLICY "Allow insert for auth (write+)" ON "public"."channel_devices" IS 'Direct channel_devices inserts require channel.manage_forced_devices for the target channel.';



COMMENT ON POLICY "Allow read for auth (read+)" ON "public"."channel_devices" IS 'Direct channel_devices reads require channel.read_forced_devices for the target channel.';



COMMENT ON POLICY "Allow update for auth, api keys (write+)" ON "public"."channel_devices" IS 'Direct channel_devices updates require channel.manage_forced_devices for both old and new target channels.';



CREATE POLICY "channel_permission_overrides_admin_delete" ON "public"."channel_permission_overrides" FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM ("public"."channels"
JOIN "public"."apps" ON ((("channels"."app_id")::"text" = ("apps"."app_id")::"text")))
Expand Down Expand Up @@ -22918,8 +22934,6 @@ ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT SELECT,INS








2 changes: 1 addition & 1 deletion supabase/tests/26_test_rls_policies.sql
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ SELECT
ARRAY[
'Allow delete for auth, api keys (write+)',
'Allow insert for auth (write+)',
'Allow read for auth, api keys (read+)',
'Allow read for auth (read+)',
'Allow update for auth, api keys (write+)',
'Prevent non 2FA access'
],
Expand Down
83 changes: 83 additions & 0 deletions supabase/tests/55_test_channel_devices_forced_device_rbac.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
BEGIN;

SELECT plan(6);

SELECT
ok(
(
SELECT qual
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'channel_devices'
AND policyname = 'Allow read for auth (read+)'
) LIKE '%rbac_check_permission_request%rbac_perm_channel_read_forced_devices%channel_id%',
'channel_devices SELECT policy uses channel.read_forced_devices with channel scope'
);

SELECT
ok(
(
SELECT qual
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'channel_devices'
AND policyname = 'Allow delete for auth, api keys (write+)'
) LIKE '%rbac_check_permission_request%rbac_perm_channel_manage_forced_devices%channel_id%',
'channel_devices DELETE policy uses channel.manage_forced_devices with channel scope'
);

SELECT
ok(
(
SELECT with_check
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'channel_devices'
AND policyname = 'Allow insert for auth (write+)'
) LIKE '%rbac_check_permission_request%rbac_perm_channel_manage_forced_devices%channel_id%',
'channel_devices INSERT policy uses channel.manage_forced_devices with channel scope'
);

SELECT
ok(
(
SELECT qual
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'channel_devices'
AND policyname = 'Allow update for auth, api keys (write+)'
) LIKE '%rbac_check_permission_request%rbac_perm_channel_manage_forced_devices%channel_id%',
'channel_devices UPDATE USING policy uses channel.manage_forced_devices with channel scope'
);

SELECT
ok(
(
SELECT with_check
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'channel_devices'
AND policyname = 'Allow update for auth, api keys (write+)'
) LIKE '%rbac_check_permission_request%rbac_perm_channel_manage_forced_devices%channel_id%',
'channel_devices UPDATE WITH CHECK policy uses channel.manage_forced_devices with channel scope'
);

SELECT
ok(
NOT EXISTS (
SELECT 1
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'channel_devices'
AND (
COALESCE(qual, '') LIKE '%check_min_rights%'
OR COALESCE(with_check, '') LIKE '%check_min_rights%'
)
),
'channel_devices policies do not retain legacy check_min_rights grants'
);

SELECT *
FROM finish();

ROLLBACK;
Loading