agent: @U0AJM7X8FBR Supabase - move all ORG API Keys into my personal account: #12
agent: @U0AJM7X8FBR Supabase - move all ORG API Keys into my personal account: #12sweetmantech wants to merge 1 commit intomainfrom
Conversation
Deprecating org API keys in favor of personal API keys. Updates all account_api_keys rows where account points to an organization (has members in account_organization_ids) to instead point to personal account fb678396-a68f-4294-ae50-b8cacf9ce77b. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Updates to Preview Branch (agent/-u0ajm7x8fbr-supabase---move-a-1773859903573) ↗︎
Tasks are run on every commit but only new migration files are pushed.
View logs for this Workflow Run ↗︎. |
📝 WalkthroughWalkthroughA SQL migration script reassigns all organization-based API keys to a designated personal account. The migration updates the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 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)
📝 Coding Plan
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: 2
🧹 Nitpick comments (1)
supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sql (1)
11-18: Preserve original key ownership for audit and rollback.This migration overwrites ownership in place and loses
old_accountprovenance. Capture affected rows before update.🧾 Suggested pattern
+CREATE TABLE IF NOT EXISTS public.account_api_keys_org_migration_backup ( + key_id uuid PRIMARY KEY, + old_account uuid NOT NULL, + migrated_to uuid NOT NULL, + migrated_at timestamptz NOT NULL DEFAULT now() +); + +INSERT INTO public.account_api_keys_org_migration_backup (key_id, old_account, migrated_to) +SELECT aak.id, aak.account, 'fb678396-a68f-4294-ae50-b8cacf9ce77b'::uuid +FROM public.account_api_keys aak +WHERE aak.account IN ( + SELECT DISTINCT organization_id + FROM public.account_organization_ids + WHERE organization_id IS NOT NULL +) +AND aak.account <> 'fb678396-a68f-4294-ae50-b8cacf9ce77b'::uuid +ON CONFLICT (key_id) DO NOTHING; + UPDATE public.account_api_keys SET account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b' WHERE account IN (🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sql` around lines 11 - 18, Before performing the in-place UPDATE to account_api_keys, record the original account ownership so provenance/rollback are possible: create or use an audit/temp table and INSERT the rows that will be updated (SELECT id, account AS old_account, organization_id, NOW() AS migrated_at FROM public.account_api_keys WHERE account IN (SELECT DISTINCT organization_id FROM public.account_organization_ids WHERE organization_id IS NOT NULL) AND account != 'fb678396-a68f-4294-ae50-b8cacf9ce77b') to preserve old_account, then run the UPDATE; reference the tables/columns account_api_keys.account, account_api_keys.id and account_organization_ids.organization_id in your statements so the captured rows exactly match those the UPDATE will change.
🤖 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/20260318000000_migrate_org_api_keys_to_personal_account.sql`:
- Around line 11-18: Add a precondition that the target personal account ID
'fb678396-a68f-4294-ae50-b8cacf9ce77b' exists before running the UPDATE against
public.account_api_keys; check existence in the accounts table (or equivalent
primary account table) and RAISE EXCEPTION (or abort the migration) if it's
missing so the UPDATE won't fail due to FK constraints; reference the target ID
and the tables account_api_keys and account_organization_ids when adding this
check.
- Around line 11-18: This migration updates the account_api_keys table by
setting account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b' for multiple
organization-derived keys (see account_api_keys.account and
account_organization_ids.organization_id); you must verify and fix
application-level authorization to ensure keys don't gain access to other
organizations: review all code paths that authorize by account (e.g., API
handlers, service methods, middleware) and either (a) preserve original
organization ownership in the migration or map each key to a specific personal
account with an explicit tenant linkage, (b) add application checks that enforce
organization-scoped access for keys now consolidated, or (c) implement
RLS/policies on account_api_keys to enforce tenant scoping; update the migration
to include the chosen approach and add unit/integration tests to cover
authorization behavior for account_api_keys after migration.
---
Nitpick comments:
In
`@supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sql`:
- Around line 11-18: Before performing the in-place UPDATE to account_api_keys,
record the original account ownership so provenance/rollback are possible:
create or use an audit/temp table and INSERT the rows that will be updated
(SELECT id, account AS old_account, organization_id, NOW() AS migrated_at FROM
public.account_api_keys WHERE account IN (SELECT DISTINCT organization_id FROM
public.account_organization_ids WHERE organization_id IS NOT NULL) AND account
!= 'fb678396-a68f-4294-ae50-b8cacf9ce77b') to preserve old_account, then run the
UPDATE; reference the tables/columns account_api_keys.account,
account_api_keys.id and account_organization_ids.organization_id in your
statements so the captured rows exactly match those the UPDATE will change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cb99a6a5-460e-4555-b829-9760654b219e
📒 Files selected for processing (1)
supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sql
| UPDATE public.account_api_keys | ||
| SET account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b' | ||
| WHERE account IN ( | ||
| SELECT DISTINCT organization_id | ||
| FROM public.account_organization_ids | ||
| WHERE organization_id IS NOT NULL | ||
| ) | ||
| AND account != 'fb678396-a68f-4294-ae50-b8cacf9ce77b'; |
There was a problem hiding this comment.
Add a precondition check that the target personal account exists.
If fb678396-a68f-4294-ae50-b8cacf9ce77b is missing in any environment, this update can fail on FK enforcement and block the migration.
🔧 Proposed fix
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1
+ FROM public.accounts
+ WHERE id = 'fb678396-a68f-4294-ae50-b8cacf9ce77b'::uuid
+ ) THEN
+ RAISE EXCEPTION
+ 'Target personal account % does not exist',
+ 'fb678396-a68f-4294-ae50-b8cacf9ce77b';
+ END IF;
+END $$;
+
UPDATE public.account_api_keys
SET account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b'
WHERE account IN (📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| UPDATE public.account_api_keys | |
| SET account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b' | |
| WHERE account IN ( | |
| SELECT DISTINCT organization_id | |
| FROM public.account_organization_ids | |
| WHERE organization_id IS NOT NULL | |
| ) | |
| AND account != 'fb678396-a68f-4294-ae50-b8cacf9ce77b'; | |
| DO $$ | |
| BEGIN | |
| IF NOT EXISTS ( | |
| SELECT 1 | |
| FROM public.accounts | |
| WHERE id = 'fb678396-a68f-4294-ae50-b8cacf9ce77b'::uuid | |
| ) THEN | |
| RAISE EXCEPTION | |
| 'Target personal account % does not exist', | |
| 'fb678396-a68f-4294-ae50-b8cacf9ce77b'; | |
| END IF; | |
| END $$; | |
| UPDATE public.account_api_keys | |
| SET account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b' | |
| WHERE account IN ( | |
| SELECT DISTINCT organization_id | |
| FROM public.account_organization_ids | |
| WHERE organization_id IS NOT NULL | |
| ) | |
| AND account != 'fb678396-a68f-4294-ae50-b8cacf9ce77b'; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sql`
around lines 11 - 18, Add a precondition that the target personal account ID
'fb678396-a68f-4294-ae50-b8cacf9ce77b' exists before running the UPDATE against
public.account_api_keys; check existence in the accounts table (or equivalent
primary account table) and RAISE EXCEPTION (or abort the migration) if it's
missing so the UPDATE won't fail due to FK constraints; reference the target ID
and the tables account_api_keys and account_organization_ids when adding this
check.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find SQL objects referencing account_api_keys
rg -n -C3 --type=sql '\baccount_api_keys\b'
# Find account-scoping logic tied to account_api_keys.account
rg -n -C4 --type=sql 'account_api_keys\.account|USING\s*\(|WITH\s+CHECK\s*\(|\baccount\s*='Repository: recoupable/database
Length of output: 6245
🏁 Script executed:
rg -n "CREATE POLICY.*account_api_keys|ON.*account_api_keys" --type=sqlRepository: recoupable/database
Length of output: 725
🏁 Script executed:
rg -n "CREATE POLICY" --type=sql -A 3 | head -100Repository: recoupable/database
Length of output: 1316
🏁 Script executed:
cat -n supabase/migrations/20251206000000_create_account_api_keys.sqlRepository: recoupable/database
Length of output: 1222
🏁 Script executed:
find supabase/migrations -name "*.sql" -type f | xargs grep -l "account_api_keys\|account.*policy" | xargs cat | grep -n "CREATE POLICY\|account_api_keys" | head -50Repository: recoupable/database
Length of output: 646
🏁 Script executed:
cat -n supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sqlRepository: recoupable/database
Length of output: 964
🏁 Script executed:
rg -n "account_api_keys" --type=sql -A 5 -B 2 | grep -E "FUNCTION|CREATE|SELECT|WHERE" | head -50Repository: recoupable/database
Length of output: 934
🏁 Script executed:
rg "account_api_keys.*POLICY|POLICY.*account_api_keys" --type=sqlRepository: recoupable/database
Length of output: 45
🏁 Script executed:
find supabase/migrations -name "*.sql" -type f -exec grep -l "POLICY" {} \; | xargs basename -aRepository: recoupable/database
Length of output: 115
Verify whether reassigning all org keys to one account breaks application logic.
No RLS policies are defined for account_api_keys, so authorization is not scoped via the account column at the database level. However, the migration still consolidates keys from multiple organization accounts into a single personal account (fb678396-a68f-4294-ae50-b8cacf9ce77b). Confirm that application-level authorization correctly handles this consolidation and that keys don't gain unintended access to other organizations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@supabase/migrations/20260318000000_migrate_org_api_keys_to_personal_account.sql`
around lines 11 - 18, This migration updates the account_api_keys table by
setting account = 'fb678396-a68f-4294-ae50-b8cacf9ce77b' for multiple
organization-derived keys (see account_api_keys.account and
account_organization_ids.organization_id); you must verify and fix
application-level authorization to ensure keys don't gain access to other
organizations: review all code paths that authorize by account (e.g., API
handlers, service methods, middleware) and either (a) preserve original
organization ownership in the migration or map each key to a specific personal
account with an explicit tenant linkage, (b) add application checks that enforce
organization-scoped access for keys now consolidated, or (c) implement
RLS/policies on account_api_keys to enforce tenant scoping; update the migration
to include the chosen approach and add unit/integration tests to cover
authorization behavior for account_api_keys after migration.
Automated PR from coding agent.
Summary by CodeRabbit