diff --git a/.changeset/friendly-adults-bathe.md b/.changeset/friendly-adults-bathe.md
new file mode 100644
index 00000000000..d0439fad4e6
--- /dev/null
+++ b/.changeset/friendly-adults-bathe.md
@@ -0,0 +1,6 @@
+---
+"@clerk/shared": patch
+"@clerk/testing": patch
+---
+
+Fixed an issue where API keys in `` are showing organization API keys.
diff --git a/integration/tests/machine-auth/component.test.ts b/integration/tests/machine-auth/component.test.ts
index f03881e4632..b37527e0f36 100644
--- a/integration/tests/machine-auth/component.test.ts
+++ b/integration/tests/machine-auth/component.test.ts
@@ -285,6 +285,43 @@ testAgainstRunningApps({
await u.page.unrouteAll();
});
+ test('UserProfile API keys uses user ID as subject even when organization is active', async ({ page, context }) => {
+ const u = createTestUtils({ app, page, context });
+
+ const admin = await u.services.users.getUser({ email: fakeAdmin.email });
+ expect(admin).toBeDefined();
+ const userId = admin.id;
+
+ await u.po.signIn.goTo();
+ await u.po.signIn.waitForMounted();
+ await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password });
+ await u.po.expect.toBeSignedIn();
+
+ await u.po.organizationSwitcher.goTo();
+ await u.po.organizationSwitcher.waitForMounted();
+ await u.po.organizationSwitcher.waitForAnOrganizationToSelected();
+
+ let capturedSubject: string | null = null;
+ const apiKeyRequestPromise = u.page.waitForRequest(request => {
+ if (request.url().includes('api_keys')) {
+ const url = new URL(request.url());
+ capturedSubject = url.searchParams.get('subject');
+ return true;
+ }
+ return false;
+ });
+
+ await u.po.page.goToRelative('/user');
+ await u.po.userProfile.waitForMounted();
+ await u.po.userProfile.switchToAPIKeysTab();
+
+ await apiKeyRequestPromise;
+
+ // Verify the subject parameter is the user ID, not the organization ID
+ expect(capturedSubject).toBe(userId);
+ expect(capturedSubject).not.toBe(fakeOrganization.organization.id);
+ });
+
test('standalone API keys component in user context based on user_api_keys_enabled', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
diff --git a/packages/shared/src/react/hooks/useAPIKeys.rq.tsx b/packages/shared/src/react/hooks/useAPIKeys.rq.tsx
index 068c139a9c2..7423a4bc59b 100644
--- a/packages/shared/src/react/hooks/useAPIKeys.rq.tsx
+++ b/packages/shared/src/react/hooks/useAPIKeys.rq.tsx
@@ -95,7 +95,9 @@ export function useAPIKeys(params?: T): UseAPIKeysRe
const isEnabled = (safeValues.enabled ?? true) && clerk.loaded;
return usePagesOrInfinite({
- fetcher: clerk.apiKeys?.getAll ? (params: GetAPIKeysParams) => clerk.apiKeys.getAll(params) : undefined,
+ fetcher: clerk.apiKeys?.getAll
+ ? (params: GetAPIKeysParams) => clerk.apiKeys.getAll({ ...params, subject: safeValues.subject })
+ : undefined,
config: {
keepPreviousData: safeValues.keepPreviousData,
infinite: safeValues.infinite,
diff --git a/packages/shared/src/react/hooks/useAPIKeys.swr.tsx b/packages/shared/src/react/hooks/useAPIKeys.swr.tsx
index dc7037ab621..7780f8e85a1 100644
--- a/packages/shared/src/react/hooks/useAPIKeys.swr.tsx
+++ b/packages/shared/src/react/hooks/useAPIKeys.swr.tsx
@@ -98,7 +98,9 @@ export function useAPIKeys(params?: T): UseAPIKeysRe
const isEnabled = (safeValues.enabled ?? true) && clerk.loaded;
const result = usePagesOrInfinite({
- fetcher: clerk.apiKeys?.getAll ? (params: GetAPIKeysParams) => clerk.apiKeys.getAll(params) : undefined,
+ fetcher: clerk.apiKeys?.getAll
+ ? (params: GetAPIKeysParams) => clerk.apiKeys.getAll({ ...params, subject: safeValues.subject })
+ : undefined,
config: {
keepPreviousData: safeValues.keepPreviousData,
infinite: safeValues.infinite,
diff --git a/packages/testing/src/playwright/unstable/page-objects/userProfile.ts b/packages/testing/src/playwright/unstable/page-objects/userProfile.ts
index f80b591e7c3..bfc0a442319 100644
--- a/packages/testing/src/playwright/unstable/page-objects/userProfile.ts
+++ b/packages/testing/src/playwright/unstable/page-objects/userProfile.ts
@@ -17,6 +17,9 @@ export const createUserProfileComponentPageObject = (testArgs: { page: EnhancedP
switchToBillingTab: async () => {
await page.getByText(/Billing/i).click();
},
+ switchToAPIKeysTab: async () => {
+ await page.getByText(/API keys/i).click();
+ },
waitForMounted: () => {
return page.waitForSelector('.cl-userProfile-root', { state: 'attached' });
},