Skip to content

[codex] Fix RBAC API key password policy gate#2080

Merged
riderx merged 13 commits into
mainfrom
codex/fix-apikey-rbac-password-policy
May 10, 2026
Merged

[codex] Fix RBAC API key password policy gate#2080
riderx merged 13 commits into
mainfrom
codex/fix-apikey-rbac-password-policy

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented May 8, 2026

Summary (AI generated)

  • Fixed check_min_rights so RBAC-managed API keys can be resolved before password-policy and 2FA gates run.
  • Added a pgTAP regression for an anon apps RLS read using an RBAC v2 API key on an org with password policy enabled.

Motivation (AI generated)

RBAC v2 API keys have mode = NULL, so get_identity_org_appid() can return NULL before rbac_check_permission_direct() resolves the key. That made password-policy enforcement reject valid CLI/API-key requests with CHECK_MIN_RIGHTS_PASSWORD_POLICY_ENFORCEMENT.

Business Impact (AI generated)

This restores CLI/API-key access for organizations using RBAC v2 and password policies, avoiding false authorization failures for valid automation keys.

Test Plan (AI generated)

  • bun lint
  • Commit hook: bun run cli:build && vue-tsc --noEmit
  • bun scripts/supabase-worktree.ts test db supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
  • Full pgTAP suite: blocked by existing PostgreSQL segfault in supabase/tests/17_test_prevent_admin_privilege_escalation.sql during SELECT my_tests()

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened API key authorization to enforce org-level password policies and 2FA gates so access is denied when requirements aren't met.
    • Improved handling of org/app/channel scoping for permission checks.
  • Tests

    • Expanded RBAC v2 test coverage for API key scenarios, including compliant and stale password-policy states.
  • UI

    • Fixed metric formatting in organization credits display.

Review Change Stack

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces public.check_min_rights (SECURITY DEFINER) to resolve effective org scope, load API-key identity, enforce org-level 2FA and password-policy gates, delegate to legacy checks when RBAC disabled, or call rbac_check_permission_direct for RBAC; updates function ownership/permissions and adds pgTAP tests for satisfied and stale RBAC-v2 API-key password-policy scenarios.

Changes

API Key RBAC and Password Policy Authorization

Layer / File(s) Summary
Authorization Function Logic
supabase/migrations/20260510171857_fix_apikey_rbac_password_policy_gate.sql
Defines public.check_min_rights to resolve effective org scope, load API-key identity header, enforce 2FA and password-policy gates, and delegate to legacy check or invoke rbac_check_permission_direct based on RBAC enablement.
Function Security and Privileges
supabase/migrations/20260510171857_fix_apikey_rbac_password_policy_gate.sql
Sets function owner to postgres, revokes EXECUTE from PUBLIC, and grants EXECUTE to anon, authenticated, and service_role roles.
Test Plan Update
supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
Increments pgTAP plan count from 24 to 27 to include three new assertions.
Test Setup and RBAC Bindings
supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
Adds DO $$ block that enables RBAC v2, writes password-policy JSON config, recreates an RBAC-v2 API key scoped to the org, upserts user_password_compliance, and creates an app-reader role binding for com.demo.app.
Satisfied Policy Test
supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
Sets request.headers.capgkey to RBAC-v2 API key and asserts anon can read com.demo.app apps when password policy is satisfied.
Stale Policy Test
supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
Deletes user_password_compliance to simulate stale policy and asserts anon cannot read com.demo.app and check_min_rights returns false.
Minor UI Tweak
src/pages/settings/organization/Credits.vue
Removes precomputed formatted min value; formats build_time minutes inline for display when under 1 hour.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Cap-go/capgo#2078: Adds a PostgreSQL scalability gate mentioning avoiding per-row calls to helpers like check_min_rights/get_identity — directly related to this PR's check_min_rights changes.
  • Cap-go/capgo#1951: Modifies RBAC permission checks and scoped API-key/org/app enforcement overlapping rbac_check_permission_direct and related authorization paths.
  • Cap-go/capgo#2074: Calls and relies on check_min_rights in usage_credit_readable_org_ids() and its tests — related to the new gate behavior.

Poem

🐰 A gateway stands tall, so precise and so wise,
With RBAC and policies checking all ties,
Passwords must pass, and the orgs must align,
So check_min_rights guards each app and design,
Now tested with care in the stale and the new!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main fix: addressing RBAC API key password policy gate issues, which is the primary objective of this changeset.
Description check ✅ Passed The PR description includes a comprehensive Summary, Motivation, Business Impact, and detailed Test Plan with checkmarks, but omits the Screenshots and Checklist sections from the template.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-apikey-rbac-password-policy

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

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 8, 2026

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing codex/fix-apikey-rbac-password-policy (2f0d4da) with main (31788db)2

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.

  2. No successful run was found on main (de13e19) during the generation of this report, so 31788db was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Copy link
Copy Markdown

@adamsardo adamsardo left a comment

Choose a reason for hiding this comment

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

I reviewed the RBAC API-key/password-policy path. The implementation direction makes sense, but I think this needs one negative regression before merge.

The new check_min_rights branch intentionally skips its local 2FA/password-policy block for API-key-only calls (v_apikey IS NOT NULL AND user_id IS NULL) and relies on rbac_check_permission_direct to enforce the API-key owner's password policy later. The added pgTAP case only proves the happy path where user_password_compliance already contains the matching policy hash.

Could you add a denial assertion for the same RBAC v2 API key after removing/staling that compliance row? For example, with the same capgkey, delete the user_password_compliance row or change password_policy_config, then assert the app RLS query returns 0 rows and/or public.check_min_rights('read', NULL, org_id, app_id, NULL) returns false. That would lock down the actual security invariant this patch is trying to preserve, not just the allowed path.

@riderx
Copy link
Copy Markdown
Member Author

riderx commented May 10, 2026

Addressed the review by adding the negative RBAC v2 API-key/password-policy regression: after deleting the owner's user_password_compliance row, the same capgkey now asserts both the app RLS query returns 0 rows and check_min_rights returns false. CI is green on the latest commit.

@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit 123c505 into main May 10, 2026
40 checks passed
@riderx riderx deleted the codex/fix-apikey-rbac-password-policy branch May 10, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants