fix(db): enforce API key expiry in get_user_org_ids#1745
fix(db): enforce API key expiry in get_user_org_ids#1745NlDev-hub wants to merge 1 commit intoCap-go:mainfrom
Conversation
📝 WalkthroughWalkthroughThis pull request enhances API key security by replacing direct database lookups with a dedicated function call and adding expiration validation checks across authentication flows. Updates include migration schema changes and corresponding test coverage for the new expiration logic. Changes
Sequence DiagramsequenceDiagram
participant Client
participant AuthFunc as Auth Function<br/>(get_orgs_v6 / get_user_org_ids)
participant Lookup as find_apikey_by_value()
participant Check as is_apikey_expired()
participant DB as Database Result
Client->>AuthFunc: Request with API key
AuthFunc->>Lookup: Retrieve API key by value
Lookup->>DB: Query apikeys table
DB-->>Lookup: Return API key record
Lookup-->>AuthFunc: API key data
AuthFunc->>Check: Validate expiration
alt Key Expired
Check-->>AuthFunc: Expired (true)
AuthFunc-->>Client: Error: API_KEY_EXPIRED
else Key Valid
Check-->>AuthFunc: Not expired (false)
AuthFunc->>DB: Proceed with org lookup
DB-->>AuthFunc: Organization data
AuthFunc-->>Client: Success: Return orgs
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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/20251222140030_rbac_system.sql`:
- Around line 2024-2035: Revert the edits made inside the committed migration
supabase/migrations/20251222140030_rbac_system.sql (remove the added SELECT/IF
blocks) and instead create a new migration using supabase migration new
<feature_slug>; in that new migration file apply the intended change to the
function public.get_user_org_ids() (add the SELECT
public.find_apikey_by_value(...) into api_key and the expiry check using
public.is_apikey_expired(api_key.expires_at) with the corresponding pg_log and
RAISE EXCEPTION statements) so the fix is introduced via a fresh migration
rather than editing a committed one.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 156e321f-7621-41d3-86ed-8096c6818ec7
📒 Files selected for processing (3)
supabase/migrations/20251222140030_rbac_system.sqlsupabase/schemas/prod.sqlsupabase/tests/42_test_apikey_expiration.sql
| SELECT * FROM public.find_apikey_by_value(api_key_text) into api_key; | ||
|
|
||
| IF api_key IS NULL THEN | ||
| PERFORM public.pg_log('deny: INVALID_API_KEY', jsonb_build_object('source', 'header')); | ||
| RAISE EXCEPTION 'Invalid API key provided'; | ||
| END IF; | ||
|
|
||
| -- Reject expired API keys (parity with get_orgs_v6/get_identity_*) | ||
| IF public.is_apikey_expired(api_key.expires_at) THEN | ||
| PERFORM public.pg_log('deny: API_KEY_EXPIRED', jsonb_build_object('key_id', api_key.id)); | ||
| RAISE EXCEPTION 'API key has expired'; | ||
| END IF; |
There was a problem hiding this comment.
Move this fix to a new migration file instead of editing a committed migration.
The logic at Line 2024 and Line 2031-Line 2035 is good, but applying it inside supabase/migrations/20251222140030_rbac_system.sql violates the migration workflow and can cause migration drift across environments. Revert these edits here and apply the same CREATE OR REPLACE FUNCTION public.get_user_org_ids() change in a new migration file.
As per coding guidelines, “Never edit committed migrations in supabase/migrations/; create new migrations with supabase migration new <feature_slug> and edit a single migration file until feature ships.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@supabase/migrations/20251222140030_rbac_system.sql` around lines 2024 - 2035,
Revert the edits made inside the committed migration
supabase/migrations/20251222140030_rbac_system.sql (remove the added SELECT/IF
blocks) and instead create a new migration using supabase migration new
<feature_slug>; in that new migration file apply the intended change to the
function public.get_user_org_ids() (add the SELECT
public.find_apikey_by_value(...) into api_key and the expiry check using
public.is_apikey_expired(api_key.expires_at) with the corresponding pg_log and
RAISE EXCEPTION statements) so the fix is introduced via a fresh migration
rather than editing a committed one.
|



Summary
Fixes an API-key-expiration bypass in
get_user_org_ids().get_user_org_ids()currently loads API keys fromapikeysbut does not reject expired keys before returning org IDs. This allows expired keys to continue resolving org memberships via RPC.Changes
find_apikey_by_value(api_key_text)inget_user_org_ids()is_apikey_expired(api_key.expires_at)guardAPI key has expired(same behavior style used inget_orgs_v6/ identity functions)supabase/tests/42_test_apikey_expiration.sqlsupabase/migrations/20251222140030_rbac_system.sqlsupabase/schemas/prod.sqlWhy
Maintains consistent expiration enforcement across RPC auth paths and prevents stale-key use for org-id enumeration.
Test notes
get_user_org_ids()Summary by CodeRabbit
Release Notes
Security
Tests