Skip to content

[codex] fix API key RBAC oracle#2060

Merged
riderx merged 1 commit into
mainfrom
codex/fix-apikey-rbac-oracle
May 7, 2026
Merged

[codex] fix API key RBAC oracle#2060
riderx merged 1 commit into
mainfrom
codex/fix-apikey-rbac-oracle

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented May 7, 2026

Summary (AI generated)

  • Bound CLI RBAC API-key RPC wrappers to the request capgkey header.
  • Preserved existing CLI RPC signatures while rejecting headerless or mismatched API-key probes.
  • Extended API-key expiration trigger enforcement to unscoped keys through user org memberships.
  • Added pgTAP regression coverage for the oracle and unscoped expiration cases.

Motivation (AI generated)

The existing wrapper RPCs accepted arbitrary apikey arguments from anon callers, bypassing the earlier public EXECUTE revocation on get_user_id(text). The expiration trigger also skipped policy checks for unscoped API keys.

Business Impact (AI generated)

This reduces API-key oracle and metadata exposure risk while preserving CLI compatibility for clients that already send capgkey headers. It also enforces organization API-key expiration settings consistently for unscoped user keys.

Test Plan (AI generated)

  • bun run lint:backend
  • git diff --check
  • Local Supabase startup applied the new migration cleanly
  • docker exec -i supabase_db_capgo-app-fac9e6f5 psql -v ON_ERROR_STOP=1 -U postgres -d postgres < supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
  • docker exec -i supabase_db_capgo-app-fac9e6f5 psql -v ON_ERROR_STOP=1 -U postgres -d postgres < supabase/tests/42_test_apikey_expiration.sql
  • Commit hook: bun run cli:build && vue-tsc --noEmit

Generated with AI

Summary by CodeRabbit

  • New Features

    • Enhanced API key expiration policy enforcement with organization-level constraints.
    • Improved API key authorization and permission validation through updated access control mechanisms.
    • Added support for scoped API key validation to ensure compliance with organizational restrictions.
  • Tests

    • Expanded test coverage for API key expiration policies and permission-based access control.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6359b61d-b57d-4961-b89a-322b92da145d

📥 Commits

Reviewing files that changed from the base of the PR and between 910dad1 and 555b95b.

📒 Files selected for processing (4)
  • supabase/migrations/20260507090436_fix_apikey_rbac_rpc_oracle_and_expiration_scope.sql
  • supabase/tests/42_test_apikey_expiration.sql
  • supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
  • tests/apikeys-expiration.test.ts

📝 Walkthrough

Walkthrough

This PR introduces three new API key authorization and enforcement functions in Supabase: a CLI permission wrapper that validates apikey headers and delegates to RBAC checks, an app-listing function that filters accessible apps by header-based API key identity, and a trigger function that enforces organization-specific API key expiration policies. Comprehensive SQL and E2E tests validate header-based auth, permission enforcement, and expiration constraints across multiple scenarios.

Changes

API Key RBAC and Expiration Enforcement

Layer / File(s) Summary
CLI Permission Wrapper Function
supabase/migrations/20260507090436_fix_apikey_rbac_rpc_oracle_and_expiration_scope.sql
Introduces public.cli_check_permission SECURITY DEFINER function that validates permission keys and apikey headers, resolves API key rows, and delegates authorization to public.rbac_check_permission_direct; configures ownership, revokes public execution, grants execute to anon, authenticated, service_role, and adds documentation.
App Listing Function
supabase/migrations/20260507090436_fix_apikey_rbac_rpc_oracle_and_expiration_scope.sql
Introduces public.get_accessible_apps_for_apikey_v2 SECURITY DEFINER function that extracts apikey from request header, resolves API key row, filters apps using public.rbac_check_permission_direct for app_read permission, and returns apps ordered by created_at DESC; sets privileges and adds descriptive comment for legacy/compatibility behavior.
Expiration Policy Enforcement Trigger
supabase/migrations/20260507090436_fix_apikey_rbac_rpc_oracle_and_expiration_scope.sql
Introduces public.enforce_apikey_expiration_policy() trigger function that validates organization-scoped API key expiration constraints on INSERT/UPDATE: computes applicable scope orgs from limited_to_orgs, limited_to_apps, and org membership; raises exceptions when expiration is required but missing or exceeds organization maximum; recreates apikeys_enforce_expiration_policy trigger on public.apikeys with BEFORE INSERT OR UPDATE.
Expiration Policy Tests
supabase/tests/42_test_apikey_expiration.sql
Adds Test 25 and Test 26 to verify enforce_apikey_expiration_policy rejects unscoped API key inserts when org requires expiration (expires_at = NULL) or expiration exceeds configured maximum; updates test plan count from 24 to 26.
CLI/App-List Authorization Tests
supabase/tests/49_test_apikey_oracle_rpc_permissions.sql
Expands test coverage for anon role to verify cli_check_permission and get_accessible_apps_for_apikey_v2 require matching apikey header (capgkey) and argument; adds negative assertions for missing header and mismatched apikey; adds positive assertions for successful authorization when header/argument align; updates test plan count from 20 to 26.
E2E Test Updates
tests/apikeys-expiration.test.ts
Updates seedPlainApiKey helper to accept optional limitedToOrgs parameter; seeds multiple test suites with limitedToOrgs: [BASE_ORG_ID] for org-scoped context; refactors null-expiration boundary test to directly query public.is_apikey_expired() via SQL instead of HTTP authentication endpoint.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Cap-go/capgo#1951: Both PRs are related: the main PR adds CLI-facing wrappers (public.cli_check_permission and get_accessible_apps_for_apikey_v2) that delegate authorization to public.rbac_check_permission_direct and also add apikey scoping/expiration enforcement, while the retrieved PR directly fixes/enforces API-key org/app scoping inside public.rbac_check_permission_direct—i.e., they touch the same authorization logic and functions.
  • Cap-go/capgo#1962: Both PRs add/modify the enforce_apikey_expiration_policy trigger and accompanying logic/tests to enforce org-level API key expiration (including app-scoped keys).
  • Cap-go/capgo#1966: Both PRs touch API-key-related DB functions and adjust execution/privilege semantics (the main PR adds CLI/apikey RPCs that call helpers like get_apikey_header/is_apikey_expired which the retrieved PR hardened).

Poem

🐰 Hops with glee, the CLI guards now hold the key,
Apps list cleanly when headers align with thee,
Expirations enforced by trigger true,
RBAC wrappers route the auth crew—
A permission dance of orgs and keys,
Testing all paths, validation with ease! 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[codex] fix API key RBAC oracle' directly describes the main change: fixing API key RBAC (Role-Based Access Control) oracle vulnerabilities.
Description check ✅ Passed The description includes all required template sections: summary (comprehensive), test plan (detailed and verified), and checklist items; screenshots are reasonably skipped for backend changes.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-apikey-rbac-oracle

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 SQLFluff (4.1.0)
supabase/migrations/20260507090436_fix_apikey_rbac_rpc_oracle_and_expiration_scope.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, doris, duckdb, exasol, flink, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica

supabase/tests/49_test_apikey_oracle_rpc_permissions.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, doris, duckdb, exasol, flink, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica

supabase/tests/42_test_apikey_expiration.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, doris, duckdb, exasol, flink, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica


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 7, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing codex/fix-apikey-rbac-oracle (555b95b) with main (910dad1)

Open in CodSpeed

@riderx riderx force-pushed the codex/fix-apikey-rbac-oracle branch from 0c44af8 to 555b95b Compare May 7, 2026 10:22
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 7, 2026

@riderx riderx marked this pull request as ready for review May 7, 2026 10:33
@riderx riderx merged commit f14f684 into main May 7, 2026
38 checks passed
@riderx riderx deleted the codex/fix-apikey-rbac-oracle branch May 7, 2026 12:47
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.

1 participant