Restrict org status RPCs to authenticated members#1751
Conversation
📝 WalkthroughWalkthroughAdds two SECURITY DEFINER PostgreSQL functions — Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Caller as Caller (anon/auth/authenticated/service_role)
participant RPC as is_paying_org / is_trial_org (SECURITY DEFINER)
participant Rights as public.check_min_rights
participant Orgs as public.orgs / public.stripe_info
Caller->>RPC: CALL is_paying_org(orgid) / is_trial_org(orgid)
RPC->>Rights: check_min_rights(caller, orgid)
Rights-->>RPC: allowed / denied
alt allowed
RPC->>Orgs: SELECT stripe_status, trial_ends FROM stripe_info JOIN orgs
Orgs-->>RPC: stripe_status / trial_ends
RPC-->>Caller: boolean / integer (days remaining)
else denied
RPC-->>Caller: false / 0
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
c6c0200 to
bc00e88
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@supabase/migrations/20260308203352_restrict-org-status-rpc-access.sql`:
- Around line 53-55: The SELECT in function public.is_trial_org (using
stripe_info.trial_at, stripe_info.customer_id and orgs.customer_id via orgid)
can return NULL when no stripe_info row or trial_at is NULL; change the return
expression to guarantee a non-null integer—wrap the computed GREATEST(...)
result in COALESCE(..., 0) or fetch into a local integer variable and return 0
when NULL—so the function always returns a non-null integer as declared.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a4b0ac10-fb4b-4a1b-bc7a-25a42c1fe259
📒 Files selected for processing (1)
supabase/migrations/20260308203352_restrict-org-status-rpc-access.sql
supabase/migrations/20260308203352_restrict-org-status-rpc-access.sql
Outdated
Show resolved
Hide resolved
|



Summary (AI generated)
is_paying_organdis_trial_orgprotected to non-public callers in migration20260308203352_restrict-org-status-rpc-access.sql.is_trial_org(uuid)return a non-null integer viaCOALESCE(..., 0)to satisfy contract and remove nullable edge behavior.06_org_functions.sql,20_test_org_management_functions.sql) to run under authenticated/service-role contexts where needed.46_test_org_status_rpcs.sql.Motivation (AI generated)
CI failures came from existing tests calling now-restricted RPCs in unauthenticated contexts and from legacy nullable expectations after the access-hardening/security fix.
Business Impact (AI generated)
The patch prevents org/payment metadata enumeration from public callers while making org status APIs deterministic for authorized callers, and aligns test coverage with the enforced access model.
Test Plan (AI generated)
bun lint.bun lint:backend.supabase/testsfor access-context compatibility and function contract expectations.riderx/fix-rpc-billing-statusontoorigin/mainand force-pushed latest commit.