Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
66390bc
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
655ddee
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
f00cf1c
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
7989c3b
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
04f5309
test(rls): assert empty result for non-admin global_stats access
riderx Mar 2, 2026
9958797
test(rls): resolve merge conflict on global_stats access assertion
riderx Mar 3, 2026
5a343ea
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
f0f1a7f
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
9874eb4
test(rls): assert empty result for non-admin global_stats access
riderx Mar 2, 2026
c7b53e3
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
8138b88
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
534e6eb
test(rls): fix merge conflict residue after rebase
riderx Mar 3, 2026
7d50b54
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
ba7f592
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
13ca4ce
test(rls): assert empty result for non-admin global_stats access
riderx Mar 2, 2026
a00781d
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
3ae7691
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
9a79832
Merge branch 'riderx/fix-global-stats' of https://github.com/Cap-go/c…
riderx Mar 3, 2026
bea7ceb
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
abcbcba
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
a8b8aed
test(rls): assert empty result for non-admin global_stats access
riderx Mar 2, 2026
f2f5f3e
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
e98af0a
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
d00dacf
test(rls): fix merge conflict residue after rebase
riderx Mar 3, 2026
1faf8d7
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
e509bc2
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
a9d4fe0
test(rls): assert empty result for non-admin global_stats access
riderx Mar 2, 2026
39b318d
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
b8ef079
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
43aecf5
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
359f783
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
e2423b1
fix(db): restrict global_stats to admin users
riderx Feb 26, 2026
41e9db1
fix(db): use unique migration version for global_stats lock
riderx Feb 27, 2026
1b6d45a
Merge branch 'riderx/fix-global-stats' of https://github.com/Cap-go/c…
riderx Mar 3, 2026
2f066a5
Merge branch 'main' into riderx/fix-global-stats
riderx Mar 3, 2026
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,27 @@
-- =============================================================================

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Rename migration to a unique timestamp

This migration uses the 20260226000000 version prefix, but that prefix is already used by 20260226000000_org_rls_require_self_2fa_update.sql; Supabase migration ordering/history is version-based, so this collision can make one migration unapplied or non-deterministic across environments, which risks leaving global_stats access policy changes out of sync.

Useful? React with 👍 / 👎.

-- Migration: Restrict global_stats access to platform admins only
-- =============================================================================

-- Remove the permissive anonymous read policy that currently exposes KPI data.
DROP POLICY IF EXISTS "Allow anon to select" ON public.global_stats;

-- Replace with an admin-only read policy.
DROP POLICY IF EXISTS "Deny anon and authenticated reads" ON public.global_stats;
DROP POLICY IF EXISTS "Allow admin users to select global_stats" ON public.global_stats;
CREATE POLICY "Allow admin users to select global_stats"
ON public.global_stats
FOR SELECT TO authenticated
USING (
EXISTS (
SELECT
1
FROM
(SELECT auth.uid() AS uid) AS auth_user
WHERE
public.is_admin(auth_user.uid)
)
);

-- Remove table privileges for low-trust roles.
REVOKE ALL PRIVILEGES ON TABLE public.global_stats FROM anon, authenticated;
GRANT SELECT ON TABLE public.global_stats TO authenticated;
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 @@ -41,7 +41,7 @@ SELECT
policies_are(
'public',
'global_stats',
ARRAY['Allow anon to select'],
ARRAY['Allow admin users to select global_stats'],
'global_stats should have correct policies'
);

Expand Down
37 changes: 34 additions & 3 deletions supabase/tests/27_test_rls_scenarios.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ BEGIN;
-- 'com.demoadmin.app', 'com.demo.app'
-- Plan tests
SELECT
plan (6);
plan (8);

-- Test 1: Users can see organizations they belong to
SET
Expand Down Expand Up @@ -55,11 +55,42 @@ SELECT
'Anonymous users should be able to select from plans table'
);

-- Test 4: Global stats is accessible to anonymous
-- Test 4: Anonymous users should not access global_stats
SELECT
throws_ok (
'SELECT COUNT(*) FROM public.global_stats',
'42501',
'permission denied',
'Anonymous users should not be able to select from global_stats'
);
-- Test 4b: Authenticated users should not be able to read global_stats
SET
LOCAL role TO authenticated;
SET
LOCAL request.jwt.claims TO '{"sub": "6aa76066-55ef-4238-ade6-0b32334a4097"}';

SELECT
is (
(
SELECT
COUNT(*)
FROM
public.global_stats
),
0::bigint,
'Authenticated non-admin users should see no rows in global_stats'
);

-- Test 4c: Non-admin can be replaced with admin and still query this table
SET
LOCAL role TO authenticated;
SET
LOCAL request.jwt.claims TO '{"sub": "c591b04e-cf29-4945-b9a0-776d0672061a"}';

SELECT
lives_ok (
'SELECT COUNT(*) FROM public.global_stats',
'Anonymous users should be able to select from global_stats'
'Admin users should be able to select from global_stats'
);

-- Test 5: Users table has RLS enabled
Expand Down
Loading