Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Restore anon execute on get_user_id(text) for published CLI 8.42.x.
-- Keep get_user_id(text,text), get_org_perm_for_apikey*, invite_user_to_org_rbac
-- revoked for anon (see 20260824144021_revoke_anon_oracle_rpc_execute.sql).

GRANT EXECUTE ON FUNCTION public.get_user_id(text) TO anon;
6 changes: 3 additions & 3 deletions tests/rbac-apikey-request-identity-rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,15 @@ describe('legacy CLI RBAC compatibility RPCs', () => {
expect(ownerPerm).toBe('perm_owner')
})

it.concurrent('denies get_user_id for anonymous API-key callers', async () => {
it.concurrent('keeps get_user_id callable for published CLI anonymous API-key callers', async () => {
const client = createApiKeyClient(APIKEY_TEST_ORG_SUPER_ADMIN)

const { data, error } = await (client.rpc as any)('get_user_id', {
apikey: APIKEY_TEST_ORG_SUPER_ADMIN,
}).single()

expect(data).toBeNull()
expect(error?.code === '42501' || /permission denied/i.test(error?.message ?? '')).toBe(true)
expect(error).toBeNull()
expect(data).toBe(USER_ID)
})

it.concurrent('keeps get_user_id callable for authenticated API-key callers', async () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/security-definer-execute-hardening.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const ANON_ALLOWED_PROCS = [
'public.reject_access_due_to_2fa_for_app(character varying)',
'public.reject_access_due_to_2fa_for_org(uuid)',
'public.request_actor_user_id()',
'public.get_user_id(text)',
'public.update_org_invite_role_rbac(uuid, uuid, text)',
'public.update_tmp_invite_role_rbac(uuid, text, text)',
'public.verify_mfa()',
Expand All @@ -106,7 +107,6 @@ const AUTHENTICATED_ONLY_PROCS = [
'public.get_org_perm_for_apikey(text, text)',
'public.get_org_perm_for_apikey_v2(text, text)',
'public.get_org_user_access_rbac(uuid, uuid)',
'public.get_user_id(text)',
'public.get_user_id(text, text)',
'public.invite_user_to_org_rbac(character varying, uuid, text)',
'public.rbac_check_permission(text, uuid, character varying, bigint)',
Expand Down
21 changes: 17 additions & 4 deletions tests/security-oracle-rpc-hardening.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getAuthHeadersForCredentials,
ORG_ID,
USER_EMAIL,
USER_ID,
USER_PASSWORD,
} from './test-utils'

Expand Down Expand Up @@ -76,7 +77,7 @@ describe('anonymous oracle RPC hardening', () => {
expect(missingOrgResult.data).toBeNull()
})

it.concurrent('blocks get_user_id for anonymous callers without distinguishable outcomes', async () => {
it.concurrent('keeps get_user_id(text) callable for published CLI anonymous callers', async () => {
const client = createAnonymousClient()

const validKeyResult = await client.rpc('get_user_id', {
Expand All @@ -86,12 +87,24 @@ describe('anonymous oracle RPC hardening', () => {
apikey: '00000000-0000-0000-0000-000000000000',
})

expect(isPermissionDenied(validKeyResult.error)).toBe(true)
expect(isPermissionDenied(invalidKeyResult.error)).toBe(true)
expect(validKeyResult.data).toBeNull()
expect(validKeyResult.error).toBeNull()
expect(validKeyResult.data).toBe(USER_ID)
expect(invalidKeyResult.error).toBeNull()
expect(invalidKeyResult.data).toBeNull()
})

it.concurrent('keeps get_user_id(text, text) denied for anonymous callers', async () => {
const client = createAnonymousApiKeyClient(APIKEY_TEST_ORG_SUPER_ADMIN)

const result = await client.rpc('get_user_id', {
apikey: APIKEY_TEST_ORG_SUPER_ADMIN,
app_id: APP_ID,
})

expect(isPermissionDenied(result.error)).toBe(true)
expect(result.data).toBeNull()
})

it.concurrent('blocks get_org_perm_for_apikey RPCs for anonymous callers', async () => {
const client = createAnonymousApiKeyClient(APIKEY_TEST_ORG_SUPER_ADMIN)

Expand Down
Loading