Skip to content

fix(db): restrict apikey table management RLS#2134

Closed
hieu-lee wants to merge 5 commits into
Cap-go:mainfrom
hieu-lee:bounty-1667-restrict-apikey-table-rls
Closed

fix(db): restrict apikey table management RLS#2134
hieu-lee wants to merge 5 commits into
Cap-go:mainfrom
hieu-lee:bounty-1667-restrict-apikey-table-rls

Conversation

@hieu-lee
Copy link
Copy Markdown

@hieu-lee hieu-lee commented May 11, 2026

Summary

  • Restrict direct public.apikeys SELECT/DELETE RLS to JWT callers or unrestricted all API keys by reusing get_identity_for_apikey_creation()
  • Keep the generated schema dump aligned with the new migration
  • Extend the API-key security pgTAP test so an org/app-limited key cannot enumerate or delete sibling API-key rows through direct table access

/claim #1667

Motivation

The Edge API-key management endpoints already reject org/app-limited API keys. The table policies still allowed direct PostgREST SELECT/DELETE for any owner key with broad enough legacy mode, which left a bypass around those endpoint checks.

Test Plan

  • git diff --check
  • Static assertion check: 53_test_apikey_creation_security.sql now has 10 planned assertions and 10 assertion calls
  • Supabase pgTAP not run locally because this laptop cannot run Docker

Checklist

  • Security-sensitive RLS change is limited to API-key table SELECT/DELETE management policies
  • Schema dump is aligned with the migration
  • Regression coverage documents the limited-key direct table bypass
  • No application API behavior is intentionally changed beyond closing the direct PostgREST bypass

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

📝 Walkthrough

Walkthrough

This PR adds Row Level Security (RLS) policies to restrict direct PostgREST access to the public.apikeys table. The migration introduces SELECT and DELETE policies that check whether the requesting user's identity matches the API key owner. The schema is updated to reflect these policies, and tests validate that limited API keys cannot enumerate or modify sibling keys.

Changes

API Key Security

Layer / File(s) Summary
RLS Policy Definitions
supabase/migrations/20260511023000_restrict_apikey_table_management_rls.sql
New FOR SELECT and FOR DELETE policies added to public.apikeys, restricting access to rows where user_id matches the identity from public.get_identity_for_apikey_creation().
Schema Policy Application
supabase/schemas/prod.sql
DELETE and SELECT policies updated to use public.get_identity_for_apikey_creation() instead of the previous get_identity() function for user ownership verification.
Access Isolation Tests
supabase/tests/53_test_apikey_creation_security.sql
Test plan increased to 10; new assertions verify limited API keys cannot enumerate sibling keys via direct table SELECT and cannot delete sibling keys when the limited key is active.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • Cap-go/capgo#1948: Both PRs tighten the apikey RLS/auth identity path—this PR switches RLS policies to use get_identity_for_apikey_creation(), while the related PR enforces hashed-key checks inside the shared auth function.

Poem

🐰 A rabbit hops with glee,
Keys now guarded carefully!
RLS policies standing tall,
Limited access for one and all—
User identity flows so true,
Security stitched through and through! 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(db): restrict apikey table management RLS' clearly and concisely summarizes the main change: adding RLS restrictions to apikey table management to prevent bypasses.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description addresses the template with a clear summary, motivation, and test plan. However, it lacks the formal checklist section matching the required template structure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@supabase/migrations/20260511023000_restrict_apikey_table_management_rls.sql`:
- Line 9: Change the policy role target from TO "anon", "authenticated" to TO
"authenticated" so the RLS/admin policy only applies to authenticated sessions;
update every occurrence of the clause (the instance that currently reads TO
"anon", "authenticated" and the other occurrence mentioned around lines 17) to
TO "authenticated" to ensure API-key identity resolution runs through the
authenticated role only.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2c3688fb-d4cb-4329-89e0-68fca6945e65

📥 Commits

Reviewing files that changed from the base of the PR and between 3d184f8 and 07151eb.

📒 Files selected for processing (3)
  • supabase/migrations/20260511023000_restrict_apikey_table_management_rls.sql
  • supabase/schemas/prod.sql
  • supabase/tests/53_test_apikey_creation_security.sql

Comment thread supabase/migrations/20260511023000_restrict_apikey_table_management_rls.sql Outdated
@hieu-lee

This comment was marked as abuse.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 11, 2026

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing hieu-lee:bounty-1667-restrict-apikey-table-rls (b3a8ae7) with main (b69f22a)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant